Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change --crate-type metadata to --emit=metadata #38571

Merged
merged 4 commits into from
Dec 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given our discussion today during triage, I think we can remove this entirely

"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