Skip to content

Commit

Permalink
Auto merge of rust-lang#83846 - torhovland:issue-10971, r=davidtwco
Browse files Browse the repository at this point in the history
Added the --temps-dir option

Fixes rust-lang#10971.

The new `--temps-dir` option puts intermediate files in a user-specified directory. This provides a fix for the issue where parallel invocations of rustc would overwrite each other's intermediate files.

No files are kept in the intermediate directory unless `-C save-temps=yes`.

If additional files are specifically requested using `--emit asm,llvm-bc,llvm-ir,obj,metadata,link,dep-info,mir`, these will be put in the output directory rather than the intermediate directory.

This is a backward-compatible change, i.e. if `--temps-dir` is not specified, the behavior is the same as before.
  • Loading branch information
bors committed Nov 11, 2021
2 parents 8e02931 + 1793a7a commit 9dbbbb1
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 5 deletions.
5 changes: 4 additions & 1 deletion compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ fn run_compiler(
None,
compiler.output_dir(),
compiler.output_file(),
compiler.temps_dir(),
);

if should_stop == Compilation::Stop {
Expand Down Expand Up @@ -295,6 +296,7 @@ fn run_compiler(
Some(compiler.input()),
compiler.output_dir(),
compiler.output_file(),
compiler.temps_dir(),
)
.and_then(|| {
RustcDefaultCalls::list_metadata(
Expand Down Expand Up @@ -647,6 +649,7 @@ impl RustcDefaultCalls {
input: Option<&Input>,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>,
temps_dir: &Option<PathBuf>,
) -> Compilation {
use rustc_session::config::PrintRequest::*;
// PrintRequest::NativeStaticLibs is special - printed during linking
Expand Down Expand Up @@ -685,7 +688,7 @@ impl RustcDefaultCalls {
});
let attrs = attrs.as_ref().unwrap();
let t_outputs = rustc_interface::util::build_output_filenames(
input, odir, ofile, attrs, sess,
input, odir, ofile, temps_dir, attrs, sess,
);
let id = rustc_session::output::find_crate_name(sess, attrs, input);
if *req == PrintRequest::CrateName {
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub struct Compiler {
pub(crate) input_path: Option<PathBuf>,
pub(crate) output_dir: Option<PathBuf>,
pub(crate) output_file: Option<PathBuf>,
pub(crate) temps_dir: Option<PathBuf>,
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
pub(crate) override_queries:
Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>,
Expand All @@ -57,6 +58,9 @@ impl Compiler {
pub fn output_file(&self) -> &Option<PathBuf> {
&self.output_file
}
pub fn temps_dir(&self) -> &Option<PathBuf> {
&self.temps_dir
}
pub fn register_lints(&self) -> &Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>> {
&self.register_lints
}
Expand All @@ -65,7 +69,14 @@ impl Compiler {
sess: &Session,
attrs: &[ast::Attribute],
) -> OutputFilenames {
util::build_output_filenames(&self.input, &self.output_dir, &self.output_file, attrs, sess)
util::build_output_filenames(
&self.input,
&self.output_dir,
&self.output_file,
&self.temps_dir,
attrs,
sess,
)
}
}

Expand Down Expand Up @@ -186,13 +197,16 @@ pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R
);
}

let temps_dir = sess.opts.debugging_opts.temps_dir.as_ref().map(|o| PathBuf::from(&o));

let compiler = Compiler {
sess,
codegen_backend,
input: config.input,
input_path: config.input_path,
output_dir: config.output_dir,
output_file: config.output_file,
temps_dir,
register_lints: config.register_lints,
override_queries: config.override_queries,
};
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,7 @@ pub fn prepare_outputs(
&compiler.input,
&compiler.output_dir,
&compiler.output_file,
&compiler.temps_dir,
&krate.attrs,
sess,
);
Expand Down Expand Up @@ -722,6 +723,13 @@ pub fn prepare_outputs(
}
}

if let Some(ref dir) = compiler.temps_dir {
if fs::create_dir_all(dir).is_err() {
sess.err("failed to find or create the directory specified by `--temps-dir`");
return Err(ErrorReported);
}
}

write_out_deps(sess, boxed_resolver, &outputs, &output_paths);

let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ fn test_debugging_options_tracking_hash() {
untracked!(span_debug, true);
untracked!(span_free_formats, true);
untracked!(strip, Strip::Debuginfo);
untracked!(temps_dir, Some(String::from("abc")));
untracked!(terminal_width, Some(80));
untracked!(threads, 99);
untracked!(time, true);
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ pub fn build_output_filenames(
input: &Input,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>,
temps_dir: &Option<PathBuf>,
attrs: &[ast::Attribute],
sess: &Session,
) -> OutputFilenames {
Expand All @@ -626,6 +627,7 @@ pub fn build_output_filenames(
dirpath,
stem,
None,
temps_dir.clone(),
sess.opts.cg.extra_filename.clone(),
sess.opts.output_types.clone(),
)
Expand Down Expand Up @@ -654,6 +656,7 @@ pub fn build_output_filenames(
out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(),
out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(),
ofile,
temps_dir.clone(),
sess.opts.cg.extra_filename.clone(),
sess.opts.output_types.clone(),
)
Expand Down
22 changes: 19 additions & 3 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ pub struct OutputFilenames {
pub out_directory: PathBuf,
filestem: String,
pub single_output_file: Option<PathBuf>,
pub temps_directory: Option<PathBuf>,
pub outputs: OutputTypes,
}

Expand All @@ -592,12 +593,14 @@ impl OutputFilenames {
out_directory: PathBuf,
out_filestem: String,
single_output_file: Option<PathBuf>,
temps_directory: Option<PathBuf>,
extra: String,
outputs: OutputTypes,
) -> Self {
OutputFilenames {
out_directory,
single_output_file,
temps_directory,
outputs,
filestem: format!("{}{}", out_filestem, extra),
}
Expand All @@ -608,7 +611,14 @@ impl OutputFilenames {
.get(&flavor)
.and_then(|p| p.to_owned())
.or_else(|| self.single_output_file.clone())
.unwrap_or_else(|| self.temp_path(flavor, None))
.unwrap_or_else(|| self.output_path(flavor))
}

/// Gets the output path where a compilation artifact of the given type
/// should be placed on disk.
pub fn output_path(&self, flavor: OutputType) -> PathBuf {
let extension = flavor.extension();
self.with_directory_and_extension(&self.out_directory, &extension)
}

/// Gets the path where a compilation artifact of the given type for the
Expand Down Expand Up @@ -643,11 +653,17 @@ impl OutputFilenames {
extension.push_str(ext);
}

self.with_extension(&extension)
let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);

self.with_directory_and_extension(&temps_directory, &extension)
}

pub fn with_extension(&self, extension: &str) -> PathBuf {
let mut path = self.out_directory.join(&self.filestem);
self.with_directory_and_extension(&self.out_directory, extension)
}

fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf {
let mut path = directory.join(&self.filestem);
path.set_extension(extension);
path
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,8 @@ options! {
"which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
teach: bool = (false, parse_bool, [TRACKED],
"show extended diagnostic help (default: no)"),
temps_dir: Option<String> = (None, parse_opt_string, [UNTRACKED],
"the directory the intermediate files are written to"),
terminal_width: Option<usize> = (None, parse_opt_number, [UNTRACKED],
"set the current terminal width"),
tune_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
Expand Down
10 changes: 10 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/temps-dir.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# `temps-dir`

--------------------

The `-Ztemps-dir` compiler flag specifies the directory to write the
intermediate files in. If not set, the output directory is used. This option is
useful if you are running more than one instance of `rustc` (e.g. with different
`--crate-type` settings), and you need to make sure they are not overwriting
each other's intermediate files. No files are kept unless `-C save-temps=yes` is
also set.
10 changes: 10 additions & 0 deletions src/test/run-make/issue-10971-temps-dir/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-include ../../run-make-fulldeps/tools.mk

# Regression test for issue #10971
# Running two invocations in parallel would overwrite each other's temp files.

all:
touch $(TMPDIR)/lib.rs

$(RUSTC) --crate-type=lib -Z temps-dir=$(TMPDIR)/temp1 $(TMPDIR)/lib.rs & \
$(RUSTC) --crate-type=staticlib -Z temps-dir=$(TMPDIR)/temp2 $(TMPDIR)/lib.rs

0 comments on commit 9dbbbb1

Please sign in to comment.