rustc: Mix extra-filename in temp outputs

When invoking the compiler in parallel, the intermediate output of the object
files and bytecode can stomp over one another if two crates with the same name
are being compiled.

The output file is already being disambiguated with `-C extra-filename`, so this
commit alters the naming of the temporary files to also mix in the extra
filename to ensure that file names don't clash.
This commit is contained in:
Alex Crichton 2014-07-15 09:13:58 -07:00
parent 50868db351
commit 82fb85a152
8 changed files with 41 additions and 16 deletions

View file

@ -571,8 +571,9 @@ pub fn find_crate_name(sess: Option<&Session>,
};
// Look in attributes 100% of the time to make sure the attribute is marked
// as used. After doing this, however, favor crate names from the command
// line.
// as used. After doing this, however, we still prioritize a crate name from
// the command line over one found in the #[crate_name] attribute. If we
// find both we ensure that they're the same later on as well.
let attr_crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
.and_then(|at| at.value_str().map(|s| (at, s)));
@ -1558,7 +1559,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
add_dynamic_crate(cmd, sess, src.dylib.unwrap())
}
cstore::RequireStatic => {
add_static_crate(cmd, sess, tmpdir, cnum, src.rlib.unwrap())
add_static_crate(cmd, sess, tmpdir, src.rlib.unwrap())
}
}
@ -1575,7 +1576,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
// Adds the static "rlib" versions of all crates to the command line.
fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
cnum: ast::CrateNum, cratepath: Path) {
cratepath: Path) {
// When performing LTO on an executable output, all of the
// bytecode from the upstream libraries has already been
// included in our object file output. We need to modify all of
@ -1591,7 +1592,8 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
// If we're not doing LTO, then our job is simply to just link
// against the archive.
if sess.lto() {
let name = sess.cstore.get_crate_data(cnum).name.clone();
let name = cratepath.filename_str().unwrap();
let name = name.slice(3, name.len() - 5); // chop off lib/.rlib
time(sess.time_passes(),
format!("altering {}.rlib", name).as_slice(),
(), |()| {

View file

@ -54,17 +54,19 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
};
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
debug!("reading {}", name);
let file = path.filename_str().unwrap();
let file = file.slice(3, file.len() - 5); // chop off lib/.rlib
debug!("reading {}", file);
let bc = time(sess.time_passes(),
format!("read {}.bytecode.deflate", name).as_slice(),
(),
|_| {
archive.read(format!("{}.bytecode.deflate",
name).as_slice())
file).as_slice())
});
let bc = bc.expect("missing compressed bytecode in archive!");
let bc = time(sess.time_passes(),
format!("inflate {}.bc", name).as_slice(),
format!("inflate {}.bc", file).as_slice(),
(),
|_| {
match flate::inflate_bytes(bc) {

View file

@ -936,6 +936,7 @@ pub struct OutputFilenames {
pub out_directory: Path,
pub out_filestem: String,
pub single_output_file: Option<Path>,
extra: String,
}
impl OutputFilenames {
@ -948,7 +949,7 @@ impl OutputFilenames {
}
pub fn temp_path(&self, flavor: link::OutputType) -> Path {
let base = self.out_directory.join(self.out_filestem.as_slice());
let base = self.out_directory.join(self.filestem());
match flavor {
link::OutputTypeBitcode => base.with_extension("bc"),
link::OutputTypeAssembly => base.with_extension("s"),
@ -959,8 +960,11 @@ impl OutputFilenames {
}
pub fn with_extension(&self, extension: &str) -> Path {
let stem = self.out_filestem.as_slice();
self.out_directory.join(stem).with_extension(extension)
self.out_directory.join(self.filestem()).with_extension(extension)
}
fn filestem(&self) -> String {
format!("{}{}", self.out_filestem, self.extra)
}
}
@ -1000,6 +1004,7 @@ pub fn build_output_filenames(input: &Input,
out_directory: dirpath,
out_filestem: stem,
single_output_file: None,
extra: sess.opts.cg.extra_filename.clone(),
}
}
@ -1018,6 +1023,7 @@ pub fn build_output_filenames(input: &Input,
out_directory: out_file.dir_path(),
out_filestem: out_file.filestem_str().unwrap().to_string(),
single_output_file: ofile,
extra: sess.opts.cg.extra_filename.clone(),
}
}
}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-args: --crate-name foo
// compile-flags: --crate-name foo
#![crate_name = "bar"]
//~^ ERROR: --crate-name and #[crate_name] are required to match, but `foo` != `bar`

View file

@ -7,7 +7,5 @@ all:
rm $(TMPDIR)/$(call BIN,bar)
$(RUSTC) foo1.rs
rm $(TMPDIR)/$(call BIN,foo)
$(RUSTC) foo1.rs --crate-name bar
rm $(TMPDIR)/$(call BIN,bar)
$(RUSTC) foo1.rs --crate-name bar -o $(TMPDIR)/bar1
$(RUSTC) foo1.rs -o $(TMPDIR)/bar1
rm $(TMPDIR)/$(call BIN,bar1)

View file

@ -0,0 +1,6 @@
-include ../tools.mk
all:
$(RUSTC) -C extra-filename=bar foo.rs -C save-temps
rm $(TMPDIR)/foobar.o
rm $(TMPDIR)/$(call BIN,foobar)

View file

@ -0,0 +1,11 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {}

View file

@ -10,6 +10,6 @@
// compile-flags:--crate-name crate-name-attr-used -F unused-attribute
#![crate_name = "test"]
#![crate_name = "crate-name-attr-used"]
fn main() {}