diff --git a/src/ld.cxx b/src/ld.cxx index 13856c7..cb6d124 100644 --- a/src/ld.cxx +++ b/src/ld.cxx @@ -5,6 +5,7 @@ */ #include "ld.h" #include +#include #include #include #include @@ -51,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(); @@ -167,15 +173,32 @@ 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 = 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 - 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); @@ -202,5 +225,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; }