diff options
| author | bors <bors@rust-lang.org> | 2016-11-22 21:54:10 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-11-22 21:54:10 -0600 |
| commit | 5196ca85189291adbb488339b321026a95330c45 (patch) | |
| tree | 964d130609bc82c03bc10f440f883a3460e4adba /src/librustc_metadata | |
| parent | 1cabe2151299c63497abc3a20bd08c04c0cd32a3 (diff) | |
| parent | af1b19555ce636788c19dba979b57536792d90e9 (diff) | |
| download | rust-5196ca85189291adbb488339b321026a95330c45.tar.gz rust-5196ca85189291adbb488339b321026a95330c45.zip | |
Auto merge of #37681 - nrc:crate-metadata, r=@alexcrichton
add --crate-type metadata r? @alexcrichton
Diffstat (limited to 'src/librustc_metadata')
| -rw-r--r-- | src/librustc_metadata/creader.rs | 13 | ||||
| -rw-r--r-- | src/librustc_metadata/cstore.rs | 16 | ||||
| -rw-r--r-- | src/librustc_metadata/cstore_impl.rs | 5 | ||||
| -rw-r--r-- | src/librustc_metadata/decoder.rs | 3 | ||||
| -rw-r--r-- | src/librustc_metadata/locator.rs | 89 |
5 files changed, 84 insertions, 42 deletions
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 269fb1dcea4..27c00481bfd 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -44,6 +44,7 @@ use log; pub struct Library { pub dylib: Option<(PathBuf, PathKind)>, pub rlib: Option<(PathBuf, PathKind)>, + pub rmeta: Option<(PathBuf, PathKind)>, pub metadata: MetadataBlob, } @@ -62,10 +63,11 @@ fn dump_crates(cstore: &CStore) { info!(" cnum: {}", data.cnum); info!(" hash: {}", data.hash()); info!(" reqd: {:?}", data.dep_kind.get()); - let CrateSource { dylib, rlib } = data.source.clone(); + let CrateSource { dylib, rlib, rmeta } = data.source.clone(); dylib.map(|dl| info!(" dylib: {}", dl.0.display())); rlib.map(|rl| info!(" rlib: {}", rl.0.display())); - }) + rmeta.map(|rl| info!(" rmeta: {}", rl.0.display())); + }); } #[derive(Debug)] @@ -278,6 +280,7 @@ impl<'a> CrateLoader<'a> { ident: ident.to_string(), dylib: lib.dylib.clone().map(|p| p.0), rlib: lib.rlib.clone().map(|p| p.0), + rmeta: lib.rmeta.clone().map(|p| p.0), }) } else { None @@ -285,7 +288,7 @@ impl<'a> CrateLoader<'a> { // Maintain a reference to the top most crate. let root = if root.is_some() { root } else { &crate_paths }; - let Library { dylib, rlib, metadata } = lib; + let Library { dylib, rlib, rmeta, metadata } = lib; let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind); @@ -305,6 +308,7 @@ impl<'a> CrateLoader<'a> { source: cstore::CrateSource { dylib: dylib, rlib: rlib, + rmeta: rmeta, }, }); @@ -767,7 +771,8 @@ impl<'a> CrateLoader<'a> { config::CrateTypeProcMacro | config::CrateTypeCdylib | config::CrateTypeStaticlib => need_lib_alloc = true, - config::CrateTypeRlib => {} + config::CrateTypeRlib | + config::CrateTypeMetadata => {} } } if !need_lib_alloc && !need_exe_alloc { return } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index ce47b936ddc..7c1834c1576 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -25,7 +25,6 @@ use rustc::util::nodemap::{FxHashMap, NodeMap, NodeSet, DefIdMap}; use std::cell::{RefCell, Cell}; use std::rc::Rc; -use std::path::PathBuf; use flate::Bytes; use syntax::{ast, attr}; use syntax::ext::base::SyntaxExtension; @@ -34,7 +33,7 @@ use syntax_pos; pub use rustc::middle::cstore::{NativeLibrary, LinkagePreference}; pub use rustc::middle::cstore::{NativeStatic, NativeFramework, NativeUnknown}; -pub use rustc::middle::cstore::{CrateSource, LinkMeta}; +pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource}; // A map from external crate numbers (as decoded from some crate file) to // local crate numbers (as generated during this session). Each external @@ -45,6 +44,7 @@ pub type CrateNumMap = IndexVec<CrateNum, CrateNum>; pub enum MetadataBlob { Inflated(Bytes), Archive(locator::ArchiveMetadata), + Raw(Vec<u8>), } /// Holds information about a syntax_pos::FileMap imported from another crate. @@ -186,7 +186,7 @@ impl CStore { // positions. pub fn do_get_used_crates(&self, prefer: LinkagePreference) - -> Vec<(CrateNum, Option<PathBuf>)> { + -> Vec<(CrateNum, LibSource)> { let mut ordering = Vec::new(); for (&num, _) in self.metas.borrow().iter() { self.push_dependencies_in_postorder(&mut ordering, num); @@ -202,6 +202,16 @@ impl CStore { LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0), LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0), }; + let path = match path { + Some(p) => LibSource::Some(p), + None => { + if data.source.rmeta.is_some() { + LibSource::MetadataOnly + } else { + LibSource::None + } + } + }; Some((cnum, path)) }) .collect::<Vec<_>>(); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 407166203de..ead933384b9 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -13,7 +13,7 @@ use encoder; use locator; use schema; -use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, DepKind, ExternCrate}; +use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, LibSource, DepKind, ExternCrate}; use rustc::middle::cstore::{NativeLibrary, LinkMeta, LinkagePreference, LoadedMacro}; use rustc::hir::def::{self, Def}; use rustc::middle::lang_items; @@ -28,7 +28,6 @@ use rustc::mir::Mir; use rustc::util::nodemap::{NodeSet, DefIdMap}; use rustc_back::PanicStrategy; -use std::path::PathBuf; use syntax::ast; use syntax::attr; use syntax::parse::new_parser_from_source_str; @@ -545,7 +544,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { locator::meta_section_name(target) } - fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)> + fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> { self.do_get_used_crates(prefer) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index fb1314992c0..8a187bb9796 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -88,8 +88,9 @@ pub trait Metadata<'a, 'tcx>: Copy { impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { fn raw_bytes(self) -> &'a [u8] { match *self { - MetadataBlob::Inflated(ref vec) => &vec[..], + MetadataBlob::Inflated(ref vec) => vec, MetadataBlob::Archive(ref ar) => ar.as_slice(), + MetadataBlob::Raw(ref vec) => vec, } } } diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index f5196f7ea84..be9284baa74 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -53,6 +53,13 @@ //! is a platform-defined dynamic library. Each library has a metadata somewhere //! inside of it. //! +//! A third kind of dependency is an rmeta file. These are metadata files and do +//! not contain any code, etc. To a first approximation, these are treated in the +//! same way as rlibs. Where there is both an rlib and an rmeta file, the rlib +//! gets priority (even if the rmeta file is newer). An rmeta file is only +//! useful for checking a downstream crate, attempting to link one will cause an +//! error. +//! //! When translating a crate name to a crate on the filesystem, we all of a //! sudden need to take into account both rlibs and dylibs! Linkage later on may //! use either one of these files, as each has their pros/cons. The job of crate @@ -233,8 +240,8 @@ use rustc_back::target::Target; use std::cmp; use std::fmt; -use std::fs; -use std::io; +use std::fs::{self, File}; +use std::io::{self, Read}; use std::path::{Path, PathBuf}; use std::ptr; use std::slice; @@ -276,6 +283,7 @@ pub struct CratePaths { pub ident: String, pub dylib: Option<PathBuf>, pub rlib: Option<PathBuf>, + pub rmeta: Option<PathBuf>, } pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; @@ -283,6 +291,7 @@ pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; #[derive(Copy, Clone, PartialEq)] enum CrateFlavor { Rlib, + Rmeta, Dylib, } @@ -290,6 +299,7 @@ impl fmt::Display for CrateFlavor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match *self { CrateFlavor::Rlib => "rlib", + CrateFlavor::Rmeta => "rmeta", CrateFlavor::Dylib => "dylib", }) } @@ -297,12 +307,7 @@ impl fmt::Display for CrateFlavor { impl CratePaths { fn paths(&self) -> Vec<PathBuf> { - match (&self.dylib, &self.rlib) { - (&None, &None) => vec![], - (&Some(ref p), &None) | - (&None, &Some(ref p)) => vec![p.clone()], - (&Some(ref p1), &Some(ref p2)) => vec![p1.clone(), p2.clone()], - } + self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).cloned().collect() } } @@ -458,32 +463,35 @@ impl<'a> Context<'a> { None => return FileDoesntMatch, Some(file) => file, }; - let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") { - (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], true) - } else if file.starts_with(&dylib_prefix) && - file.ends_with(&dypair.1) { - (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], false) - } else { - if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) { - staticlibs.push(CrateMismatch { - path: path.to_path_buf(), - got: "static".to_string(), - }); - } - return FileDoesntMatch; - }; + let (hash, found_kind) = + if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") { + (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib) + } else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") { + (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta) + } else if file.starts_with(&dylib_prefix) && + file.ends_with(&dypair.1) { + (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib) + } else { + if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) { + staticlibs.push(CrateMismatch { + path: path.to_path_buf(), + got: "static".to_string(), + }); + } + return FileDoesntMatch; + }; info!("lib candidate: {}", path.display()); let hash_str = hash.to_string(); let slot = candidates.entry(hash_str) - .or_insert_with(|| (FxHashMap(), FxHashMap())); - let (ref mut rlibs, ref mut dylibs) = *slot; + .or_insert_with(|| (FxHashMap(), FxHashMap(), FxHashMap())); + let (ref mut rlibs, ref mut rmetas, ref mut dylibs) = *slot; fs::canonicalize(path) .map(|p| { - if rlib { - rlibs.insert(p, kind); - } else { - dylibs.insert(p, kind); + match found_kind { + CrateFlavor::Rlib => { rlibs.insert(p, kind); } + CrateFlavor::Rmeta => { rmetas.insert(p, kind); } + CrateFlavor::Dylib => { dylibs.insert(p, kind); } } FileMatches }) @@ -500,15 +508,17 @@ impl<'a> Context<'a> { // libraries corresponds to the crate id and hash criteria that this // search is being performed for. let mut libraries = FxHashMap(); - for (_hash, (rlibs, dylibs)) in candidates { + for (_hash, (rlibs, rmetas, dylibs)) in candidates { let mut slot = None; let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot); + let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot); let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot); if let Some((h, m)) = slot { libraries.insert(h, Library { dylib: dylib, rlib: rlib, + rmeta: rmeta, metadata: m, }); } @@ -704,6 +714,7 @@ impl<'a> Context<'a> { let sess = self.sess; let dylibname = self.dylibname(); let mut rlibs = FxHashMap(); + let mut rmetas = FxHashMap(); let mut dylibs = FxHashMap(); { let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| { @@ -722,7 +733,8 @@ impl<'a> Context<'a> { return false; } }; - if file.starts_with("lib") && file.ends_with(".rlib") { + if file.starts_with("lib") && + (file.ends_with(".rlib") || file.ends_with(".rmeta")) { return true; } else { let (ref prefix, ref suffix) = dylibname; @@ -745,6 +757,8 @@ impl<'a> Context<'a> { for loc in locs { if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { rlibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag); + } else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") { + rmetas.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag); } else { dylibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag); } @@ -754,9 +768,10 @@ impl<'a> Context<'a> { // Extract the rlib/dylib pair. let mut slot = None; let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot); + let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot); let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot); - if rlib.is_none() && dylib.is_none() { + if rlib.is_none() && rmeta.is_none() && dylib.is_none() { return None; } match slot { @@ -764,6 +779,7 @@ impl<'a> Context<'a> { Some(Library { dylib: dylib, rlib: rlib, + rmeta: rmeta, metadata: metadata, }) } @@ -851,6 +867,15 @@ fn get_metadata_section_imp(target: &Target, Ok(blob) } }; + } else if flavor == CrateFlavor::Rmeta { + let mut file = File::open(filename).map_err(|_| + format!("could not open file: '{}'", filename.display()))?; + let mut buf = vec![]; + file.read_to_end(&mut buf).map_err(|_| + format!("failed to read rlib metadata: '{}'", filename.display()))?; + let blob = MetadataBlob::Raw(buf); + verify_decompressed_encoding_version(&blob, filename)?; + return Ok(blob); } unsafe { let buf = common::path2cstr(filename); @@ -934,6 +959,8 @@ pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> let filename = path.file_name().unwrap().to_str().unwrap(); let flavor = if filename.ends_with(".rlib") { CrateFlavor::Rlib + } else if filename.ends_with(".rmeta") { + CrateFlavor::Rmeta } else { CrateFlavor::Dylib }; |
