summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/Job.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-03-17 16:24:34 +0000
committerZachary Turner <zturner@google.com>2017-03-17 16:24:34 +0000
commita0f96be9b14bc6c1cc8226658a6bedf4b4fc3547 (patch)
tree0e35c1b4cb59ee8004e1ac0372476b4d9a129ace /clang/lib/Driver/Job.cpp
parent4734c6f80814547364343dc72f07a8e627d5b0ed (diff)
downloadbcm5719-llvm-a0f96be9b14bc6c1cc8226658a6bedf4b4fc3547.tar.gz
bcm5719-llvm-a0f96be9b14bc6c1cc8226658a6bedf4b4fc3547.zip
[clang-cl] Fix cross-compilation with MSVC 2017.
clang-cl works best when the user runs vcvarsall to set up an environment before running, but even this is not enough on VC 2017 when cross compiling (e.g. using an x64 toolchain to target x86, or vice versa). The reason is that although clang-cl itself will have a valid environment, it will shell out to other tools (such as link.exe) which may not. Generally we solve this through adding the appropriate linker flags, but this is not enough in VC 2017. The cross-linker and the regular linker both link against some common DLLs, but these DLLs live in the binary directory of the native linker. When setting up a cross-compilation environment through vcvarsall, it will add *both* directories to %PATH%, so that when cl shells out to any of the associated tools, those tools will be able to find all of the dependencies that it links against. If you don't do this, link.exe will fail to run because the loader won't be able to find all of the required DLLs that it links against. To solve this we teach the driver how to spawn a process with an explicitly specified environment. Then we modify the PATH before shelling out to subtools and run with the modified PATH. Patch by Hamza Sood Differential Revision: https://reviews.llvm.org/D30991 llvm-svn: 298098
Diffstat (limited to 'clang/lib/Driver/Job.cpp')
-rw-r--r--clang/lib/Driver/Job.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp
index 9fd8808af30..7a4d055159e 100644
--- a/clang/lib/Driver/Job.cpp
+++ b/clang/lib/Driver/Job.cpp
@@ -301,19 +301,33 @@ void Command::setResponseFile(const char *FileName) {
ResponseFileFlag += FileName;
}
+void Command::setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) {
+ Environment.reserve(NewEnvironment.size() + 1);
+ Environment.assign(NewEnvironment.begin(), NewEnvironment.end());
+ Environment.push_back(nullptr);
+}
+
int Command::Execute(const StringRef **Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const {
SmallVector<const char*, 128> Argv;
+ const char **Envp;
+ if (Environment.empty()) {
+ Envp = nullptr;
+ } else {
+ assert(Environment.back() == nullptr &&
+ "Environment vector should be null-terminated by now");
+ Envp = const_cast<const char **>(Environment.data());
+ }
+
if (ResponseFile == nullptr) {
Argv.push_back(Executable);
Argv.append(Arguments.begin(), Arguments.end());
Argv.push_back(nullptr);
- return llvm::sys::ExecuteAndWait(Executable, Argv.data(), /*env*/ nullptr,
- Redirects, /*secondsToWait*/ 0,
- /*memoryLimit*/ 0, ErrMsg,
- ExecutionFailed);
+ return llvm::sys::ExecuteAndWait(
+ Executable, Argv.data(), Envp, Redirects, /*secondsToWait*/ 0,
+ /*memoryLimit*/ 0, ErrMsg, ExecutionFailed);
}
// We need to put arguments in a response file (command is too large)
@@ -337,8 +351,8 @@ int Command::Execute(const StringRef **Redirects, std::string *ErrMsg,
return -1;
}
- return llvm::sys::ExecuteAndWait(Executable, Argv.data(), /*env*/ nullptr,
- Redirects, /*secondsToWait*/ 0,
+ return llvm::sys::ExecuteAndWait(Executable, Argv.data(), Envp, Redirects,
+ /*secondsToWait*/ 0,
/*memoryLimit*/ 0, ErrMsg, ExecutionFailed);
}
OpenPOWER on IntegriCloud