Skip to content

Commit

Permalink
Rollup merge of rust-lang#107752 - riverar:rafael/gnu_dlltool_temp_pr…
Browse files Browse the repository at this point in the history
…efix, 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.)
  • Loading branch information
matthiaskrgr authored Feb 9, 2023
2 parents 3b9543c + c825e08 commit a621769
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions compiler/rustc_codegen_llvm/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
// able to control the *exact* spelling of each of the symbols that are being imported:
// hence we don't want `dlltool` adding leading underscores automatically.
let dlltool = find_binutils_dlltool(sess);
let temp_prefix = {
let mut path = PathBuf::from(&output_path);
path.pop();
path.push(lib_name);
path
};
let result = std::process::Command::new(dlltool)
.args([
"-d",
Expand All @@ -192,6 +198,8 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
"-l",
output_path.to_str().unwrap(),
"--no-leading-underscore",
"--temp-prefix",
temp_prefix.to_str().unwrap(),
])
.output();

Expand Down

0 comments on commit a621769

Please sign in to comment.