Skip to content

Commit 6eb5ad0

Browse files
authored
ld.cxx: fix variable reference; clean up temp files(#34)
* ld.cxx: res and rc variables were accidentally swapped. Unswap them * use raii to cleanup the res file Signed-off-by: John Parent <john.parent@kitware.com>
1 parent e73f83c commit 6eb5ad0

2 files changed

Lines changed: 49 additions & 16 deletions

File tree

src/ld.cxx

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,30 @@
44
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
55
*/
66
#include "ld.h"
7+
#include <errhandlingapi.h>
8+
#include <fileapi.h>
79
#include <minwindef.h>
10+
#include <process.h>
11+
#include <winbase.h>
12+
#include <winerror.h>
813
#include <array>
914
#include <cstdio>
1015
#include <cstdlib>
1116
#include <cstring>
1217
#include <fstream>
1318
#include <iostream>
19+
#include <memory>
20+
#include <system_error>
21+
#include <string>
22+
#include <utility>
1423
#include "coff_parser.h"
1524
#include "coff_reader_writer.h"
1625
#include "linker_invocation.h"
1726
#include "spack_env.h"
1827
#include "toolchain.h"
1928
#include "utils.h"
2029

30+
2131
void LdInvocation::LoadToolchainDependentSpackVars(SpackEnvState& spackenv) {
2232
this->command = spackenv.SpackLD;
2333
}
@@ -29,7 +39,7 @@ DWORD LdInvocation::InvokeToolchain() {
2939
// understand what we'll be doing
3040
LinkerInvocation link_run(this->inputs);
3141
link_run.Parse();
32-
std::string rc_file;
42+
std::unique_ptr<RCFileManager> rc_file;
3343
try {
3444
// Run resource compiler to create
3545
// Resource for id'ing binary when relocating its import library
@@ -44,19 +54,13 @@ DWORD LdInvocation::InvokeToolchain() {
4454
// file the linker sees (or is referenced in the case of an rsp)
4555
// otherwise this resource file will dictate the binairies
4656
// name, which will break client expectations
47-
this->inputs.push_back(rc_file);
57+
this->inputs.push_back(rc_file->getRC());
4858
// Run base linker invocation to produce initial
4959
// dll and import library
5060
DWORD const ret_code = ToolChainInvocation::InvokeToolchain();
5161
if (ret_code != 0) {
5262
return ret_code;
5363
}
54-
55-
if(!DeleteFile2A(rc_file.c_str(), FILE_FLAG_DISALLOW_PATH_REDIRECTS)) {
56-
throw std::system_error(static_cast<int>(::GetLastError()),
57-
std::system_category(), "Failed to remove intermediate rc file");
58-
}
59-
6064
// We're creating a PE, we need to create an appropriate import lib
6165
std::string const imp_lib_name = link_run.get_implib_name();
6266

@@ -166,7 +170,8 @@ DWORD LdInvocation::InvokeToolchain() {
166170
return ret_code;
167171
}
168172

169-
std::string LdInvocation::createRC(LinkerInvocation& link_run) {
173+
174+
std::unique_ptr<RCFileManager> LdInvocation::createRC(LinkerInvocation& link_run) {
170175
const std::string pe_stage_name = link_run.get_out();
171176
const std::string template_base =
172177
"spack SPACKRESOURCE\n"
@@ -180,9 +185,9 @@ std::string LdInvocation::createRC(LinkerInvocation& link_run) {
180185
throw std::system_error(static_cast<int>(::GetLastError()),
181186
std::system_category(), "Failed to get TEMP PATH");
182187
}
183-
std::string rc_tmp_dir = join({std::string(temp_dir_buffer.data()), std::to_string(_getpid())}, "");
184-
if(!CreateDirectoryA(rc_tmp_dir.c_str(), NULL)){
185-
DWORD err = ::GetLastError();
188+
const std::string rc_tmp_dir = join({std::string(temp_dir_buffer.data()), std::to_string(_getpid())}, "");
189+
if(!CreateDirectoryA(rc_tmp_dir.c_str(), nullptr)){
190+
const DWORD err = ::GetLastError();
186191
if (err != ERROR_ALREADY_EXISTS) {
187192
throw std::system_error(static_cast<int>(err),
188193
std::system_category(), "Failed to make directory");
@@ -196,8 +201,8 @@ std::string LdInvocation::createRC(LinkerInvocation& link_run) {
196201
base_res_file_name = "spack-" + base_res_file_name;
197202
}
198203

199-
const std::string res_file_name = join({rc_tmp_dir, base_rc_file_name}, "\\");
200-
const std::string rc_file_name = join({rc_tmp_dir, base_res_file_name}, "\\");
204+
const std::string res_file_name = join({rc_tmp_dir, base_res_file_name}, "\\");
205+
const std::string rc_file_name = join({rc_tmp_dir, base_rc_file_name}, "\\");
201206

202207
ExecuteCommand rc_executor("rc",
203208
{"/fo" + res_file_name + " " + rc_file_name});
@@ -229,5 +234,22 @@ std::string LdInvocation::createRC(LinkerInvocation& link_run) {
229234
throw std::system_error(static_cast<int>(::GetLastError()),
230235
std::system_category(), "Failed to remove intermediate rc file");
231236
}
232-
return res_file_name;
237+
std::unique_ptr<RCFileManager> res_file_ptr = std::make_unique<RCFileManager>(res_file_name);
238+
return res_file_ptr;
239+
}
240+
241+
242+
RCFileManager::RCFileManager(std::string file) {
243+
this->rc_file_ = std::move(file);
244+
}
245+
246+
RCFileManager::~RCFileManager(){
247+
if(!DeleteFile2A(this->rc_file_.c_str(), FILE_FLAG_DISALLOW_PATH_REDIRECTS)) {
248+
std::cerr << std::system_error(static_cast<int>(::GetLastError()),
249+
std::system_category(), "Failed to remove intermediate rc file").what() << "\n";
250+
}
251+
}
252+
253+
const std::string& RCFileManager::getRC() {
254+
return this->rc_file_;
233255
}

src/ld.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@
99

1010
#include "toolchain.h"
1111

12+
13+
class RCFileManager {
14+
public:
15+
explicit RCFileManager(std::string file);
16+
~RCFileManager();
17+
const std::string& getRC();
18+
private:
19+
std::string rc_file_;
20+
};
21+
22+
1223
/**
1324
* @brief ClInvocation exposes an interface driving invocations of
1425
* link.exe and defines the parameters of the call to said executable
@@ -22,5 +33,5 @@ class LdInvocation : public ToolChainInvocation {
2233
void LoadToolchainDependentSpackVars(SpackEnvState& spackenv);
2334
std::string lang = "link";
2435
ExecuteCommand rpath_executor;
25-
static std::string createRC(LinkerInvocation& link_run);
36+
static std::unique_ptr<RCFileManager> createRC(LinkerInvocation& link_run);
2637
};

0 commit comments

Comments
 (0)