aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-rc
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2023-12-15 20:16:19 +0200
committerGitHub <noreply@github.com>2023-12-15 20:16:19 +0200
commit1709e8c656de69f6d823a3ae6773bf815e373909 (patch)
tree97133127831863df1ba7118d2275f37766cf39c7 /llvm/tools/llvm-rc
parent10b78cc8cea65e7e77d227af4027963f39402724 (diff)
downloadllvm-1709e8c656de69f6d823a3ae6773bf815e373909.zip
llvm-1709e8c656de69f6d823a3ae6773bf815e373909.tar.gz
llvm-1709e8c656de69f6d823a3ae6773bf815e373909.tar.bz2
[llvm-windres] Resolve the --preprocessor executable in $PATH (#75390)
The llvm::sys::ExecuteAndWait function doesn't resolve the file to be executed from $PATH - i.e. it is similar to execv(), not execvp(). Due to this, specifying a --preprocessor argument to llvm-windres only worked if it specified an absolute path to the preprocessor executable. This was observed as one of the issues in https://github.com/msys2/MINGW-packages/pull/19157. Before d2fa6b694c2052cef1ddd507f6569bc84e3bbe35, this usage of --preprocessor seemed to work, because the first argument of Args[] was ignored and llvm-windres just executed the autodetected clang executable regardless. Also improve the error messages printed if preprocessing failed. (If the preprocessor executable was started but itself returned an error, we don't get any error string.)
Diffstat (limited to 'llvm/tools/llvm-rc')
-rw-r--r--llvm/tools/llvm-rc/llvm-rc.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp
index 4375697..27fb030 100644
--- a/llvm/tools/llvm-rc/llvm-rc.cpp
+++ b/llvm/tools/llvm-rc/llvm-rc.cpp
@@ -248,10 +248,17 @@ void preprocess(StringRef Src, StringRef Dst, const RcOptions &Opts,
SmallVector<StringRef, 8> Args = {
Clang, "--driver-mode=gcc", "-target", Opts.Triple, "-E",
"-xc", "-DRC_INVOKED"};
+ std::string PreprocessorExecutable;
if (!Opts.PreprocessCmd.empty()) {
Args.clear();
for (const auto &S : Opts.PreprocessCmd)
Args.push_back(S);
+ if (!sys::fs::can_execute(Args[0])) {
+ if (auto P = sys::findProgramByName(Args[0])) {
+ PreprocessorExecutable = *P;
+ Args[0] = PreprocessorExecutable;
+ }
+ }
}
for (const auto &S : Opts.PreprocessArgs)
Args.push_back(S);
@@ -269,9 +276,15 @@ void preprocess(StringRef Src, StringRef Dst, const RcOptions &Opts,
}
// The llvm Support classes don't handle reading from stdout of a child
// process; otherwise we could avoid using a temp file.
- int Res = sys::ExecuteAndWait(Args[0], Args);
+ std::string ErrMsg;
+ int Res =
+ sys::ExecuteAndWait(Args[0], Args, /*Env=*/std::nullopt, /*Redirects=*/{},
+ /*SecondsToWait=*/0, /*MemoryLimit=*/0, &ErrMsg);
if (Res) {
- fatalError("llvm-rc: Preprocessing failed.");
+ if (!ErrMsg.empty())
+ fatalError("llvm-rc: Preprocessing failed: " + ErrMsg);
+ else
+ fatalError("llvm-rc: Preprocessing failed.");
}
}