Rebasing and review changes
This commit is contained in:
parent
baedc3b70f
commit
af1b19555c
@ -65,6 +65,18 @@ pub struct CrateSource {
|
|||||||
pub rmeta: 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)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
pub enum LibSource {
|
pub enum LibSource {
|
||||||
Some(PathBuf),
|
Some(PathBuf),
|
||||||
|
@ -1634,7 +1634,7 @@ impl fmt::Display for CrateType {
|
|||||||
CrateTypeStaticlib => "staticlib".fmt(f),
|
CrateTypeStaticlib => "staticlib".fmt(f),
|
||||||
CrateTypeCdylib => "cdylib".fmt(f),
|
CrateTypeCdylib => "cdylib".fmt(f),
|
||||||
CrateTypeProcMacro => "proc-macro".fmt(f),
|
CrateTypeProcMacro => "proc-macro".fmt(f),
|
||||||
CrateTypeMetadata => "rmeta".fmt(f),
|
CrateTypeMetadata => "metadata".fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,7 @@ fn dump_crates(cstore: &CStore) {
|
|||||||
dylib.map(|dl| info!(" dylib: {}", dl.0.display()));
|
dylib.map(|dl| info!(" dylib: {}", dl.0.display()));
|
||||||
rlib.map(|rl| info!(" rlib: {}", rl.0.display()));
|
rlib.map(|rl| info!(" rlib: {}", rl.0.display()));
|
||||||
rmeta.map(|rl| info!(" rmeta: {}", rl.0.display()));
|
rmeta.map(|rl| info!(" rmeta: {}", rl.0.display()));
|
||||||
});
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -43,6 +43,7 @@ pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
|
|||||||
pub enum MetadataBlob {
|
pub enum MetadataBlob {
|
||||||
Inflated(Bytes),
|
Inflated(Bytes),
|
||||||
Archive(locator::ArchiveMetadata),
|
Archive(locator::ArchiveMetadata),
|
||||||
|
Raw(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Holds information about a syntax_pos::FileMap imported from another crate.
|
/// Holds information about a syntax_pos::FileMap imported from another crate.
|
||||||
@ -203,7 +204,7 @@ impl CStore {
|
|||||||
let path = match path {
|
let path = match path {
|
||||||
Some(p) => LibSource::Some(p),
|
Some(p) => LibSource::Some(p),
|
||||||
None => {
|
None => {
|
||||||
if data.rmeta.is_some() {
|
if data.source.rmeta.is_some() {
|
||||||
LibSource::MetadataOnly
|
LibSource::MetadataOnly
|
||||||
} else {
|
} else {
|
||||||
LibSource::None
|
LibSource::None
|
||||||
|
@ -88,8 +88,9 @@ pub trait Metadata<'a, 'tcx>: Copy {
|
|||||||
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
|
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
|
||||||
fn raw_bytes(self) -> &'a [u8] {
|
fn raw_bytes(self) -> &'a [u8] {
|
||||||
match *self {
|
match *self {
|
||||||
MetadataBlob::Inflated(ref vec) => &vec[..],
|
MetadataBlob::Inflated(ref vec) => vec,
|
||||||
MetadataBlob::Archive(ref ar) => ar.as_slice(),
|
MetadataBlob::Archive(ref ar) => ar.as_slice(),
|
||||||
|
MetadataBlob::Raw(ref vec) => vec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,8 @@
|
|||||||
//! is a platform-defined dynamic library. Each library has a metadata somewhere
|
//! is a platform-defined dynamic library. Each library has a metadata somewhere
|
||||||
//! inside of it.
|
//! inside of it.
|
||||||
//!
|
//!
|
||||||
//! A third kind of dependency is an rmeta file. These are rlibs, which contain
|
//! A third kind of dependency is an rmeta file. These are metadata files and do
|
||||||
//! metadata, but no code. To a first approximation, these are treated in the
|
//! 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
|
//! 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
|
//! 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
|
//! useful for checking a downstream crate, attempting to link one will cause an
|
||||||
@ -239,8 +239,8 @@ use rustc_back::target::Target;
|
|||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs;
|
use std::fs::{self, File};
|
||||||
use std::io;
|
use std::io::{self, Read};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
@ -462,22 +462,23 @@ impl<'a> Context<'a> {
|
|||||||
None => return FileDoesntMatch,
|
None => return FileDoesntMatch,
|
||||||
Some(file) => file,
|
Some(file) => file,
|
||||||
};
|
};
|
||||||
let (hash, found_kind) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
|
let (hash, found_kind) =
|
||||||
(&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
|
if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
|
||||||
} else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") {
|
(&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
|
||||||
(&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
|
} else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") {
|
||||||
} else if file.starts_with(&dylib_prefix) &&
|
(&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
|
||||||
file.ends_with(&dypair.1) {
|
} else if file.starts_with(&dylib_prefix) &&
|
||||||
(&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
|
file.ends_with(&dypair.1) {
|
||||||
} else {
|
(&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
|
||||||
if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
|
} else {
|
||||||
staticlibs.push(CrateMismatch {
|
if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
|
||||||
path: path.to_path_buf(),
|
staticlibs.push(CrateMismatch {
|
||||||
got: "static".to_string(),
|
path: path.to_path_buf(),
|
||||||
});
|
got: "static".to_string(),
|
||||||
}
|
});
|
||||||
return FileDoesntMatch;
|
}
|
||||||
};
|
return FileDoesntMatch;
|
||||||
|
};
|
||||||
info!("lib candidate: {}", path.display());
|
info!("lib candidate: {}", path.display());
|
||||||
|
|
||||||
let hash_str = hash.to_string();
|
let hash_str = hash.to_string();
|
||||||
@ -731,7 +732,8 @@ impl<'a> Context<'a> {
|
|||||||
return false;
|
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;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
let (ref prefix, ref suffix) = dylibname;
|
let (ref prefix, ref suffix) = dylibname;
|
||||||
@ -846,7 +848,7 @@ fn get_metadata_section_imp(target: &Target,
|
|||||||
if !filename.exists() {
|
if !filename.exists() {
|
||||||
return Err(format!("no such file: '{}'", filename.display()));
|
return Err(format!("no such file: '{}'", filename.display()));
|
||||||
}
|
}
|
||||||
if flavor == CrateFlavor::Rlib || flavor == CrateFlavor::Rmeta {
|
if flavor == CrateFlavor::Rlib {
|
||||||
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
|
// 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
|
// internally to read the file. We also avoid even using a memcpy by
|
||||||
// just keeping the archive along while the metadata is in use.
|
// just keeping the archive along while the metadata is in use.
|
||||||
@ -864,6 +866,15 @@ fn get_metadata_section_imp(target: &Target,
|
|||||||
Ok(blob)
|
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 {
|
unsafe {
|
||||||
let buf = common::path2cstr(filename);
|
let buf = common::path2cstr(filename);
|
||||||
|
@ -190,7 +190,6 @@ pub fn link_binary(sess: &Session,
|
|||||||
let mut out_filenames = Vec::new();
|
let mut out_filenames = Vec::new();
|
||||||
for &crate_type in sess.crate_types.borrow().iter() {
|
for &crate_type in sess.crate_types.borrow().iter() {
|
||||||
// Ignore executable crates if we have -Z no-trans, as they will error.
|
// Ignore executable crates if we have -Z no-trans, as they will error.
|
||||||
// TODO do we need to check for CrateTypeMetadata here?
|
|
||||||
if sess.opts.debugging_opts.no_trans &&
|
if sess.opts.debugging_opts.no_trans &&
|
||||||
crate_type == config::CrateTypeExecutable {
|
crate_type == config::CrateTypeExecutable {
|
||||||
continue;
|
continue;
|
||||||
@ -312,7 +311,8 @@ pub fn each_linked_rlib(sess: &Session,
|
|||||||
let path = match path {
|
let path = match path {
|
||||||
LibSource::Some(p) => p,
|
LibSource::Some(p) => p,
|
||||||
LibSource::MetadataOnly => {
|
LibSource::MetadataOnly => {
|
||||||
sess.fatal(&format!("could not find rlib for: `{}`, found rmeta (metadata) file", name));
|
sess.fatal(&format!("could not find rlib for: `{}`, found rmeta (metadata) file",
|
||||||
|
name));
|
||||||
}
|
}
|
||||||
LibSource::None => {
|
LibSource::None => {
|
||||||
sess.fatal(&format!("could not find rlib for: `{}`", name));
|
sess.fatal(&format!("could not find rlib for: `{}`", name));
|
||||||
@ -351,13 +351,16 @@ fn link_binary_output(sess: &Session,
|
|||||||
};
|
};
|
||||||
|
|
||||||
match crate_type {
|
match crate_type {
|
||||||
config::CrateTypeRlib | config::CrateTypeMetadata => {
|
config::CrateTypeRlib => {
|
||||||
link_rlib(sess, Some(trans), &objects, &out_filename,
|
link_rlib(sess, Some(trans), &objects, &out_filename,
|
||||||
tmpdir.path()).build();
|
tmpdir.path()).build();
|
||||||
}
|
}
|
||||||
config::CrateTypeStaticlib => {
|
config::CrateTypeStaticlib => {
|
||||||
link_staticlib(sess, &objects, &out_filename, tmpdir.path());
|
link_staticlib(sess, &objects, &out_filename, tmpdir.path());
|
||||||
}
|
}
|
||||||
|
config::CrateTypeMetadata => {
|
||||||
|
emit_metadata(sess, trans, &out_filename);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
link_natively(sess, crate_type, &objects, &out_filename, trans,
|
link_natively(sess, crate_type, &objects, &out_filename, trans,
|
||||||
outputs, tmpdir.path());
|
outputs, tmpdir.path());
|
||||||
@ -396,6 +399,13 @@ fn archive_config<'a>(sess: &'a Session,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_metadata<'a>(sess: &'a Session, trans: &CrateTranslation, out_filename: &Path) {
|
||||||
|
let result = fs::File::create(out_filename).and_then(|mut f| f.write_all(&trans.metadata));
|
||||||
|
if let Err(e) = result {
|
||||||
|
sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create an 'rlib'
|
// Create an 'rlib'
|
||||||
//
|
//
|
||||||
// An rlib in its current incarnation is essentially a renamed .a file. The
|
// An rlib in its current incarnation is essentially a renamed .a file. The
|
||||||
@ -471,15 +481,7 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||||||
// here so concurrent builds in the same directory don't try to use
|
// here so concurrent builds in the same directory don't try to use
|
||||||
// the same filename for metadata (stomping over one another)
|
// the same filename for metadata (stomping over one another)
|
||||||
let metadata = tmpdir.join(sess.cstore.metadata_filename());
|
let metadata = tmpdir.join(sess.cstore.metadata_filename());
|
||||||
match fs::File::create(&metadata).and_then(|mut f| {
|
emit_metadata(sess, trans, &metadata);
|
||||||
f.write_all(&trans.metadata)
|
|
||||||
}) {
|
|
||||||
Ok(..) => {}
|
|
||||||
Err(e) => {
|
|
||||||
sess.fatal(&format!("failed to write {}: {}",
|
|
||||||
metadata.display(), e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ab.add_file(&metadata);
|
ab.add_file(&metadata);
|
||||||
|
|
||||||
// For LTO purposes, the bytecode of this library is also inserted
|
// For LTO purposes, the bytecode of this library is also inserted
|
||||||
|
@ -691,12 +691,10 @@ pub fn run_passes(sess: &Session,
|
|||||||
// Whenever an rlib is created, the bitcode is inserted into the
|
// Whenever an rlib is created, the bitcode is inserted into the
|
||||||
// archive in order to allow LTO against it.
|
// archive in order to allow LTO against it.
|
||||||
let needs_crate_bitcode =
|
let needs_crate_bitcode =
|
||||||
(sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
|
sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
|
||||||
sess.opts.output_types.contains_key(&OutputType::Exe)) ||
|
sess.opts.output_types.contains_key(&OutputType::Exe);
|
||||||
sess.crate_types.borrow().contains(&config::CrateTypeMetadata);
|
|
||||||
let needs_crate_object =
|
let needs_crate_object =
|
||||||
sess.opts.output_types.contains_key(&OutputType::Exe) ||
|
sess.opts.output_types.contains_key(&OutputType::Exe);
|
||||||
sess.crate_types.borrow().contains(&config::CrateTypeMetadata);
|
|
||||||
if needs_crate_bitcode {
|
if needs_crate_bitcode {
|
||||||
modules_config.emit_bc = true;
|
modules_config.emit_bc = true;
|
||||||
}
|
}
|
||||||
|
18
src/test/run-pass/auxiliary/rmeta_rlib.rs
Normal file
18
src/test/run-pass/auxiliary/rmeta_rlib.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// no-prefer-dynamic
|
||||||
|
|
||||||
|
#![crate_type="rlib"]
|
||||||
|
#![crate_name="rmeta_aux"]
|
||||||
|
|
||||||
|
pub struct Foo {
|
||||||
|
pub field: i32,
|
||||||
|
}
|
18
src/test/run-pass/auxiliary/rmeta_rmeta.rs
Normal file
18
src/test/run-pass/auxiliary/rmeta_rmeta.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// no-prefer-dynamic
|
||||||
|
|
||||||
|
#![crate_type="metadata"]
|
||||||
|
#![crate_name="rmeta_aux"]
|
||||||
|
|
||||||
|
pub struct Foo {
|
||||||
|
pub field2: i32,
|
||||||
|
}
|
22
src/test/run-pass/rmeta.rs
Normal file
22
src/test/run-pass/rmeta.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test that using rlibs and rmeta dep crates work together. Specifically, that
|
||||||
|
// there can be both an rmeta and an rlib file and rustc will prefer the rlib.
|
||||||
|
|
||||||
|
// aux-build:rmeta_rmeta.rs
|
||||||
|
// aux-build:rmeta_rlib.rs
|
||||||
|
|
||||||
|
extern crate rmeta_aux;
|
||||||
|
use rmeta_aux::Foo;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let _ = Foo { field: 42 };
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user