Skip to content

Commit 534556a

Browse files
committed
Read in rmeta crates
1 parent b286a2f commit 534556a

File tree

10 files changed

+93
-50
lines changed

10 files changed

+93
-50
lines changed

src/librustc/middle/cstore.rs

+26-13
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,37 @@ pub struct LinkMeta {
5656
pub crate_hash: Svh,
5757
}
5858

59-
// Where a crate came from on the local filesystem. One of these two options
59+
// Where a crate came from on the local filesystem. One of these three options
6060
// must be non-None.
6161
#[derive(PartialEq, Clone, Debug)]
6262
pub struct CrateSource {
6363
pub dylib: Option<(PathBuf, PathKind)>,
6464
pub rlib: Option<(PathBuf, PathKind)>,
65+
pub rmeta: Option<(PathBuf, PathKind)>,
6566
}
6667

67-
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
68-
pub enum DepKind {
69-
/// A dependency that is only used for its macros.
70-
MacrosOnly,
71-
/// A dependency that is always injected into the dependency list and so
72-
/// doesn't need to be linked to an rlib, e.g. the injected allocator.
73-
Implicit,
74-
/// A dependency that is required by an rlib version of this crate.
75-
/// Ordinary `extern crate`s result in `Explicit` dependencies.
76-
Explicit,
68+
#[derive(PartialEq, Clone, Debug)]
69+
pub enum LibSource {
70+
Some(PathBuf),
71+
MetadataOnly,
72+
None,
73+
}
74+
75+
impl LibSource {
76+
pub fn is_some(&self) -> bool {
77+
if let LibSource::Some(_) = *self {
78+
true
79+
} else {
80+
false
81+
}
82+
}
83+
84+
pub fn option(&self) -> Option<PathBuf> {
85+
match *self {
86+
LibSource::Some(ref p) => Some(p.clone()),
87+
LibSource::MetadataOnly | LibSource::None => None,
88+
}
89+
}
7790
}
7891

7992
#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)]
@@ -244,7 +257,7 @@ pub trait CrateStore<'tcx> {
244257
// utility functions
245258
fn metadata_filename(&self) -> &str;
246259
fn metadata_section_name(&self, target: &Target) -> &str;
247-
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>;
260+
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
248261
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
249262
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
250263
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -427,7 +440,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
427440
// utility functions
428441
fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
429442
fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
430-
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
443+
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
431444
{ vec![] }
432445
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
433446
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }

src/librustc/middle/dependency_format.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ fn calculate_type(sess: &session::Session,
192192
if src.dylib.is_none() &&
193193
!formats.contains_key(&cnum) &&
194194
sess.cstore.dep_kind(cnum) == DepKind::Explicit {
195-
assert!(src.rlib.is_some());
195+
assert!(src.rlib.is_some() || src.rmeta.is_some());
196196
info!("adding staticlib: {}", sess.cstore.crate_name(cnum));
197197
add_library(sess, cnum, RequireStatic, &mut formats);
198198
ret[cnum.as_usize() - 1] = Linkage::Static;

src/librustc_driver/driver.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,6 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
10931093
"serialize work products",
10941094
move || rustc_incremental::save_work_products(sess));
10951095

1096-
println!("finish phase 5: {}", sess.err_count());
10971096
if sess.err_count() > 0 {
10981097
Err(sess.err_count())
10991098
} else {

src/librustc_metadata/creader.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use log;
4444
pub struct Library {
4545
pub dylib: Option<(PathBuf, PathKind)>,
4646
pub rlib: Option<(PathBuf, PathKind)>,
47+
pub rmeta: Option<(PathBuf, PathKind)>,
4748
pub metadata: MetadataBlob,
4849
}
4950

@@ -62,9 +63,11 @@ fn dump_crates(cstore: &CStore) {
6263
info!(" cnum: {}", data.cnum);
6364
info!(" hash: {}", data.hash());
6465
info!(" reqd: {:?}", data.dep_kind.get());
65-
let CrateSource { dylib, rlib } = data.source.clone();
66+
let CrateSource { dylib, rlib, rmeta } = data.source.clone();
6667
dylib.map(|dl| info!(" dylib: {}", dl.0.display()));
6768
rlib.map(|rl| info!(" rlib: {}", rl.0.display()));
69+
rmeta.map(|rl| info!(" rmeta: {}", rl.0.display()));
70+
});
6871
})
6972
}
7073

@@ -278,14 +281,15 @@ impl<'a> CrateLoader<'a> {
278281
ident: ident.to_string(),
279282
dylib: lib.dylib.clone().map(|p| p.0),
280283
rlib: lib.rlib.clone().map(|p| p.0),
284+
rmeta: lib.rmeta.clone().map(|p| p.0),
281285
})
282286
} else {
283287
None
284288
};
285289
// Maintain a reference to the top most crate.
286290
let root = if root.is_some() { root } else { &crate_paths };
287291

288-
let Library { dylib, rlib, metadata } = lib;
292+
let Library { dylib, rlib, rmeta, metadata } = lib;
289293

290294
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
291295

@@ -305,6 +309,7 @@ impl<'a> CrateLoader<'a> {
305309
source: cstore::CrateSource {
306310
dylib: dylib,
307311
rlib: rlib,
312+
rmeta: rmeta,
308313
},
309314
});
310315

src/librustc_metadata/cstore.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,14 @@ use rustc::util::nodemap::{FxHashMap, NodeMap, NodeSet, DefIdMap};
2525

2626
use std::cell::{RefCell, Cell};
2727
use std::rc::Rc;
28-
use std::path::PathBuf;
2928
use flate::Bytes;
3029
use syntax::{ast, attr};
3130
use syntax::ext::base::SyntaxExtension;
3231
use syntax_pos;
3332

3433
pub use rustc::middle::cstore::{NativeLibrary, LinkagePreference};
3534
pub use rustc::middle::cstore::{NativeStatic, NativeFramework, NativeUnknown};
36-
pub use rustc::middle::cstore::{CrateSource, LinkMeta};
35+
pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource};
3736

3837
// A map from external crate numbers (as decoded from some crate file) to
3938
// local crate numbers (as generated during this session). Each external
@@ -185,7 +184,7 @@ impl CStore {
185184
// positions.
186185
pub fn do_get_used_crates(&self,
187186
prefer: LinkagePreference)
188-
-> Vec<(CrateNum, Option<PathBuf>)> {
187+
-> Vec<(CrateNum, LibSource)> {
189188
let mut ordering = Vec::new();
190189
for (&num, _) in self.metas.borrow().iter() {
191190
self.push_dependencies_in_postorder(&mut ordering, num);
@@ -201,6 +200,16 @@ impl CStore {
201200
LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0),
202201
LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0),
203202
};
203+
let path = match path {
204+
Some(p) => LibSource::Some(p),
205+
None => {
206+
if data.rmeta.is_some() {
207+
LibSource::MetadataOnly
208+
} else {
209+
LibSource::None
210+
}
211+
}
212+
};
204213
Some((cnum, path))
205214
})
206215
.collect::<Vec<_>>();

src/librustc_metadata/cstore_impl.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use encoder;
1313
use locator;
1414
use schema;
1515

16-
use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, DepKind, ExternCrate};
16+
use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, LibSource, DepKind, ExternCrate};
1717
use rustc::middle::cstore::{NativeLibrary, LinkMeta, LinkagePreference, LoadedMacro};
1818
use rustc::hir::def::{self, Def};
1919
use rustc::middle::lang_items;
@@ -28,7 +28,6 @@ use rustc::mir::Mir;
2828
use rustc::util::nodemap::{NodeSet, DefIdMap};
2929
use rustc_back::PanicStrategy;
3030

31-
use std::path::PathBuf;
3231
use syntax::ast;
3332
use syntax::attr;
3433
use syntax::parse::{token, new_parser_from_source_str};
@@ -544,7 +543,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
544543
locator::meta_section_name(target)
545544
}
546545

547-
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
546+
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
548547
{
549548
self.do_get_used_crates(prefer)
550549
}

src/librustc_metadata/locator.rs

+34-18
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@
5353
//! is a platform-defined dynamic library. Each library has a metadata somewhere
5454
//! inside of it.
5555
//!
56+
//! A third kind of dependency is an rmeta file. These are rlibs, which contain
57+
//! metadata, but no code. To a first approximation, these are treated in the
58+
//! same way as rlibs. Where there is both an rlib and an rmeta file, the rlib
59+
//! gets priority (even if the rmeta file is newer). An rmeta file is only
60+
//! useful for checking a downstream crate, attempting to link one will cause an
61+
//! error.
62+
//!
5663
//! When translating a crate name to a crate on the filesystem, we all of a
5764
//! sudden need to take into account both rlibs and dylibs! Linkage later on may
5865
//! use either one of these files, as each has their pros/cons. The job of crate
@@ -275,33 +282,31 @@ pub struct CratePaths {
275282
pub ident: String,
276283
pub dylib: Option<PathBuf>,
277284
pub rlib: Option<PathBuf>,
285+
pub rmeta: Option<PathBuf>,
278286
}
279287

280288
pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
281289

282290
#[derive(Copy, Clone, PartialEq)]
283291
enum CrateFlavor {
284292
Rlib,
293+
Rmeta,
285294
Dylib,
286295
}
287296

288297
impl fmt::Display for CrateFlavor {
289298
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
290299
f.write_str(match *self {
291300
CrateFlavor::Rlib => "rlib",
301+
CrateFlavor::Rmeta => "rmeta",
292302
CrateFlavor::Dylib => "dylib",
293303
})
294304
}
295305
}
296306

297307
impl CratePaths {
298308
fn paths(&self) -> Vec<PathBuf> {
299-
match (&self.dylib, &self.rlib) {
300-
(&None, &None) => vec![],
301-
(&Some(ref p), &None) |
302-
(&None, &Some(ref p)) => vec![p.clone()],
303-
(&Some(ref p1), &Some(ref p2)) => vec![p1.clone(), p2.clone()],
304-
}
309+
self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).cloned().collect()
305310
}
306311
}
307312

@@ -457,11 +462,13 @@ impl<'a> Context<'a> {
457462
None => return FileDoesntMatch,
458463
Some(file) => file,
459464
};
460-
let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
461-
(&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], true)
465+
let (hash, found_kind) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
466+
(&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
467+
} else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") {
468+
(&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
462469
} else if file.starts_with(&dylib_prefix) &&
463470
file.ends_with(&dypair.1) {
464-
(&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], false)
471+
(&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
465472
} else {
466473
if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
467474
staticlibs.push(CrateMismatch {
@@ -475,14 +482,14 @@ impl<'a> Context<'a> {
475482

476483
let hash_str = hash.to_string();
477484
let slot = candidates.entry(hash_str)
478-
.or_insert_with(|| (FxHashMap(), FxHashMap()));
479-
let (ref mut rlibs, ref mut dylibs) = *slot;
485+
.or_insert_with(|| (FxHashMap(), FxHashMap(), FxHashMap()));
486+
let (ref mut rlibs, ref mut rmetas, ref mut dylibs) = *slot;
480487
fs::canonicalize(path)
481488
.map(|p| {
482-
if rlib {
483-
rlibs.insert(p, kind);
484-
} else {
485-
dylibs.insert(p, kind);
489+
match found_kind {
490+
CrateFlavor::Rlib => { rlibs.insert(p, kind); }
491+
CrateFlavor::Rmeta => { rmetas.insert(p, kind); }
492+
CrateFlavor::Dylib => { dylibs.insert(p, kind); }
486493
}
487494
FileMatches
488495
})
@@ -499,15 +506,17 @@ impl<'a> Context<'a> {
499506
// libraries corresponds to the crate id and hash criteria that this
500507
// search is being performed for.
501508
let mut libraries = FxHashMap();
502-
for (_hash, (rlibs, dylibs)) in candidates {
509+
for (_hash, (rlibs, rmetas, dylibs)) in candidates {
503510
let mut slot = None;
504511
let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot);
512+
let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot);
505513
let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot);
506514
if let Some((h, m)) = slot {
507515
libraries.insert(h,
508516
Library {
509517
dylib: dylib,
510518
rlib: rlib,
519+
rmeta: rmeta,
511520
metadata: m,
512521
});
513522
}
@@ -703,6 +712,7 @@ impl<'a> Context<'a> {
703712
let sess = self.sess;
704713
let dylibname = self.dylibname();
705714
let mut rlibs = FxHashMap();
715+
let mut rmetas = FxHashMap();
706716
let mut dylibs = FxHashMap();
707717
{
708718
let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| {
@@ -744,6 +754,8 @@ impl<'a> Context<'a> {
744754
for loc in locs {
745755
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
746756
rlibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
757+
} else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
758+
rmetas.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
747759
} else {
748760
dylibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
749761
}
@@ -753,16 +765,18 @@ impl<'a> Context<'a> {
753765
// Extract the rlib/dylib pair.
754766
let mut slot = None;
755767
let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot);
768+
let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot);
756769
let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot);
757770

758-
if rlib.is_none() && dylib.is_none() {
771+
if rlib.is_none() && rmeta.is_none() && dylib.is_none() {
759772
return None;
760773
}
761774
match slot {
762775
Some((_, metadata)) => {
763776
Some(Library {
764777
dylib: dylib,
765778
rlib: rlib,
779+
rmeta: rmeta,
766780
metadata: metadata,
767781
})
768782
}
@@ -832,7 +846,7 @@ fn get_metadata_section_imp(target: &Target,
832846
if !filename.exists() {
833847
return Err(format!("no such file: '{}'", filename.display()));
834848
}
835-
if flavor == CrateFlavor::Rlib {
849+
if flavor == CrateFlavor::Rlib || flavor == CrateFlavor::Rmeta {
836850
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
837851
// internally to read the file. We also avoid even using a memcpy by
838852
// 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) ->
933947
let filename = path.file_name().unwrap().to_str().unwrap();
934948
let flavor = if filename.ends_with(".rlib") {
935949
CrateFlavor::Rlib
950+
} else if filename.ends_with(".rmeta") {
951+
CrateFlavor::Rmeta
936952
} else {
937953
CrateFlavor::Dylib
938954
};

0 commit comments

Comments
 (0)