Skip to content

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

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

Merged
merged 4 commits into from
Dec 29, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Support --emit=foo,metadata
  • Loading branch information
nrc committed Dec 29, 2016
commit b059a80d4c3911a9e59d517930ee6928b329cc35
2 changes: 1 addition & 1 deletion src/librustc/middle/dependency_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub fn calculate(sess: &session::Session) {

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

Expand Down
13 changes: 13 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,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
77 changes: 52 additions & 25 deletions src/librustc_trans/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub fn link_binary(sess: &Session,
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 ||
sess.opts.output_types.contains_key(&OutputType::Metadata)) &&
!sess.opts.output_types.should_trans()) &&
crate_type == config::CrateTypeExecutable {
continue;
}
Expand All @@ -201,13 +201,13 @@ 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 {
if !sess.opts.output_types.contains_key(&OutputType::Metadata) {
if sess.opts.output_types.should_trans() {
for obj in object_filenames(trans, outputs) {
remove(sess, &obj);
}
Expand Down Expand Up @@ -256,16 +256,21 @@ 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);

if outputs.outputs.contains_key(&OutputType::Metadata) {
return outputs.out_directory.join(&format!("lib{}.rmeta", libname));
}

match crate_type {
config::CrateTypeRlib => {
outputs.out_directory.join(&format!("lib{}.rlib", libname))
Expand Down Expand Up @@ -327,37 +332,58 @@ 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)),
};

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);
} else {
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,
Expand All @@ -371,9 +397,10 @@ fn link_binary_output(sess: &Session,
outputs, tmpdir.path());
}
}
out_filenames.push(out_filename);
}

out_filename
out_filenames
}

fn object_filenames(trans: &CrateTranslation,
Expand Down