Skip to content

Commit 5b50273

Browse files
Rollup merge of rust-lang#107752 - riverar:rafael/gnu_dlltool_temp_prefix, r=petrochenkov
Specify dlltool prefix when generating import libs Ref: rust-lang#106610 (comment) tl;dr: This PR adds an explicit dlltool temporary filename prefix. The prefix resolves a race condition by ensuring dlltool temporary files are siloed in an appropriate/unique Rust temporary directory. --- GNU dlltool, as part of its import library generation logic, uses a bunch of temporary files on disk. In the interest of deterministic build runs, dlltool supports deterministic temporary filenames. The temporary filename prefix is automatically generated internally or can be explicitly specified via a `--temp-prefix` argument. GNU dlltool **2.38** (that ships with `x86_64-12.2.0-release-posix-seh-rt_v10-rev0` [installed during CI](https://github.com/rust-lang/rust/blob/master/src/ci/scripts/install-mingw.sh)) generates a prefix based on the target library name ([source](https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=binutils/dlltool.c;h=d95bf3f5470b999fa3b30bc887791859f48d81d1;hb=20756b0fbe065a84710aa38f2457563b57546440#l3992)). The tool writes to files such as `target_dll_h.s` and `target_dll_s00203.o` in the current working directory. This presents a problem when multiple instances of rustc_codegen_llvm are running to generate an import library (as part of the raw_dylib feature) for the same target library (e.g. kernel32) ([source](https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/back/archive.rs#L185-L196)). That is, dlltool instances race and may overwrite or delete files belonging to each other. GNU dlltool **2.39**+ (not used in Rust CI) generates a prefix based on the output library path ([source](https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=binutils/dlltool.c;h=e2af20847009945b4c61a6fef08268fbb4429715;hb=b51c2fec1da205ea3e7354cbb3e253018d64873c#l3992)). The tool, when invoked as part of rustc_codegen_llvm, writes to files at paths such as `C_Users_Foo_AppData_Local_Temp_rustcOFqhXZ_target_lib_h.s`. (The output library path is normalized and non-alphanumeric characters are replaced with underscores.)
2 parents ec325bf + c825e08 commit 5b50273

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

compiler/rustc_codegen_llvm/src/back/archive.rs

+8
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
183183
// able to control the *exact* spelling of each of the symbols that are being imported:
184184
// hence we don't want `dlltool` adding leading underscores automatically.
185185
let dlltool = find_binutils_dlltool(sess);
186+
let temp_prefix = {
187+
let mut path = PathBuf::from(&output_path);
188+
path.pop();
189+
path.push(lib_name);
190+
path
191+
};
186192
let result = std::process::Command::new(dlltool)
187193
.args([
188194
"-d",
@@ -192,6 +198,8 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
192198
"-l",
193199
output_path.to_str().unwrap(),
194200
"--no-leading-underscore",
201+
"--temp-prefix",
202+
temp_prefix.to_str().unwrap(),
195203
])
196204
.output();
197205

0 commit comments

Comments
 (0)