From ac081c30be77ca95f195b9f984c47f7735edc7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Mon, 27 Jun 2011 15:24:44 -0400 Subject: [PATCH] Record and link with used native libraries. --- src/comp/driver/rustc.rs | 13 ++++++-- src/comp/driver/session.rs | 14 +++++++++ src/comp/front/creader.rs | 42 +++++++++++++++++++++++-- src/comp/front/parser.rs | 18 ++--------- src/lib/linux_os.rs | 2 +- src/lib/macos_os.rs | 2 +- src/lib/win32_os.rs | 2 +- src/test/run-pass/binops.rs | 2 +- src/test/run-pass/import-glob-1.rs | 2 +- src/test/run-pass/native-opaque-type.rs | 2 +- src/test/run-pass/native2.rs | 8 ++--- 11 files changed, 76 insertions(+), 31 deletions(-) diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 3644a1d271b..9a924b7b913 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -273,7 +273,7 @@ fn build_session(@session::options sopts) -> session::session { auto target_crate_num = 0; auto sess = session::session(target_crate_num, target_cfg, sopts, crate_cache, [], - front::codemap::new_codemap(), 0u); + [], front::codemap::new_codemap(), 0u); ret sess; } @@ -419,12 +419,19 @@ fn main(vec[str] args) { } } - gcc_args += sess.get_used_libraries(); + gcc_args += sess.get_used_crate_files(); + + auto used_libs = sess.get_used_libraries(); + for (str l in used_libs) { + gcc_args += ["-l" + l]; + } if (sopts.shared) { gcc_args += [shared_cmd]; } else { - gcc_args += ["-Lrustllvm", "-lrustllvm", "-lm", main]; + // FIXME: having -Lrustllvm hardcoded in here is hack + // FIXME: same for -lm + gcc_args += ["-Lrustllvm", "-lm", main]; } // We run 'gcc' here diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs index 3b73b650a9f..30a14f45bd7 100644 --- a/src/comp/driver/session.rs +++ b/src/comp/driver/session.rs @@ -66,6 +66,7 @@ obj session(ast::crate_num cnum, @config targ_cfg, @options opts, map::hashmap[int, crate_metadata] crates, + mutable vec[str] used_crate_files, mutable vec[str] used_libraries, codemap::codemap cm, mutable uint err_count) { @@ -136,6 +137,19 @@ obj session(ast::crate_num cnum, fn get_used_libraries() -> vec[str] { ret used_libraries; } + fn add_used_crate_file(&str lib) { + // A program has a small number of crates, so a vector is probably + // a good data structure in here. + for (str l in used_crate_files) { + if (l == lib) { + ret; + } + } + used_crate_files += [lib]; + } + fn get_used_crate_files() -> vec[str] { + ret used_crate_files; + } fn get_codemap() -> codemap::codemap { ret cm; } fn lookup_pos(uint pos) -> codemap::loc { ret codemap::lookup_pos(cm, pos); diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs index e6e48c78df7..90e22db9ba7 100644 --- a/src/comp/front/creader.rs +++ b/src/comp/front/creader.rs @@ -590,6 +590,15 @@ fn metadata_matches(hashmap[str, str] mm, &vec[@ast::meta_item] metas) -> ret true; } +fn default_native_lib_naming(session::session sess) -> + rec(str prefix, str suffix) { + alt (sess.get_targ_cfg().os) { + case (session::os_win32) { ret rec(prefix="", suffix=".dll"); } + case (session::os_macos) { ret rec(prefix="lib", suffix=".dylib"); } + case (session::os_linux) { ret rec(prefix="lib", suffix=".so"); } + } +} + fn find_library_crate(&session::session sess, &ast::ident ident, &vec[@ast::meta_item] metas, &vec[str] library_search_paths) -> @@ -609,7 +618,7 @@ fn find_library_crate(&session::session sess, &ast::ident ident, } } } - auto nn = parser::default_native_lib_naming(sess); + auto nn = default_native_lib_naming(sess); let str prefix = nn.prefix + crate_name; // FIXME: we could probably use a 'glob' function in std::fs but it will // be much easier to write once the unsafe module knows more about FFI @@ -649,7 +658,7 @@ fn load_library_crate(&session::session sess, int cnum, &ast::ident ident, alt (find_library_crate(sess, ident, metas, library_search_paths)) { case (some(?t)) { sess.set_external_crate(cnum, rec(name=ident, data=t._1)); - sess.add_used_library(t._0); + sess.add_used_crate_file(t._0); ret; } case (_) { } @@ -682,6 +691,32 @@ fn visit_view_item(env e, &@ast::view_item i) { } } +fn visit_item(env e, &@ast::item i) { + alt (i.node) { + case (ast::item_native_mod(?m)) { + auto name; + if (m.native_name == "" ) { + name = i.ident; + } else { + name = m.native_name; + } + alt (m.abi) { + case (ast::native_abi_rust) { + e.sess.add_used_library(name); + } + case (ast::native_abi_cdecl) { + e.sess.add_used_library(name); + } + case (ast::native_abi_llvm) { + } + case (ast::native_abi_rust_intrinsic) { + } + } + } + case (_) { + } + } +} // Reads external crates referenced by "use" directives. fn read_crates(session::session sess, resolve::crate_map crate_map, @@ -693,7 +728,8 @@ fn read_crates(session::session sess, resolve::crate_map crate_map, library_search_paths=sess.get_opts().library_search_paths, mutable next_crate_num=1); auto v = - rec(visit_view_item_pre=bind visit_view_item(e, _) + rec(visit_view_item_pre=bind visit_view_item(e, _), + visit_item_pre=bind visit_item(e, _) with walk::default_visitor()); walk::walk_crate(v, crate); } diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index a39b6885583..d153f0273f8 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -1899,20 +1899,6 @@ fn parse_native_mod_items(&parser p, &str native_name, ast::native_abi abi) -> items=items); } -fn default_native_lib_naming(session::session sess) -> - rec(str prefix, str suffix) { - alt (sess.get_targ_cfg().os) { - case (session::os_win32) { ret rec(prefix="", suffix=".dll"); } - case (session::os_macos) { ret rec(prefix="lib", suffix=".dylib"); } - case (session::os_linux) { ret rec(prefix="lib", suffix=".so"); } - } -} - -fn default_native_name(session::session sess, str id) -> str { - auto n = default_native_lib_naming(sess); - ret n.prefix + id + n.suffix; -} - fn parse_item_native_mod(&parser p, vec[ast::attribute] attrs) -> @ast::item { auto lo = p.get_last_lo_pos(); auto abi = ast::native_abi_cdecl; @@ -1933,7 +1919,9 @@ fn parse_item_native_mod(&parser p, vec[ast::attribute] attrs) -> @ast::item { if (p.peek() == token::EQ) { expect(p, token::EQ); native_name = parse_str(p); - } else { native_name = default_native_name(p.get_session(), id); } + } else { + native_name = ""; + } expect(p, token::LBRACE); auto m = parse_native_mod_items(p, native_name, abi); auto hi = p.get_hi_pos(); diff --git a/src/lib/linux_os.rs b/src/lib/linux_os.rs index b3d5cea3ac3..fbd5c138bdc 100644 --- a/src/lib/linux_os.rs +++ b/src/lib/linux_os.rs @@ -5,7 +5,7 @@ import vec::vbuf; // FIXME Somehow merge stuff duplicated here and macosx_os.rs. Made difficult // by https://github.com/graydon/rust/issues#issue/268 -native "cdecl" mod libc { +native "cdecl" mod libc = "c" { fn open(sbuf s, int flags, uint mode) -> int; fn read(int fd, vbuf buf, uint count) -> int; fn write(int fd, vbuf buf, uint count) -> int; diff --git a/src/lib/macos_os.rs b/src/lib/macos_os.rs index 2ab7e7b748a..b20ea8e5019 100644 --- a/src/lib/macos_os.rs +++ b/src/lib/macos_os.rs @@ -2,7 +2,7 @@ import str::sbuf; import vec::vbuf; -native "cdecl" mod libc { +native "cdecl" mod libc = "c" { fn open(sbuf s, int flags, uint mode) -> int; fn read(int fd, vbuf buf, uint count) -> int; fn write(int fd, vbuf buf, uint count) -> int; diff --git a/src/lib/win32_os.rs b/src/lib/win32_os.rs index 1a8d2071d2e..f8b38b30538 100644 --- a/src/lib/win32_os.rs +++ b/src/lib/win32_os.rs @@ -2,7 +2,7 @@ import str::sbuf; import vec::vbuf; -native "cdecl" mod libc { +native "cdecl" mod libc = "c" { fn open(sbuf s, int flags, uint mode) -> int = "_open"; fn read(int fd, vbuf buf, uint count) -> int = "_read"; fn write(int fd, vbuf buf, uint count) -> int = "_write"; diff --git a/src/test/run-pass/binops.rs b/src/test/run-pass/binops.rs index e9679f960dd..e265028af8c 100644 --- a/src/test/run-pass/binops.rs +++ b/src/test/run-pass/binops.rs @@ -112,7 +112,7 @@ fn test_fn() { assert (h1 >= h2); } -native "rust" mod native_mod { +native "rust" mod native_mod = "c" { fn str_byte_len(str s) -> vec[u8]; fn str_alloc(uint n_bytes) -> str; } diff --git a/src/test/run-pass/import-glob-1.rs b/src/test/run-pass/import-glob-1.rs index fb9648fe9ac..717e722a87a 100644 --- a/src/test/run-pass/import-glob-1.rs +++ b/src/test/run-pass/import-glob-1.rs @@ -12,7 +12,7 @@ mod a1 { // } // | | | // | | | mod a2 { // | | | - native mod b1 { // | | | + native mod b1 = "c" { // | | | import a1::b2::*; // | <-/ -/ export word_traveler; // | } // | diff --git a/src/test/run-pass/native-opaque-type.rs b/src/test/run-pass/native-opaque-type.rs index d3f6dc30f37..1a304fddf83 100644 --- a/src/test/run-pass/native-opaque-type.rs +++ b/src/test/run-pass/native-opaque-type.rs @@ -1,6 +1,6 @@ -native "cdecl" mod libc { +native "cdecl" mod libc = "c" { type file_handle; } diff --git a/src/test/run-pass/native2.rs b/src/test/run-pass/native2.rs index 9605d11e47c..40bb8304d7f 100644 --- a/src/test/run-pass/native2.rs +++ b/src/test/run-pass/native2.rs @@ -5,14 +5,14 @@ native "rust" mod rustrt { fn vec_buf[T](vec[T] v, uint offset) -> vbuf; } -native "rust" mod bar { } +native "rust" mod bar = "c" { } -native "cdecl" mod zed { } +native "cdecl" mod zed = "c" { } -native "cdecl" mod libc { +native "cdecl" mod libc = "c" { fn write(int fd, rustrt::vbuf buf, uint count) -> int; } -native "cdecl" mod baz { } +native "cdecl" mod baz = "c" { } fn main(vec[str] args) { } \ No newline at end of file