Skip to content

Commit af1b195

Browse files
committed
Rebasing and review changes
1 parent baedc3b commit af1b195

File tree

11 files changed

+126
-44
lines changed

11 files changed

+126
-44
lines changed

src/librustc/middle/cstore.rs

+12
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@ pub struct CrateSource {
6565
pub rmeta: Option<(PathBuf, PathKind)>,
6666
}
6767

68+
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
69+
pub enum DepKind {
70+
/// A dependency that is only used for its macros.
71+
MacrosOnly,
72+
/// A dependency that is always injected into the dependency list and so
73+
/// doesn't need to be linked to an rlib, e.g. the injected allocator.
74+
Implicit,
75+
/// A dependency that is required by an rlib version of this crate.
76+
/// Ordinary `extern crate`s result in `Explicit` dependencies.
77+
Explicit,
78+
}
79+
6880
#[derive(PartialEq, Clone, Debug)]
6981
pub enum LibSource {
7082
Some(PathBuf),

src/librustc/session/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@ impl fmt::Display for CrateType {
16341634
CrateTypeStaticlib => "staticlib".fmt(f),
16351635
CrateTypeCdylib => "cdylib".fmt(f),
16361636
CrateTypeProcMacro => "proc-macro".fmt(f),
1637-
CrateTypeMetadata => "rmeta".fmt(f),
1637+
CrateTypeMetadata => "metadata".fmt(f),
16381638
}
16391639
}
16401640
}

src/librustc_metadata/creader.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,7 @@ fn dump_crates(cstore: &CStore) {
6767
dylib.map(|dl| info!(" dylib: {}", dl.0.display()));
6868
rlib.map(|rl| info!(" rlib: {}", rl.0.display()));
6969
rmeta.map(|rl| info!(" rmeta: {}", rl.0.display()));
70-
});
71-
})
70+
});
7271
}
7372

7473
#[derive(Debug)]

src/librustc_metadata/cstore.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
4343
pub enum MetadataBlob {
4444
Inflated(Bytes),
4545
Archive(locator::ArchiveMetadata),
46+
Raw(Vec<u8>),
4647
}
4748

4849
/// Holds information about a syntax_pos::FileMap imported from another crate.
@@ -203,7 +204,7 @@ impl CStore {
203204
let path = match path {
204205
Some(p) => LibSource::Some(p),
205206
None => {
206-
if data.rmeta.is_some() {
207+
if data.source.rmeta.is_some() {
207208
LibSource::MetadataOnly
208209
} else {
209210
LibSource::None

src/librustc_metadata/decoder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ pub trait Metadata<'a, 'tcx>: Copy {
8888
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
8989
fn raw_bytes(self) -> &'a [u8] {
9090
match *self {
91-
MetadataBlob::Inflated(ref vec) => &vec[..],
91+
MetadataBlob::Inflated(ref vec) => vec,
9292
MetadataBlob::Archive(ref ar) => ar.as_slice(),
93+
MetadataBlob::Raw(ref vec) => vec,
9394
}
9495
}
9596
}

src/librustc_metadata/locator.rs

+33-22
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
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
56+
//! A third kind of dependency is an rmeta file. These are metadata files and do
57+
//! not contain any code, etc. To a first approximation, these are treated in the
5858
//! same way as rlibs. Where there is both an rlib and an rmeta file, the rlib
5959
//! gets priority (even if the rmeta file is newer). An rmeta file is only
6060
//! useful for checking a downstream crate, attempting to link one will cause an
@@ -239,8 +239,8 @@ use rustc_back::target::Target;
239239

240240
use std::cmp;
241241
use std::fmt;
242-
use std::fs;
243-
use std::io;
242+
use std::fs::{self, File};
243+
use std::io::{self, Read};
244244
use std::path::{Path, PathBuf};
245245
use std::ptr;
246246
use std::slice;
@@ -462,22 +462,23 @@ impl<'a> Context<'a> {
462462
None => return FileDoesntMatch,
463463
Some(file) => file,
464464
};
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)
469-
} else if file.starts_with(&dylib_prefix) &&
470-
file.ends_with(&dypair.1) {
471-
(&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
472-
} else {
473-
if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
474-
staticlibs.push(CrateMismatch {
475-
path: path.to_path_buf(),
476-
got: "static".to_string(),
477-
});
478-
}
479-
return FileDoesntMatch;
480-
};
465+
let (hash, found_kind) =
466+
if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
467+
(&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
468+
} else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") {
469+
(&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
470+
} else if file.starts_with(&dylib_prefix) &&
471+
file.ends_with(&dypair.1) {
472+
(&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
473+
} else {
474+
if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
475+
staticlibs.push(CrateMismatch {
476+
path: path.to_path_buf(),
477+
got: "static".to_string(),
478+
});
479+
}
480+
return FileDoesntMatch;
481+
};
481482
info!("lib candidate: {}", path.display());
482483

483484
let hash_str = hash.to_string();
@@ -731,7 +732,8 @@ impl<'a> Context<'a> {
731732
return false;
732733
}
733734
};
734-
if file.starts_with("lib") && file.ends_with(".rlib") {
735+
if file.starts_with("lib") &&
736+
(file.ends_with(".rlib") || file.ends_with(".rmeta")) {
735737
return true;
736738
} else {
737739
let (ref prefix, ref suffix) = dylibname;
@@ -846,7 +848,7 @@ fn get_metadata_section_imp(target: &Target,
846848
if !filename.exists() {
847849
return Err(format!("no such file: '{}'", filename.display()));
848850
}
849-
if flavor == CrateFlavor::Rlib || flavor == CrateFlavor::Rmeta {
851+
if flavor == CrateFlavor::Rlib {
850852
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
851853
// internally to read the file. We also avoid even using a memcpy by
852854
// just keeping the archive along while the metadata is in use.
@@ -864,6 +866,15 @@ fn get_metadata_section_imp(target: &Target,
864866
Ok(blob)
865867
}
866868
};
869+
} else if flavor == CrateFlavor::Rmeta {
870+
let mut file = File::open(filename).map_err(|_|
871+
format!("could not open file: '{}'", filename.display()))?;
872+
let mut buf = vec![];
873+
file.read_to_end(&mut buf).map_err(|_|
874+
format!("failed to read rlib metadata: '{}'", filename.display()))?;
875+
let blob = MetadataBlob::Raw(buf);
876+
verify_decompressed_encoding_version(&blob, filename)?;
877+
return Ok(blob);
867878
}
868879
unsafe {
869880
let buf = common::path2cstr(filename);

src/librustc_trans/back/link.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ pub fn link_binary(sess: &Session,
190190
let mut out_filenames = Vec::new();
191191
for &crate_type in sess.crate_types.borrow().iter() {
192192
// Ignore executable crates if we have -Z no-trans, as they will error.
193-
// TODO do we need to check for CrateTypeMetadata here?
194193
if sess.opts.debugging_opts.no_trans &&
195194
crate_type == config::CrateTypeExecutable {
196195
continue;
@@ -312,7 +311,8 @@ pub fn each_linked_rlib(sess: &Session,
312311
let path = match path {
313312
LibSource::Some(p) => p,
314313
LibSource::MetadataOnly => {
315-
sess.fatal(&format!("could not find rlib for: `{}`, found rmeta (metadata) file", name));
314+
sess.fatal(&format!("could not find rlib for: `{}`, found rmeta (metadata) file",
315+
name));
316316
}
317317
LibSource::None => {
318318
sess.fatal(&format!("could not find rlib for: `{}`", name));
@@ -351,13 +351,16 @@ fn link_binary_output(sess: &Session,
351351
};
352352

353353
match crate_type {
354-
config::CrateTypeRlib | config::CrateTypeMetadata => {
354+
config::CrateTypeRlib => {
355355
link_rlib(sess, Some(trans), &objects, &out_filename,
356356
tmpdir.path()).build();
357357
}
358358
config::CrateTypeStaticlib => {
359359
link_staticlib(sess, &objects, &out_filename, tmpdir.path());
360360
}
361+
config::CrateTypeMetadata => {
362+
emit_metadata(sess, trans, &out_filename);
363+
}
361364
_ => {
362365
link_natively(sess, crate_type, &objects, &out_filename, trans,
363366
outputs, tmpdir.path());
@@ -396,6 +399,13 @@ fn archive_config<'a>(sess: &'a Session,
396399
}
397400
}
398401

402+
fn emit_metadata<'a>(sess: &'a Session, trans: &CrateTranslation, out_filename: &Path) {
403+
let result = fs::File::create(out_filename).and_then(|mut f| f.write_all(&trans.metadata));
404+
if let Err(e) = result {
405+
sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
406+
}
407+
}
408+
399409
// Create an 'rlib'
400410
//
401411
// An rlib in its current incarnation is essentially a renamed .a file. The
@@ -471,15 +481,7 @@ fn link_rlib<'a>(sess: &'a Session,
471481
// here so concurrent builds in the same directory don't try to use
472482
// the same filename for metadata (stomping over one another)
473483
let metadata = tmpdir.join(sess.cstore.metadata_filename());
474-
match fs::File::create(&metadata).and_then(|mut f| {
475-
f.write_all(&trans.metadata)
476-
}) {
477-
Ok(..) => {}
478-
Err(e) => {
479-
sess.fatal(&format!("failed to write {}: {}",
480-
metadata.display(), e));
481-
}
482-
}
484+
emit_metadata(sess, trans, &metadata);
483485
ab.add_file(&metadata);
484486

485487
// For LTO purposes, the bytecode of this library is also inserted

src/librustc_trans/back/write.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -691,12 +691,10 @@ pub fn run_passes(sess: &Session,
691691
// Whenever an rlib is created, the bitcode is inserted into the
692692
// archive in order to allow LTO against it.
693693
let needs_crate_bitcode =
694-
(sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
695-
sess.opts.output_types.contains_key(&OutputType::Exe)) ||
696-
sess.crate_types.borrow().contains(&config::CrateTypeMetadata);
694+
sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
695+
sess.opts.output_types.contains_key(&OutputType::Exe);
697696
let needs_crate_object =
698-
sess.opts.output_types.contains_key(&OutputType::Exe) ||
699-
sess.crate_types.borrow().contains(&config::CrateTypeMetadata);
697+
sess.opts.output_types.contains_key(&OutputType::Exe);
700698
if needs_crate_bitcode {
701699
modules_config.emit_bc = true;
702700
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// no-prefer-dynamic
12+
13+
#![crate_type="rlib"]
14+
#![crate_name="rmeta_aux"]
15+
16+
pub struct Foo {
17+
pub field: i32,
18+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// no-prefer-dynamic
12+
13+
#![crate_type="metadata"]
14+
#![crate_name="rmeta_aux"]
15+
16+
pub struct Foo {
17+
pub field2: i32,
18+
}

src/test/run-pass/rmeta.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that using rlibs and rmeta dep crates work together. Specifically, that
12+
// there can be both an rmeta and an rlib file and rustc will prefer the rlib.
13+
14+
// aux-build:rmeta_rmeta.rs
15+
// aux-build:rmeta_rlib.rs
16+
17+
extern crate rmeta_aux;
18+
use rmeta_aux::Foo;
19+
20+
pub fn main() {
21+
let _ = Foo { field: 42 };
22+
}

0 commit comments

Comments
 (0)