mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Support --emit=foo,metadata
This commit is contained in:
parent
9c89166611
commit
b059a80d4c
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 link_binary_output(sess: &Session,
|
||||
trans: &CrateTranslation,
|
||||
crate_type: config::CrateType,
|
||||
outputs: &OutputFilenames,
|
||||
crate_name: &str) -> PathBuf {
|
||||
let objects = object_filenames(trans, outputs);
|
||||
let default_filename = filename_for_input(sess, crate_type, crate_name,
|
||||
outputs);
|
||||
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);
|
||||
|
||||
// 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()));
|
||||
}
|
||||
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) -> Vec<PathBuf> {
|
||||
let objects = object_filenames(trans, outputs);
|
||||
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user