Skip to content

Commit

Permalink
Auto merge of #38571 - nrc:emit-metadata-change, r=alexcrichton
Browse files Browse the repository at this point in the history
Change --crate-type metadata to --emit=metadata

WIP
  • Loading branch information
bors committed Dec 29, 2016
2 parents ebc293b + b059a80 commit e571f2d
Show file tree
Hide file tree
Showing 19 changed files with 154 additions and 77 deletions.
6 changes: 5 additions & 1 deletion src/librustc/middle/dependency_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ pub fn calculate(sess: &session::Session) {

fn calculate_type(sess: &session::Session,
ty: config::CrateType) -> DependencyList {
if !sess.opts.output_types.should_trans() {
return Vec::new();
}

match ty {
// If the global prefer_dynamic switch is turned off, first attempt
// static linkage (this can fail).
Expand All @@ -114,7 +118,7 @@ fn calculate_type(sess: &session::Session,

// No linkage happens with rlibs, we just needed the metadata (which we
// got long ago), so don't bother with anything.
config::CrateTypeRlib | config::CrateTypeMetadata => return Vec::new(),
config::CrateTypeRlib => return Vec::new(),

// Staticlibs and cdylibs must have all static dependencies. If any fail
// to be found, we generate some nice pretty errors.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ReachableContext<'a, 'tcx> {
let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
*ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib ||
*ty == config::CrateTypeProcMacro || *ty == config::CrateTypeMetadata
*ty == config::CrateTypeProcMacro
});
ReachableContext {
tcx: tcx,
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/middle/weak_lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
config::CrateTypeCdylib |
config::CrateTypeExecutable |
config::CrateTypeStaticlib => true,
config::CrateTypeRlib |
config::CrateTypeMetadata => false,
config::CrateTypeRlib => false,
}
});
if !needs_check {
Expand Down
46 changes: 36 additions & 10 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub enum OutputType {
Bitcode,
Assembly,
LlvmAssembly,
Metadata,
Object,
Exe,
DepInfo,
Expand All @@ -86,7 +87,8 @@ impl OutputType {
OutputType::Bitcode |
OutputType::Assembly |
OutputType::LlvmAssembly |
OutputType::Object => false,
OutputType::Object |
OutputType::Metadata => false,
}
}

Expand All @@ -96,6 +98,7 @@ impl OutputType {
OutputType::Assembly => "asm",
OutputType::LlvmAssembly => "llvm-ir",
OutputType::Object => "obj",
OutputType::Metadata => "metadata",
OutputType::Exe => "link",
OutputType::DepInfo => "dep-info",
}
Expand All @@ -107,6 +110,7 @@ impl OutputType {
OutputType::Assembly => "s",
OutputType::LlvmAssembly => "ll",
OutputType::Object => "o",
OutputType::Metadata => "rmeta",
OutputType::DepInfo => "d",
OutputType::Exe => "",
}
Expand Down Expand Up @@ -152,6 +156,19 @@ impl OutputTypes {
pub fn values<'a>(&'a self) -> BTreeMapValuesIter<'a, OutputType, Option<PathBuf>> {
self.0.values()
}

// True if any of the output types require codegen or linking.
pub fn should_trans(&self) -> bool {
self.0.keys().any(|k| match *k {
OutputType::Bitcode |
OutputType::Assembly |
OutputType::LlvmAssembly |
OutputType::Object |
OutputType::Exe => true,
OutputType::Metadata |
OutputType::DepInfo => false,
})
}
}


Expand Down Expand Up @@ -482,7 +499,6 @@ pub enum CrateType {
CrateTypeStaticlib,
CrateTypeCdylib,
CrateTypeProcMacro,
CrateTypeMetadata,
}

#[derive(Clone, Hash)]
Expand Down Expand Up @@ -1159,12 +1175,12 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
assumed.", "[KIND=]NAME"),
opt::multi_s("", "crate-type", "Comma separated list of types of crates
for the compiler to emit",
"[bin|lib|rlib|dylib|cdylib|staticlib|metadata]"),
"[bin|lib|rlib|dylib|cdylib|staticlib]"),
opt::opt_s("", "crate-name", "Specify the name of the crate being built",
"NAME"),
opt::multi_s("", "emit", "Comma separated list of types of output for \
the compiler to emit",
"[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info]"),
opt::multi_s("", "print", "Comma separated list of compiler information to \
print on stdout", &print_opts.join("|")),
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
Expand Down Expand Up @@ -1293,7 +1309,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
};

let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
let (crate_types, emit_metadata) = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_error(error_format, &e[..]));

let mut lint_opts = vec![];
Expand Down Expand Up @@ -1327,6 +1343,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
"llvm-ir" => OutputType::LlvmAssembly,
"llvm-bc" => OutputType::Bitcode,
"obj" => OutputType::Object,
"metadata" => OutputType::Metadata,
"link" => OutputType::Exe,
"dep-info" => OutputType::DepInfo,
part => {
Expand All @@ -1339,7 +1356,9 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
}
}
};
if output_types.is_empty() {
if emit_metadata {
output_types.insert(OutputType::Metadata, None);
} else if output_types.is_empty() {
output_types.insert(OutputType::Exe, None);
}

Expand Down Expand Up @@ -1541,8 +1560,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
cfg)
}

pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
pub fn parse_crate_types_from_list(list_list: Vec<String>)
-> Result<(Vec<CrateType>, bool), String> {
let mut crate_types: Vec<CrateType> = Vec::new();
let mut emit_metadata = false;
for unparsed_crate_type in &list_list {
for part in unparsed_crate_type.split(',') {
let new_part = match part {
Expand All @@ -1553,7 +1574,13 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
"cdylib" => CrateTypeCdylib,
"bin" => CrateTypeExecutable,
"proc-macro" => CrateTypeProcMacro,
"metadata" => CrateTypeMetadata,
// FIXME(#38640) remove this when Cargo is fixed.
"metadata" => {
early_warn(ErrorOutputType::default(), "--crate-type=metadata is deprecated, \
prefer --emit=metadata");
emit_metadata = true;
CrateTypeRlib
}
_ => {
return Err(format!("unknown crate type: `{}`",
part));
Expand All @@ -1565,7 +1592,7 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
}
}

return Ok(crate_types);
return Ok((crate_types, emit_metadata));
}

pub mod nightly_options {
Expand Down Expand Up @@ -1638,7 +1665,6 @@ impl fmt::Display for CrateType {
CrateTypeStaticlib => "staticlib".fmt(f),
CrateTypeCdylib => "cdylib".fmt(f),
CrateTypeProcMacro => "proc-macro".fmt(f),
CrateTypeMetadata => "metadata".fmt(f),
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1182,9 +1182,6 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
Some(ref n) if *n == "rlib" => {
Some(config::CrateTypeRlib)
}
Some(ref n) if *n == "metadata" => {
Some(config::CrateTypeMetadata)
}
Some(ref n) if *n == "dylib" => {
Some(config::CrateTypeDylib)
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
control.after_hir_lowering.stop = Compilation::Stop;
}

if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) {
if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe ||
i == OutputType::Metadata) {
control.after_llvm.stop = Compilation::Stop;
}

Expand Down
3 changes: 1 addition & 2 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,8 +799,7 @@ impl<'a> CrateLoader<'a> {
config::CrateTypeProcMacro |
config::CrateTypeCdylib |
config::CrateTypeStaticlib => need_lib_alloc = true,
config::CrateTypeRlib |
config::CrateTypeMetadata => {}
config::CrateTypeRlib => {}
}
}
if !need_lib_alloc && !need_exe_alloc { return }
Expand Down
110 changes: 71 additions & 39 deletions src/librustc_trans/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ pub fn link_binary(sess: &Session,
let mut out_filenames = Vec::new();
for &crate_type in sess.crate_types.borrow().iter() {
// Ignore executable crates if we have -Z no-trans, as they will error.
if sess.opts.debugging_opts.no_trans &&
if (sess.opts.debugging_opts.no_trans ||
!sess.opts.output_types.should_trans()) &&
crate_type == config::CrateTypeExecutable {
continue;
}
Expand All @@ -200,15 +201,16 @@ pub fn link_binary(sess: &Session,
bug!("invalid output type `{:?}` for target os `{}`",
crate_type, sess.opts.target_triple);
}
let out_file = link_binary_output(sess, trans, crate_type, outputs,
crate_name);
out_filenames.push(out_file);
let mut out_files = link_binary_output(sess, trans, crate_type, outputs, crate_name);
out_filenames.append(&mut out_files);
}

// Remove the temporary object file and metadata if we aren't saving temps
if !sess.opts.cg.save_temps {
for obj in object_filenames(trans, outputs) {
remove(sess, &obj);
if sess.opts.output_types.should_trans() {
for obj in object_filenames(trans, outputs) {
remove(sess, &obj);
}
}
remove(sess, &outputs.with_extension("metadata.o"));
}
Expand Down Expand Up @@ -254,18 +256,25 @@ fn is_writeable(p: &Path) -> bool {
}
}

fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilenames) -> PathBuf {
let out_filename = outputs.single_output_file.clone()
.unwrap_or(outputs
.out_directory
.join(&format!("lib{}{}.rmeta", crate_name, sess.opts.cg.extra_filename)));
check_file_is_writeable(&out_filename, sess);
out_filename
}

pub fn filename_for_input(sess: &Session,
crate_type: config::CrateType,
crate_name: &str,
outputs: &OutputFilenames) -> PathBuf {
let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename);

match crate_type {
config::CrateTypeRlib => {
outputs.out_directory.join(&format!("lib{}.rlib", libname))
}
config::CrateTypeMetadata => {
outputs.out_directory.join(&format!("lib{}.rmeta", libname))
}
config::CrateTypeCdylib |
config::CrateTypeProcMacro |
config::CrateTypeDylib => {
Expand Down Expand Up @@ -323,52 +332,75 @@ pub fn each_linked_rlib(sess: &Session,
}
}

fn out_filename(sess: &Session,
crate_type: config::CrateType,
outputs: &OutputFilenames,
crate_name: &str)
-> PathBuf {
let default_filename = filename_for_input(sess, crate_type, crate_name, outputs);
let out_filename = outputs.outputs.get(&OutputType::Exe)
.and_then(|s| s.to_owned())
.or_else(|| outputs.single_output_file.clone())
.unwrap_or(default_filename);

check_file_is_writeable(&out_filename, sess);

out_filename
}

// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers
// check this already -- however, the Linux linker will happily overwrite a
// read-only file. We should be consistent.
fn check_file_is_writeable(file: &Path, sess: &Session) {
if !is_writeable(file) {
sess.fatal(&format!("output file {} is not writeable -- check its \
permissions", file.display()));
}
}

fn link_binary_output(sess: &Session,
trans: &CrateTranslation,
crate_type: config::CrateType,
outputs: &OutputFilenames,
crate_name: &str) -> PathBuf {
crate_name: &str) -> Vec<PathBuf> {
let objects = object_filenames(trans, outputs);
let default_filename = filename_for_input(sess, crate_type, crate_name,
outputs);
let out_filename = outputs.outputs.get(&OutputType::Exe)
.and_then(|s| s.to_owned())
.or_else(|| outputs.single_output_file.clone())
.unwrap_or(default_filename);

// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers
// check this already -- however, the Linux linker will happily overwrite a
// read-only file. We should be consistent.
for file in objects.iter().chain(Some(&out_filename)) {
if !is_writeable(file) {
sess.fatal(&format!("output file {} is not writeable -- check its \
permissions", file.display()));
}
for file in &objects {
check_file_is_writeable(file, sess);
}

let tmpdir = match TempDir::new("rustc") {
Ok(tmpdir) => tmpdir,
Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
};

match crate_type {
config::CrateTypeRlib => {
link_rlib(sess, Some(trans), &objects, &out_filename,
tmpdir.path()).build();
}
config::CrateTypeStaticlib => {
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,
outputs, tmpdir.path());
let mut out_filenames = vec![];

if outputs.outputs.contains_key(&OutputType::Metadata) {
let out_filename = filename_for_metadata(sess, crate_name, outputs);
emit_metadata(sess, trans, &out_filename);
out_filenames.push(out_filename);
}

if outputs.outputs.should_trans() {
let out_filename = out_filename(sess, crate_type, outputs, crate_name);
match crate_type {
config::CrateTypeRlib => {
link_rlib(sess, Some(trans), &objects, &out_filename,
tmpdir.path()).build();
}
config::CrateTypeStaticlib => {
link_staticlib(sess, &objects, &out_filename, tmpdir.path());
}
_ => {
link_natively(sess, crate_type, &objects, &out_filename, trans,
outputs, tmpdir.path());
}
}
out_filenames.push(out_filename);
}

out_filename
out_filenames
}

fn object_filenames(trans: &CrateTranslation,
Expand Down
1 change: 0 additions & 1 deletion src/librustc_trans/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {

config::CrateTypeDylib |
config::CrateTypeRlib |
config::CrateTypeMetadata |
config::CrateTypeProcMacro => false,
}
}
Expand Down
Loading

0 comments on commit e571f2d

Please sign in to comment.