From 02959d051e2197fa7df73316125707d500a9d89d Mon Sep 17 00:00:00 2001 From: John Parent Date: Wed, 29 Apr 2026 18:29:41 -0400 Subject: [PATCH 1/3] ld.cxx: use temp dir for RC file creation Signed-off-by: John Parent --- src/ld.cxx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ld.cxx b/src/ld.cxx index 13856c7..ca4a7f9 100644 --- a/src/ld.cxx +++ b/src/ld.cxx @@ -5,6 +5,7 @@ */ #include "ld.h" #include +#include #include #include #include @@ -167,15 +168,26 @@ std::string LdInvocation::createRC(LinkerInvocation& link_run) { "BEGIN\n"; const std::string template_end = "END\n"; const std::string pe_name = stripLastExt(basename(pe_stage_name)); - const std::string rc_file_name = "spack-" + pe_name + ".rc"; + const std::string base_rc_file_name = "spack-" + pe_name + ".rc"; + + std::array temp_dir_buffer; + if (!GetTempPath2A(MAX_PATH, temp_dir_buffer.data())) { + throw std::system_error(static_cast(::GetLastError()), + std::system_category(), "Failed to get TEMP PATH"); + } + + std::string rc_tmp_dir = std::string(temp_dir_buffer.data()); // This res file name needs to mirror the PE name _exactly_ // Otherwise the RC file will override the default // or user set name, violating user expectation - std::string res_file_name = pe_name + ".res"; + std::string base_res_file_name = pe_name + ".res"; if (!link_run.get_rc_files().empty()) { - res_file_name = "spack-" + res_file_name; + base_res_file_name = "spack-" + base_res_file_name; } + const std::string res_file_name = join({rc_tmp_dir, base_rc_file_name}, "\\"); + const std::string rc_file_name = join({rc_tmp_dir, base_res_file_name}, "\\"); + ExecuteCommand rc_executor("rc", {"/fo" + res_file_name + " " + rc_file_name}); std::ofstream rc_out(rc_file_name); From d036f4f598723b91df19c09084837c39d79c9845 Mon Sep 17 00:00:00 2001 From: John Parent Date: Wed, 29 Apr 2026 18:43:55 -0400 Subject: [PATCH 2/3] cleanup files and ensure unique tmp dir Signed-off-by: John Parent --- src/ld.cxx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ld.cxx b/src/ld.cxx index ca4a7f9..f6908c8 100644 --- a/src/ld.cxx +++ b/src/ld.cxx @@ -52,6 +52,11 @@ DWORD LdInvocation::InvokeToolchain() { return ret_code; } + if(!DeleteFile2A(rc_file.c_str(), FILE_FLAG_DISALLOW_PATH_REDIRECTS)) { + throw std::system_error(static_cast(::GetLastError()), + std::system_category(), "Failed to remove intermediate rc file"); + } + // We're creating a PE, we need to create an appropriate import lib std::string const imp_lib_name = link_run.get_implib_name(); @@ -175,8 +180,7 @@ std::string LdInvocation::createRC(LinkerInvocation& link_run) { throw std::system_error(static_cast(::GetLastError()), std::system_category(), "Failed to get TEMP PATH"); } - - std::string rc_tmp_dir = std::string(temp_dir_buffer.data()); + std::string rc_tmp_dir = join({std::string(temp_dir_buffer.data()), std::to_string(_getpid()), "spack"}, "\\"); // This res file name needs to mirror the PE name _exactly_ // Otherwise the RC file will override the default // or user set name, violating user expectation @@ -214,5 +218,9 @@ std::string LdInvocation::createRC(LinkerInvocation& link_run) { if (err_code != 0) { throw RCCompilerFailure("Could not compile RC file"); } + if(!DeleteFile2A(rc_file_name.c_str(), FILE_FLAG_DISALLOW_PATH_REDIRECTS)) { + throw std::system_error(static_cast(::GetLastError()), + std::system_category(), "Failed to remove intermediate rc file"); + } return res_file_name; } From da2922bcf19768077b418fc0f86b9a85c61d1123 Mon Sep 17 00:00:00 2001 From: John Parent Date: Wed, 29 Apr 2026 18:51:07 -0400 Subject: [PATCH 3/3] Create temp dir Signed-off-by: John Parent --- src/ld.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ld.cxx b/src/ld.cxx index f6908c8..cb6d124 100644 --- a/src/ld.cxx +++ b/src/ld.cxx @@ -180,7 +180,14 @@ std::string LdInvocation::createRC(LinkerInvocation& link_run) { throw std::system_error(static_cast(::GetLastError()), std::system_category(), "Failed to get TEMP PATH"); } - std::string rc_tmp_dir = join({std::string(temp_dir_buffer.data()), std::to_string(_getpid()), "spack"}, "\\"); + std::string rc_tmp_dir = join({std::string(temp_dir_buffer.data()), std::to_string(_getpid())}, ""); + if(!CreateDirectoryA(rc_tmp_dir.c_str(), NULL)){ + DWORD err = ::GetLastError(); + if (err != ERROR_ALREADY_EXISTS) { + throw std::system_error(static_cast(err), + std::system_category(), "Failed to make directory"); + } + } // This res file name needs to mirror the PE name _exactly_ // Otherwise the RC file will override the default // or user set name, violating user expectation