diff options
| author | bors <bors@rust-lang.org> | 2013-08-09 16:17:10 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-08-09 16:17:10 -0700 |
| commit | 6f6dce7bbcfb104a8a1e23b0b93d83cbb770f338 (patch) | |
| tree | 1f5f151dfd5c72f41338c495a38b422ea4aa552c /src/librustc | |
| parent | 1de201c3c6ee1e563ca58d4d6b288929e841081e (diff) | |
| parent | 37fd8f03fdbc622457396877168d2a8d82cf3d2b (diff) | |
auto merge of #8176 : catamorphism/rust/rustpkg-extern-mod, r=catamorphism
r? @graydon Also, notably, make rustpkgtest depend on the rustpkg executable (otherwise, tests that shell out to rustpgk might run when rustpkg doesn't exist).
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/back/link.rs | 23 | ||||
| -rw-r--r-- | src/librustc/back/rpath.rs | 117 | ||||
| -rw-r--r-- | src/librustc/front/std_inject.rs | 2 | ||||
| -rw-r--r-- | src/librustc/front/test.rs | 2 | ||||
| -rw-r--r-- | src/librustc/metadata/common.rs | 2 | ||||
| -rw-r--r-- | src/librustc/metadata/creader.rs | 45 | ||||
| -rw-r--r-- | src/librustc/metadata/filesearch.rs | 143 | ||||
| -rw-r--r-- | src/librustc/metadata/loader.rs | 78 | ||||
| -rw-r--r-- | src/librustc/middle/resolve.rs | 5 |
9 files changed, 184 insertions, 233 deletions
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 637ea159d79..bd95f1b735b 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -16,7 +16,7 @@ use lib::llvm::llvm; use lib::llvm::ModuleRef; use lib; use metadata::common::LinkMeta; -use metadata::{encoder, csearch, cstore}; +use metadata::{encoder, csearch, cstore, filesearch}; use middle::trans::context::CrateContext; use middle::trans::common::gensym_name; use middle::ty; @@ -497,6 +497,7 @@ pub fn build_link_meta(sess: Session, struct ProvidedMetas { name: Option<@str>, vers: Option<@str>, + pkg_id: Option<@str>, cmh_items: ~[@ast::MetaItem] } @@ -504,6 +505,7 @@ pub fn build_link_meta(sess: Session, ProvidedMetas { let mut name = None; let mut vers = None; + let mut pkg_id = None; let mut cmh_items = ~[]; let linkage_metas = attr::find_linkage_metas(c.attrs); attr::require_unique_names(sess.diagnostic(), linkage_metas); @@ -511,6 +513,7 @@ pub fn build_link_meta(sess: Session, match meta.name_str_pair() { Some((n, value)) if "name" == n => name = Some(value), Some((n, value)) if "vers" == n => vers = Some(value), + Some((n, value)) if "package_id" == n => pkg_id = Some(value), _ => cmh_items.push(*meta) } } @@ -518,6 +521,7 @@ pub fn build_link_meta(sess: Session, ProvidedMetas { name: name, vers: vers, + pkg_id: pkg_id, cmh_items: cmh_items } } @@ -525,7 +529,8 @@ pub fn build_link_meta(sess: Session, // This calculates CMH as defined above fn crate_meta_extras_hash(symbol_hasher: &mut hash::State, cmh_items: ~[@ast::MetaItem], - dep_hashes: ~[@str]) -> @str { + dep_hashes: ~[@str], + pkg_id: Option<@str>) -> @str { fn len_and_str(s: &str) -> ~str { fmt!("%u_%s", s.len(), s) } @@ -563,7 +568,10 @@ pub fn build_link_meta(sess: Session, write_string(symbol_hasher, len_and_str(*dh)); } - // tjc: allocation is unfortunate; need to change std::hash + for p in pkg_id.iter() { + write_string(symbol_hasher, len_and_str(*p)); + } + return truncated_hash_result(symbol_hasher).to_managed(); } @@ -605,6 +613,7 @@ pub fn build_link_meta(sess: Session, let ProvidedMetas { name: opt_name, vers: opt_vers, + pkg_id: opt_pkg_id, cmh_items: cmh_items } = provided_link_metas(sess, c); let name = crate_meta_name(sess, output, opt_name); @@ -612,11 +621,12 @@ pub fn build_link_meta(sess: Session, let dep_hashes = cstore::get_dep_hashes(sess.cstore); let extras_hash = crate_meta_extras_hash(symbol_hasher, cmh_items, - dep_hashes); + dep_hashes, opt_pkg_id); LinkMeta { name: name, vers: vers, + package_id: opt_pkg_id, extras_hash: extras_hash } } @@ -939,6 +949,11 @@ pub fn link_args(sess: Session, args.push(~"-L" + path.to_str()); } + let rustpath = filesearch::rust_path(); + for path in rustpath.iter() { + args.push(~"-L" + path.to_str()); + } + // The names of the extern libraries let used_libs = cstore::get_used_libraries(cstore); for l in used_libs.iter() { args.push(~"-l" + *l); } diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 6aac627729c..5dc92dbc5e6 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -14,10 +14,7 @@ use metadata::cstore; use metadata::filesearch; use std::hashmap::HashSet; -use std::num; -use std::os; -use std::util; -use std::vec; +use std::{num, os, path, uint, util, vec}; fn not_win32(os: session::os) -> bool { os != session::os_win32 @@ -122,42 +119,7 @@ pub fn get_rpath_relative_to_output(os: session::os, session::os_win32 => util::unreachable() }; - Path(prefix).push_rel(&get_relative_to(&os::make_absolute(output), - &os::make_absolute(lib))) -} - -// Find the relative path from one file to another -pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path { - assert!(abs1.is_absolute); - assert!(abs2.is_absolute); - let abs1 = abs1.normalize(); - let abs2 = abs2.normalize(); - debug!("finding relative path from %s to %s", - abs1.to_str(), abs2.to_str()); - let split1: &[~str] = abs1.components; - let split2: &[~str] = abs2.components; - let len1 = split1.len(); - let len2 = split2.len(); - assert!(len1 > 0); - assert!(len2 > 0); - - let max_common_path = num::min(len1, len2) - 1; - let mut start_idx = 0; - while start_idx < max_common_path - && split1[start_idx] == split2[start_idx] { - start_idx += 1; - } - - let mut path = ~[]; - for _ in range(start_idx, len1 - 1) { path.push(~".."); }; - - path.push_all(split2.slice(start_idx, len2 - 1)); - - return if !path.is_empty() { - Path("").push_many(path) - } else { - Path(".") - } + Path(prefix).push_rel(&os::make_absolute(output).get_relative_to(&os::make_absolute(lib))) } fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] { @@ -208,8 +170,7 @@ mod test { #[cfg(test)] #[cfg(test)] use back::rpath::{get_absolute_rpath, get_install_prefix_rpath}; - use back::rpath::{get_relative_to, get_rpath_relative_to_output}; - use back::rpath::{minimize_rpaths, rpaths_to_flags}; + use back::rpath::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output}; use driver::session; #[test] @@ -254,77 +215,8 @@ mod test { } #[test] - fn test_relative_to1() { - let p1 = Path("/usr/bin/rustc"); - let p2 = Path("/usr/lib/mylib"); - let res = get_relative_to(&p1, &p2); - assert_eq!(res, Path("../lib")); - } - - #[test] - fn test_relative_to2() { - let p1 = Path("/usr/bin/rustc"); - let p2 = Path("/usr/bin/../lib/mylib"); - let res = get_relative_to(&p1, &p2); - assert_eq!(res, Path("../lib")); - } - - #[test] - fn test_relative_to3() { - let p1 = Path("/usr/bin/whatever/rustc"); - let p2 = Path("/usr/lib/whatever/mylib"); - let res = get_relative_to(&p1, &p2); - assert_eq!(res, Path("../../lib/whatever")); - } - - #[test] - fn test_relative_to4() { - let p1 = Path("/usr/bin/whatever/../rustc"); - let p2 = Path("/usr/lib/whatever/mylib"); - let res = get_relative_to(&p1, &p2); - assert_eq!(res, Path("../lib/whatever")); - } - - #[test] - fn test_relative_to5() { - let p1 = Path("/usr/bin/whatever/../rustc"); - let p2 = Path("/usr/lib/whatever/../mylib"); - let res = get_relative_to(&p1, &p2); - assert_eq!(res, Path("../lib")); - } - - #[test] - fn test_relative_to6() { - let p1 = Path("/1"); - let p2 = Path("/2/3"); - let res = get_relative_to(&p1, &p2); - assert_eq!(res, Path("2")); - } - - #[test] - fn test_relative_to7() { - let p1 = Path("/1/2"); - let p2 = Path("/3"); - let res = get_relative_to(&p1, &p2); - assert_eq!(res, Path("..")); - } - - #[test] - fn test_relative_to8() { - let p1 = Path("/home/brian/Dev/rust/build/").push_rel( - &Path("stage2/lib/rustc/i686-unknown-linux-gnu/lib/librustc.so")); - let p2 = Path("/home/brian/Dev/rust/build/stage2/bin/..").push_rel( - &Path("lib/rustc/i686-unknown-linux-gnu/lib/libstd.so")); - let res = get_relative_to(&p1, &p2); - debug!("test_relative_tu8: %s vs. %s", - res.to_str(), - Path(".").to_str()); - assert_eq!(res, Path(".")); - } - - #[test] #[cfg(target_os = "linux")] - #[cfg(target_os = "andorid")] + #[cfg(target_os = "android")] fn test_rpath_relative() { let o = session::os_linux; let res = get_rpath_relative_to_output(o, @@ -344,7 +236,6 @@ mod test { #[test] #[cfg(target_os = "macos")] fn test_rpath_relative() { - // this is why refinements would be nice let o = session::os_macos; let res = get_rpath_relative_to_output(o, &Path("bin/rustc"), diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 3a1129b1dd9..2a61ea28e0c 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -47,7 +47,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate { let n1 = sess.next_node_id(); let vi1 = ast::view_item { node: ast::view_item_extern_mod( - sess.ident_of("std"), ~[], n1), + sess.ident_of("std"), None, ~[], n1), attrs: ~[ attr::mk_attr( attr::mk_name_value_item_str(@"vers", STD_VERSION.to_managed())) diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index d2d2a8b4be9..c6b1bdbe51b 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -282,7 +282,7 @@ fn mk_std(cx: &TestCtxt) -> ast::view_item { cx.sess.next_node_id()))]) } else { let mi = attr::mk_name_value_item_str(@"vers", @"0.8-pre"); - ast::view_item_extern_mod(id_extra, ~[mi], cx.sess.next_node_id()) + ast::view_item_extern_mod(id_extra, None, ~[mi], cx.sess.next_node_id()) }; ast::view_item { node: vi, diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 1c5d202d4d9..f2d8b68faa6 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -185,5 +185,7 @@ pub static tag_item_impl_vtables: uint = 0x82; pub struct LinkMeta { name: @str, vers: @str, + // Optional package ID + package_id: Option<@str>, // non-None if this was a URL-like package ID extras_hash: @str } diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index d8f14228824..0a9e8490f22 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -18,6 +18,7 @@ use metadata::loader; use std::hashmap::HashMap; use syntax::ast; +use std::vec; use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::codemap::{span, dummy_sp}; @@ -137,18 +138,33 @@ fn visit_crate(e: &Env, c: &ast::Crate) { fn visit_view_item(e: @mut Env, i: &ast::view_item) { match i.node { - ast::view_item_extern_mod(ident, ref meta_items, id) => { - debug!("resolving extern mod stmt. ident: %?, meta: %?", - ident, *meta_items); - let cnum = resolve_crate(e, - ident, - (*meta_items).clone(), - @"", - i.span); - cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum); + ast::view_item_extern_mod(ident, path_opt, ref meta_items, id) => { + let ident = token::ident_to_str(&ident); + let meta_items = match path_opt { + None => meta_items.clone(), + Some(p) => { + let p_path = Path(p); + match p_path.filestem() { + Some(s) => + vec::append( + ~[attr::mk_name_value_item_str(@"package_id", p), + attr::mk_name_value_item_str(@"name", s.to_managed())], + *meta_items), + None => e.diag.span_bug(i.span, "Bad package path in `extern mod` item") + } + } + }; + debug!("resolving extern mod stmt. ident: %?, meta: %?", + ident, meta_items); + let cnum = resolve_crate(e, + ident, + meta_items, + @"", + i.span); + cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum); } _ => () - } + } } fn visit_item(e: &Env, i: @ast::item) { @@ -233,12 +249,12 @@ fn existing_match(e: &Env, metas: &[@ast::MetaItem], hash: &str) } fn resolve_crate(e: @mut Env, - ident: ast::ident, + ident: @str, metas: ~[@ast::MetaItem], hash: @str, span: span) -> ast::CrateNum { - let metas = metas_with_ident(token::ident_to_str(&ident), metas); + let metas = metas_with_ident(ident, metas); match existing_match(e, metas, hash) { None => { @@ -279,7 +295,7 @@ fn resolve_crate(e: @mut Env, match attr::last_meta_item_value_str_by_name(load_ctxt.metas, "name") { Some(v) => v, - None => token::ident_to_str(&ident), + None => ident }; let cmeta = @cstore::crate_metadata { name: cname, @@ -308,7 +324,6 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map { let r = decoder::get_crate_deps(cdata); for dep in r.iter() { let extrn_cnum = dep.cnum; - let cname = dep.name; let cname_str = token::ident_to_str(&dep.name); let cmetas = metas_with(dep.vers, @"vers", ~[]); debug!("resolving dep crate %s ver: %s hash: %s", @@ -327,7 +342,7 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map { // FIXME (#2404): Need better error reporting than just a bogus // span. let fake_span = dummy_sp(); - let local_cnum = resolve_crate(e, cname, cmetas, dep.hash, + let local_cnum = resolve_crate(e, cname_str, cmetas, dep.hash, fake_span); cnum_map.insert(extrn_cnum, local_cnum); } diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index e18879464e8..2b44d793a9d 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -11,12 +11,15 @@ use std::option; use std::os; -use std::result; +use std::{result, str}; +use std::hashmap::HashSet; // A module for searching for libraries // FIXME (#2658): I'm not happy how this module turned out. Should // probably just be folded into cstore. +/// Functions with type `pick` take a parent directory as well as +/// a file found in that directory. pub type pick<'self, T> = &'self fn(path: &Path) -> Option<T>; pub fn pick_file(file: Path, path: &Path) -> Option<Path> { @@ -46,28 +49,33 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, impl FileSearch for FileSearchImpl { fn sysroot(&self) -> @Path { self.sysroot } fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool { + let mut visited_dirs = HashSet::new(); + debug!("filesearch: searching additional lib search paths [%?]", self.addl_lib_search_paths.len()); - // a little weird - self.addl_lib_search_paths.iter().advance(|path| f(path)); + for path in self.addl_lib_search_paths.iter() { + f(path); + visited_dirs.insert(path.to_str()); + } debug!("filesearch: searching target lib path"); - if !f(&make_target_lib_path(self.sysroot, - self.target_triple)) { - return false; - } - debug!("filesearch: searching rustpkg lib path nearest"); - if match get_rustpkg_lib_path_nearest() { - result::Ok(ref p) => f(p), - result::Err(_) => true - } { - return true; + let tlib_path = make_target_lib_path(self.sysroot, + self.target_triple); + if !visited_dirs.contains(&tlib_path.to_str()) { + if !f(&tlib_path) { + return false; } - debug!("filesearch: searching rustpkg lib path"); - match get_rustpkg_lib_path() { - result::Ok(ref p) => f(p), - result::Err(_) => true - } + } + visited_dirs.insert(tlib_path.to_str()); + // Try RUST_PATH + let rustpath = rust_path(); + for path in rustpath.iter() { + if !visited_dirs.contains(&path.push("lib").to_str()) { + f(&path.push("lib")); + visited_dirs.insert(path.push("lib").to_str()); + } + } + true } fn get_target_lib_path(&self) -> Path { make_target_lib_path(self.sysroot, self.target_triple) @@ -94,12 +102,15 @@ pub fn search<T>(filesearch: @FileSearch, pick: pick<T>) -> Option<T> { for path in r.iter() { debug!("testing %s", path.to_str()); let maybe_picked = pick(path); - if maybe_picked.is_some() { - debug!("picked %s", path.to_str()); - rslt = maybe_picked; - break; - } else { - debug!("rejected %s", path.to_str()); + match maybe_picked { + Some(_) => { + debug!("picked %s", path.to_str()); + rslt = maybe_picked; + break; + } + None => { + debug!("rejected %s", path.to_str()); + } } } rslt.is_none() @@ -132,55 +143,59 @@ fn get_sysroot(maybe_sysroot: &Option<@Path>) -> @Path { } } -pub fn get_rustpkg_sysroot() -> Result<Path, ~str> { - result::Ok(get_or_default_sysroot().push_many([libdir(), ~"rustpkg"])) +#[cfg(windows)] +static PATH_ENTRY_SEPARATOR: &'static str = ";"; +#[cfg(not(windows))] +static PATH_ENTRY_SEPARATOR: &'static str = ":"; + +/// Returns RUST_PATH as a string, without default paths added +pub fn get_rust_path() -> Option<~str> { + os::getenv("RUST_PATH") } -pub fn get_rustpkg_root() -> Result<Path, ~str> { - match os::getenv("RUSTPKG_ROOT") { - Some(ref _p) => result::Ok(Path((*_p))), - None => match os::homedir() { - Some(ref _q) => result::Ok((*_q).push(".rustpkg")), - None => result::Err(~"no RUSTPKG_ROOT or home directory") +/// Returns the value of RUST_PATH, as a list +/// of Paths. Includes default entries for, if they exist: +/// $HOME/.rust +/// DIR/.rust for any DIR that's the current working directory +/// or an ancestor of it +pub fn rust_path() -> ~[Path] { + let mut env_rust_path: ~[Path] = match get_rust_path() { + Some(env_path) => { + let env_path_components: ~[&str] = + env_path.split_str_iter(PATH_ENTRY_SEPARATOR).collect(); + env_path_components.map(|&s| Path(s)) } + None => ~[] + }; + let cwd = os::getcwd(); + // now add in default entries + let cwd_dot_rust = cwd.push(".rust"); + if !env_rust_path.contains(&cwd_dot_rust) { + env_rust_path.push(cwd_dot_rust); } -} - -pub fn get_rustpkg_root_nearest() -> Result<Path, ~str> { - do get_rustpkg_root().chain |p| { - let cwd = os::getcwd(); - let cwd_rustpkg = cwd.push(".rustpkg"); - let rustpkg_is_non_root_file = - !os::path_is_dir(&cwd_rustpkg) && cwd_rustpkg != p; - let mut par_rustpkg = cwd.pop().push(".rustpkg"); - let mut rslt = result::Ok(cwd_rustpkg); - - if rustpkg_is_non_root_file { - while par_rustpkg != p { - if os::path_is_dir(&par_rustpkg) { - rslt = result::Ok(par_rustpkg); - break; - } - if par_rustpkg.components.len() == 1 { - // We just checked /.rustpkg, stop now. - break; - } - par_rustpkg = par_rustpkg.pop().pop().push(".rustpkg"); - } + if !env_rust_path.contains(&cwd) { + env_rust_path.push(cwd.clone()); + } + do cwd.each_parent() |p| { + if !env_rust_path.contains(&p.push(".rust")) { + push_if_exists(&mut env_rust_path, p); } - rslt } -} - -fn get_rustpkg_lib_path() -> Result<Path, ~str> { - do get_rustpkg_root().chain |p| { - result::Ok(p.push(libdir())) + let h = os::homedir(); + for h in h.iter() { + if !env_rust_path.contains(&h.push(".rust")) { + push_if_exists(&mut env_rust_path, h); + } } + env_rust_path } -fn get_rustpkg_lib_path_nearest() -> Result<Path, ~str> { - do get_rustpkg_root_nearest().chain |p| { - result::Ok(p.push(libdir())) + +/// Adds p/.rust into vec, only if it exists +fn push_if_exists(vec: &mut ~[Path], p: &Path) { + let maybe_dir = p.push(".rust"); + if os::path_exists(&maybe_dir) { + vec.push(maybe_dir); } } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 9330cfc5c88..5f145d87ca8 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -18,7 +18,6 @@ use metadata::filesearch::FileSearch; use metadata::filesearch; use syntax::codemap::span; use syntax::diagnostic::span_handler; -use syntax::parse::token; use syntax::parse::token::ident_interner; use syntax::print::pprust; use syntax::{ast, attr}; @@ -46,7 +45,7 @@ pub struct Context { diag: @span_handler, filesearch: @FileSearch, span: span, - ident: ast::ident, + ident: @str, metas: ~[@ast::MetaItem], hash: @str, os: os, @@ -60,7 +59,7 @@ pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) { None => { cx.diag.span_fatal(cx.span, fmt!("can't find crate for `%s`", - token::ident_to_str(&cx.ident))); + cx.ident)); } } } @@ -89,37 +88,38 @@ fn find_library_crate_aux( filesearch: @filesearch::FileSearch ) -> Option<(~str, @~[u8])> { let crate_name = crate_name_from_metas(cx.metas); - let prefix = prefix + crate_name + "-"; - + // want: crate_name.dir_part() + prefix + crate_name.file_part + "-" + let prefix = fmt!("%s%s-", prefix, crate_name); let mut matches = ~[]; filesearch::search(filesearch, |path| -> Option<()> { - debug!("inspecting file %s", path.to_str()); - match path.filename() { - Some(ref f) if f.starts_with(prefix) && f.ends_with(suffix) => { - debug!("%s is a candidate", path.to_str()); - match get_metadata_section(cx.os, path) { - Some(cvec) => - if !crate_matches(cvec, cx.metas, cx.hash) { - debug!("skipping %s, metadata doesn't match", - path.to_str()); - None - } else { - debug!("found %s with matching metadata", path.to_str()); - matches.push((path.to_str(), cvec)); - None - }, - _ => { - debug!("could not load metadata for %s", path.to_str()); - None - } - } - } - _ => { - debug!("skipping %s, doesn't look like %s*%s", path.to_str(), - prefix, suffix); - None - } - }}); + let path_str = path.filename(); + match path_str { + None => None, + Some(path_str) => + if path_str.starts_with(prefix) && path_str.ends_with(suffix) { + debug!("%s is a candidate", path.to_str()); + match get_metadata_section(cx.os, path) { + Some(cvec) => + if !crate_matches(cvec, cx.metas, cx.hash) { + debug!("skipping %s, metadata doesn't match", + path.to_str()); + None + } else { + debug!("found %s with matching metadata", path.to_str()); + matches.push((path.to_str(), cvec)); + None + }, + _ => { + debug!("could not load metadata for %s", path.to_str()); + None + } + } + } + else { + None + } + } + }); match matches.len() { 0 => None, @@ -137,8 +137,8 @@ fn find_library_crate_aux( } cx.diag.handler().abort_if_errors(); None - } } + } } pub fn crate_name_from_metas(metas: &[@ast::MetaItem]) -> @str { @@ -151,6 +151,16 @@ pub fn crate_name_from_metas(metas: &[@ast::MetaItem]) -> @str { fail!("expected to find the crate name") } +pub fn package_id_from_metas(metas: &[@ast::MetaItem]) -> Option<@str> { + for m in metas.iter() { + match m.name_str_pair() { + Some((name, s)) if "package_id" == name => { return Some(s); } + _ => {} + } + } + None +} + pub fn note_linkage_attrs(intr: @ident_interner, diag: @span_handler, attrs: ~[ast::Attribute]) { @@ -175,6 +185,8 @@ fn crate_matches(crate_data: @~[u8], pub fn metadata_matches(extern_metas: &[@ast::MetaItem], local_metas: &[@ast::MetaItem]) -> bool { +// extern_metas: metas we read from the crate +// local_metas: metas we're looking for debug!("matching %u metadata requirements against %u items", local_metas.len(), extern_metas.len()); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 43953a50e15..7d892d97676 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1487,9 +1487,10 @@ impl Resolver { } } - view_item_extern_mod(name, _, node_id) => { + view_item_extern_mod(name, _, _, node_id) => { + // n.b. we don't need to look at the path option here, because cstore already did match find_extern_mod_stmt_cnum(self.session.cstore, - node_id) { + node_id) { Some(crate_id) => { let def_id = def_id { crate: crate_id, node: 0 }; let parent_link = ModuleParentLink |
