diff options
| author | Michael Goulet <michael@errs.io> | 2025-04-06 23:50:16 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-04-07 20:48:40 +0000 |
| commit | 9c372d8940a8dad14d586f6bd4dd42541f25cd80 (patch) | |
| tree | f5f7f7735e27aa5e524b4f815fa63c5f836233bf /compiler/rustc_session | |
| parent | effef88ac70f2d12229b77b8e428037df8028b7e (diff) | |
| download | rust-9c372d8940a8dad14d586f6bd4dd42541f25cd80.tar.gz rust-9c372d8940a8dad14d586f6bd4dd42541f25cd80.zip | |
Prepend temp files with a string per invocation of rustc
Diffstat (limited to 'compiler/rustc_session')
| -rw-r--r-- | compiler/rustc_session/Cargo.toml | 1 | ||||
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_session/src/session.rs | 17 |
3 files changed, 50 insertions, 8 deletions
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index a087725d34d..63772a32222 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" # tidy-alphabetical-start bitflags = "2.4.1" getopts = "0.2" +rand = "0.9.0" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 946b1201e05..bdd54a15147 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1016,10 +1016,13 @@ impl OutFileName { outputs: &OutputFilenames, flavor: OutputType, codegen_unit_name: &str, + invocation_temp: Option<&str>, ) -> PathBuf { match *self { OutFileName::Real(ref path) => path.clone(), - OutFileName::Stdout => outputs.temp_path_for_cgu(flavor, codegen_unit_name), + OutFileName::Stdout => { + outputs.temp_path_for_cgu(flavor, codegen_unit_name, invocation_temp) + } } } @@ -1094,21 +1097,41 @@ impl OutputFilenames { /// Gets the path where a compilation artifact of the given type for the /// given codegen unit should be placed on disk. If codegen_unit_name is /// None, a path distinct from those of any codegen unit will be generated. - pub fn temp_path_for_cgu(&self, flavor: OutputType, codegen_unit_name: &str) -> PathBuf { + pub fn temp_path_for_cgu( + &self, + flavor: OutputType, + codegen_unit_name: &str, + invocation_temp: Option<&str>, + ) -> PathBuf { let extension = flavor.extension(); - self.temp_path_ext_for_cgu(extension, codegen_unit_name) + self.temp_path_ext_for_cgu(extension, codegen_unit_name, invocation_temp) } /// Like `temp_path`, but specifically for dwarf objects. - pub fn temp_path_dwo_for_cgu(&self, codegen_unit_name: &str) -> PathBuf { - self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name) + pub fn temp_path_dwo_for_cgu( + &self, + codegen_unit_name: &str, + invocation_temp: Option<&str>, + ) -> PathBuf { + self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name, invocation_temp) } /// Like `temp_path`, but also supports things where there is no corresponding /// OutputType, like noopt-bitcode or lto-bitcode. - pub fn temp_path_ext_for_cgu(&self, ext: &str, codegen_unit_name: &str) -> PathBuf { + pub fn temp_path_ext_for_cgu( + &self, + ext: &str, + codegen_unit_name: &str, + invocation_temp: Option<&str>, + ) -> PathBuf { let mut extension = codegen_unit_name.to_string(); + // Append `.{invocation_temp}` to ensure temporary files are unique. + if let Some(rng) = invocation_temp { + extension.push('.'); + extension.push_str(rng); + } + // FIXME: This is sketchy that we're not appending `.rcgu` when the ext is empty. // Append `.rcgu.{ext}`. if !ext.is_empty() { @@ -1144,9 +1167,10 @@ impl OutputFilenames { split_debuginfo_kind: SplitDebuginfo, split_dwarf_kind: SplitDwarfKind, cgu_name: &str, + invocation_temp: Option<&str>, ) -> Option<PathBuf> { - let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name); - let dwo_out = self.temp_path_dwo_for_cgu(cgu_name); + let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name, invocation_temp); + let dwo_out = self.temp_path_dwo_for_cgu(cgu_name, invocation_temp); match (split_debuginfo_kind, split_dwarf_kind) { (SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None, // Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index fb4a437a487..1359f7eb7bb 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -6,6 +6,8 @@ use std::sync::Arc; use std::sync::atomic::AtomicBool; use std::{env, fmt, io}; +use rand::{RngCore, rng}; +use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; @@ -203,6 +205,14 @@ pub struct Session { target_filesearch: FileSearch, host_filesearch: FileSearch, + + /// A random string generated per invocation of rustc. + /// + /// This is prepended to all temporary files so that they do not collide + /// during concurrent invocations of rustc, or past invocations that were + /// preserved with a flag like `-C save-temps`, since these files may be + /// hard linked. + pub invocation_temp: Option<String>, } #[derive(PartialEq, Eq, PartialOrd, Ord)] @@ -1117,6 +1127,12 @@ pub fn build_session( let target_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &target_tlib_path, &target); let host_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &host_tlib_path, &host); + + let invocation_temp = sopts + .incremental + .as_ref() + .map(|_| rng().next_u32().to_base_fixed_len(CASE_INSENSITIVE).to_string()); + let sess = Session { target, host, @@ -1140,6 +1156,7 @@ pub fn build_session( expanded_args, target_filesearch, host_filesearch, + invocation_temp, }; validate_commandline_args_with_session_available(&sess); |
