]> git.lizzy.rs Git - rust.git/commitdiff
Read in rmeta crates
authorNick Cameron <ncameron@mozilla.com>
Thu, 10 Nov 2016 02:57:30 +0000 (15:57 +1300)
committerNick Cameron <ncameron@mozilla.com>
Sun, 20 Nov 2016 18:10:12 +0000 (07:10 +1300)
src/librustc/middle/cstore.rs
src/librustc/middle/dependency_format.rs
src/librustc_driver/driver.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/locator.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/rpath.rs
src/librustc_trans/base.rs

index f61978271e7f6c34e1bb095e9e8dca16c0c23ffb..1468e94459e63f2bec8df9b46761adbeea6a4ded 100644 (file)
@@ -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 @@ fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
     // 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 @@ fn used_link_args(&self) -> Vec<String> { vec![] }
     // 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 }
index aeccaac385ac5aeaf6f67b92b27ce0ec58756eb8..ee7f13f9e6e2266ddfafe6e0aa8b4dc629e6b560 100644 (file)
@@ -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;
index 9c207108374db05f3a6698921f571a93a47dee64..6a3a1bbb55ca2bea035f80100b11d81736d281fa 100644 (file)
@@ -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 {
index 313b3b0fddf4d80218816df0cbcac24aa051ed8a..693b04ae661cd02b75fbad5e3b966e0c3e43c630 100644 (file)
@@ -44,6 +44,7 @@
 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 @@ fn register_crate(&mut self,
                 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 @@ fn register_crate(&mut self,
         // 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 @@ fn register_crate(&mut self,
             source: cstore::CrateSource {
                 dylib: dylib,
                 rlib: rlib,
+                rmeta: rmeta,
             },
         });
 
index 37853b7473a6500d05e3e42b7f346fdf5b574d33..e5f7964d7eb9ccd6ca27b80e0f05dfe7568ccaca 100644 (file)
@@ -25,7 +25,6 @@
 
 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 @@
 
 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 @@ pub fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate
     // 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 @@ pub fn do_get_used_crates(&self,
                     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<_>>();
index 2018d829597d43bb280799594efe1343a737f07e..cf8240db1958a2936d382cc457a8ce32d944c8dc 100644 (file)
@@ -13,7 +13,7 @@
 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::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 @@ fn metadata_section_name(&self, target: &Target) -> &str
         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)
     }
index b677a63edc06458c6e50247dd22281535175dfd2..6cdd8b46464058aa0c3ed98c66067754414b1458 100644 (file)
 //! 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 struct CratePaths {
 #[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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 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 @@ fn find_library_crate(&mut self) -> Option<Library> {
                 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 @@ fn find_library_crate(&mut self) -> Option<Library> {
 
             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 @@ fn find_library_crate(&mut self) -> Option<Library> {
         // 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 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
         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 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
             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 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
         // 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 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
                 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
     };
index fcbead49a2635fdfec2a3a92bd1343ff56547e35..7938ddde4cec733ad4926785e37246a04a0df998 100644 (file)
@@ -19,7 +19,7 @@
 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)
index 8758cdcf9d0ab63928ef1100381060561773bb1f..ccaa0d4e1b1b059de8214d48454ea049d7897eac 100644 (file)
 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[..]));
 
index 59d81d5c6902dba6992b1f5213bf8e6c4fa27f23..c006eb9156b6cc03f63e9752cbd2f28d3709c077 100644 (file)
@@ -45,7 +45,7 @@
 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};