diff options
| author | Nick Cameron <ncameron@mozilla.com> | 2016-12-29 13:23:38 +1300 |
|---|---|---|
| committer | Nick Cameron <ncameron@mozilla.com> | 2016-12-29 18:17:07 +1300 |
| commit | b059a80d4c3911a9e59d517930ee6928b329cc35 (patch) | |
| tree | 72ce2210b39c5a7880ed7e625da09a6588baf2f1 | |
| parent | 9c8916661105322df7774378a264eb25b873401b (diff) | |
| download | rust-b059a80d4c3911a9e59d517930ee6928b329cc35.tar.gz rust-b059a80d4c3911a9e59d517930ee6928b329cc35.zip | |
Support --emit=foo,metadata
| -rw-r--r-- | src/librustc/middle/dependency_format.rs | 2 | ||||
| -rw-r--r-- | src/librustc/session/config.rs | 13 | ||||
| -rw-r--r-- | src/librustc_trans/back/link.rs | 77 |
3 files changed, 66 insertions, 26 deletions
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 662b5a2e2e2..e60d0533c9f 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -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(); } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 4cdf821c925..b3cb5ace45b 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -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, + }) + } } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 58fe1e8e1c2..defbb44448a 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -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; } @@ -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); } @@ -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)) @@ -327,27 +332,41 @@ 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") { @@ -355,9 +374,16 @@ fn link_binary_output(sess: &Session, 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, @@ -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, |
