Read in rmeta crates
This commit is contained in:
parent
b286a2f081
commit
534556a445
@ -56,24 +56,37 @@ pub struct LinkMeta {
|
||||
pub crate_hash: Svh,
|
||||
}
|
||||
|
||||
// Where a crate came from on the local filesystem. One of these two options
|
||||
// Where a crate came from on the local filesystem. One of these three options
|
||||
// must be non-None.
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub struct CrateSource {
|
||||
pub dylib: Option<(PathBuf, PathKind)>,
|
||||
pub rlib: Option<(PathBuf, PathKind)>,
|
||||
pub rmeta: Option<(PathBuf, PathKind)>,
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
|
||||
pub enum DepKind {
|
||||
/// A dependency that is only used for its macros.
|
||||
MacrosOnly,
|
||||
/// A dependency that is always injected into the dependency list and so
|
||||
/// doesn't need to be linked to an rlib, e.g. the injected allocator.
|
||||
Implicit,
|
||||
/// A dependency that is required by an rlib version of this crate.
|
||||
/// Ordinary `extern crate`s result in `Explicit` dependencies.
|
||||
Explicit,
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub enum LibSource {
|
||||
Some(PathBuf),
|
||||
MetadataOnly,
|
||||
None,
|
||||
}
|
||||
|
||||
impl LibSource {
|
||||
pub fn is_some(&self) -> bool {
|
||||
if let LibSource::Some(_) = *self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn option(&self) -> Option<PathBuf> {
|
||||
match *self {
|
||||
LibSource::Some(ref p) => Some(p.clone()),
|
||||
LibSource::MetadataOnly | LibSource::None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)]
|
||||
@ -244,7 +257,7 @@ pub trait CrateStore<'tcx> {
|
||||
// utility functions
|
||||
fn metadata_filename(&self) -> &str;
|
||||
fn metadata_section_name(&self, target: &Target) -> &str;
|
||||
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>;
|
||||
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
|
||||
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
|
||||
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
|
||||
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
@ -427,7 +440,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
||||
// utility functions
|
||||
fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
|
||||
fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
|
||||
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
|
||||
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
|
||||
{ vec![] }
|
||||
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
|
||||
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
|
||||
|
@ -192,7 +192,7 @@ fn calculate_type(sess: &session::Session,
|
||||
if src.dylib.is_none() &&
|
||||
!formats.contains_key(&cnum) &&
|
||||
sess.cstore.dep_kind(cnum) == DepKind::Explicit {
|
||||
assert!(src.rlib.is_some());
|
||||
assert!(src.rlib.is_some() || src.rmeta.is_some());
|
||||
info!("adding staticlib: {}", sess.cstore.crate_name(cnum));
|
||||
add_library(sess, cnum, RequireStatic, &mut formats);
|
||||
ret[cnum.as_usize() - 1] = Linkage::Static;
|
||||
|
@ -1093,7 +1093,6 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
|
||||
"serialize work products",
|
||||
move || rustc_incremental::save_work_products(sess));
|
||||
|
||||
println!("finish phase 5: {}", sess.err_count());
|
||||
if sess.err_count() > 0 {
|
||||
Err(sess.err_count())
|
||||
} else {
|
||||
|
@ -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,9 +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()));
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
@ -278,6 +281,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 +289,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 +309,7 @@ impl<'a> CrateLoader<'a> {
|
||||
source: cstore::CrateSource {
|
||||
dylib: dylib,
|
||||
rlib: rlib,
|
||||
rmeta: rmeta,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -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;
|
||||
@ -33,7 +32,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
|
||||
@ -185,7 +184,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);
|
||||
@ -201,6 +200,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.rmeta.is_some() {
|
||||
LibSource::MetadataOnly
|
||||
} else {
|
||||
LibSource::None
|
||||
}
|
||||
}
|
||||
};
|
||||
Some((cnum, path))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -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::{token, new_parser_from_source_str};
|
||||
@ -544,7 +543,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)
|
||||
}
|
||||
|
@ -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 rlibs, which contain
|
||||
//! metadata, but no code. 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
|
||||
@ -275,6 +282,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";
|
||||
@ -282,6 +290,7 @@ pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
enum CrateFlavor {
|
||||
Rlib,
|
||||
Rmeta,
|
||||
Dylib,
|
||||
}
|
||||
|
||||
@ -289,6 +298,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",
|
||||
})
|
||||
}
|
||||
@ -296,12 +306,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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -457,11 +462,13 @@ 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)
|
||||
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())], false)
|
||||
(&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 {
|
||||
@ -475,14 +482,14 @@ impl<'a> Context<'a> {
|
||||
|
||||
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
|
||||
})
|
||||
@ -499,15 +506,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,
|
||||
});
|
||||
}
|
||||
@ -703,6 +712,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| {
|
||||
@ -744,6 +754,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);
|
||||
}
|
||||
@ -753,9 +765,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 {
|
||||
@ -763,6 +776,7 @@ impl<'a> Context<'a> {
|
||||
Some(Library {
|
||||
dylib: dylib,
|
||||
rlib: rlib,
|
||||
rmeta: rmeta,
|
||||
metadata: metadata,
|
||||
})
|
||||
}
|
||||
@ -832,7 +846,7 @@ fn get_metadata_section_imp(target: &Target,
|
||||
if !filename.exists() {
|
||||
return Err(format!("no such file: '{}'", filename.display()));
|
||||
}
|
||||
if flavor == CrateFlavor::Rlib {
|
||||
if flavor == CrateFlavor::Rlib || flavor == CrateFlavor::Rmeta {
|
||||
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
|
||||
// internally to read the file. We also avoid even using a memcpy by
|
||||
// just keeping the archive along while the metadata is in use.
|
||||
@ -933,6 +947,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
|
||||
};
|
||||
|
@ -19,7 +19,7 @@ use session::config::{OutputFilenames, Input, OutputType};
|
||||
use session::filesearch;
|
||||
use session::search_paths::PathKind;
|
||||
use session::Session;
|
||||
use middle::cstore::{self, LinkMeta, NativeLibrary};
|
||||
use middle::cstore::{self, LinkMeta, NativeLibrary, LibSource};
|
||||
use middle::cstore::{LinkagePreference, NativeLibraryKind};
|
||||
use middle::dependency_format::Linkage;
|
||||
use CrateTranslation;
|
||||
@ -123,7 +123,6 @@ pub fn find_crate_name(sess: Option<&Session>,
|
||||
}
|
||||
|
||||
"rust_out".to_string()
|
||||
|
||||
}
|
||||
|
||||
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap,
|
||||
@ -302,7 +301,7 @@ pub fn each_linked_rlib(sess: &Session,
|
||||
.or_else(|| fmts.get(&config::CrateTypeCdylib))
|
||||
.or_else(|| fmts.get(&config::CrateTypeProcMacro));
|
||||
let fmts = fmts.unwrap_or_else(|| {
|
||||
bug!("could not find formats for rlibs")
|
||||
bug!("could not find formats for rlibs");
|
||||
});
|
||||
for (cnum, path) in crates {
|
||||
match fmts[cnum.as_usize() - 1] {
|
||||
@ -311,8 +310,11 @@ pub fn each_linked_rlib(sess: &Session,
|
||||
}
|
||||
let name = sess.cstore.crate_name(cnum).clone();
|
||||
let path = match path {
|
||||
Some(p) => p,
|
||||
None => {
|
||||
LibSource::Some(p) => p,
|
||||
LibSource::MetadataOnly => {
|
||||
sess.fatal(&format!("could not find rlib for: `{}`, found rmeta (metadata) file", name));
|
||||
}
|
||||
LibSource::None => {
|
||||
sess.fatal(&format!("could not find rlib for: `{}`", name));
|
||||
}
|
||||
};
|
||||
@ -326,7 +328,6 @@ fn link_binary_output(sess: &Session,
|
||||
outputs: &OutputFilenames,
|
||||
crate_name: &str) -> PathBuf {
|
||||
let objects = object_filenames(trans, outputs);
|
||||
println!("objects: {:?}", objects);
|
||||
let default_filename = filename_for_input(sess, crate_type, crate_name,
|
||||
outputs);
|
||||
let out_filename = outputs.outputs.get(&OutputType::Exe)
|
||||
|
@ -14,9 +14,10 @@ use std::path::{Path, PathBuf};
|
||||
use std::fs;
|
||||
|
||||
use rustc::hir::def_id::CrateNum;
|
||||
use rustc::middle::cstore::LibSource;
|
||||
|
||||
pub struct RPathConfig<'a> {
|
||||
pub used_crates: Vec<(CrateNum, Option<PathBuf>)>,
|
||||
pub used_crates: Vec<(CrateNum, LibSource)>,
|
||||
pub out_filename: PathBuf,
|
||||
pub is_like_osx: bool,
|
||||
pub has_rpath: bool,
|
||||
@ -35,7 +36,7 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
|
||||
debug!("preparing the RPATH!");
|
||||
|
||||
let libs = config.used_crates.clone();
|
||||
let libs = libs.into_iter().filter_map(|(_, l)| l).collect::<Vec<_>>();
|
||||
let libs = libs.into_iter().filter_map(|(_, l)| l.option()).collect::<Vec<_>>();
|
||||
let rpaths = get_rpaths(config, &libs[..]);
|
||||
flags.extend_from_slice(&rpaths_to_flags(&rpaths[..]));
|
||||
|
||||
|
@ -45,7 +45,7 @@ use rustc::ty::adjustment::CustomCoerceUnsized;
|
||||
use rustc::dep_graph::{DepNode, WorkProduct};
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::util::common::time;
|
||||
use session::config::{self, NoDebugInfo, OutputType};
|
||||
use session::config::{self, NoDebugInfo};
|
||||
use rustc_incremental::IncrementalHashesMap;
|
||||
use session::Session;
|
||||
use abi::{self, Abi, FnType};
|
||||
|
Loading…
Reference in New Issue
Block a user