[clang] d283a55 - [clang-nvlink-wrapper] Fix response file handling for the nvlink wrapper (#220249)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 13 05:41:19 PDT 2026
Author: Joseph Huber
Date: 2026-09-13T07:41:14-05:00
New Revision: d283a555109576cd92b35a88b4d110166043fb77
URL: https://github.com/llvm/llvm-project/commit/d283a555109576cd92b35a88b4d110166043fb77
DIFF: https://github.com/llvm/llvm-project/commit/d283a555109576cd92b35a88b4d110166043fb77.diff
LOG: [clang-nvlink-wrapper] Fix response file handling for the nvlink wrapper (#220249)
Summary:
Response files were not handled correctly because the copied support
used the `nvlink` argument which is not supported by the argument
parser. Pass to the nvlink wrapper using the canonical format and then
reconstruct it when we execute the sub jobs
Fixes: https://github.com/llvm/llvm-project/issues/219914
Added:
Modified:
clang/lib/Driver/ToolChains/Cuda.cpp
clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c
clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 08a06c175d8ec..54bc9b3f65e27 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -519,7 +519,7 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(std::make_unique<Command>(
JA, *this,
ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8,
- "--options-file"},
+ "--options-file="},
Exec, CmdArgs, Inputs, Output));
}
@@ -586,7 +586,7 @@ void NVPTX::FatBinary::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(std::make_unique<Command>(
JA, *this,
ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8,
- "--options-file"},
+ "--options-file="},
Exec, CmdArgs, Inputs, Output));
}
@@ -684,9 +684,7 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
C.addCommand(std::make_unique<Command>(
- JA, *this,
- ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8,
- "--options-file"},
+ JA, *this, ResponseFileSupport::AtFileUTF8(),
Args.MakeArgString(getToolChain().GetProgramPath("clang-nvlink-wrapper")),
CmdArgs, Inputs, Output));
}
diff --git a/clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c b/clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c
index e5de6260ae61c..0aa6e8fc72349 100644
--- a/clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c
+++ b/clang/test/OffloadTools/clang-nvlink-wrapper/nvlink-wrapper.c
@@ -46,6 +46,17 @@ int baz() { return y + x; }
// RUN: | FileCheck %s --check-prefix=ARGS
// ARGS: nvlink{{.*}} -arch sm_52 -foo -o a.out [[INPUT:.+]].cubin
+//
+// Check that GNU response files are expanded to nvlink.
+//
+// RUN: echo '-arch sm_52 %t-u.o -o a.out' > %t.rsp
+// RUN: clang-nvlink-wrapper --dry-run --assume-device-object @%t.rsp 2>&1 \
+// RUN: | FileCheck %s --check-prefix=RSP
+// RUN: echo '"-arch" "sm_52" "%t-u.o" "-o" "a.out"' > %t.quoted.rsp
+// RUN: clang-nvlink-wrapper --dry-run --assume-device-object @%t.quoted.rsp 2>&1 \
+// RUN: | FileCheck %s --check-prefix=RSP
+// RSP: nvlink{{.*}} -arch sm_52 -o a.out {{.*}}.cubin
+
//
// Check the symbol resolution for static archives. We expect to only link
// `libx.a` and `liby.a` because extern weak symbols do not extract and `libz.a`
diff --git a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
index bc1f510963321..4e06d1c149bb6 100644
--- a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
+++ b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
@@ -16,6 +16,8 @@
#include "clang/Basic/Version.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Bitcode/BitcodeWriter.h"
@@ -255,6 +257,44 @@ void printCommands(ArrayRef<StringRef> CmdArgs) {
errs() << join(std::next(CmdArgs.begin()), CmdArgs.end(), " ") << "\n";
}
+Error executeProgram(StringRef Executable, ArrayRef<StringRef> Args,
+ const ArgList &WrapperArgs) {
+ if (WrapperArgs.hasArg(OPT_dry_run) || WrapperArgs.hasArg(OPT_verbose))
+ printCommands(Args);
+ if (WrapperArgs.hasArg(OPT_dry_run))
+ return Error::success();
+
+ if (sys::commandLineFitsWithinSystemLimits(Executable, Args)) {
+ if (sys::ExecuteAndWait(Executable, Args))
+ return createStringError("'%s' failed",
+ sys::path::filename(Executable).str().c_str());
+ return Error::success();
+ }
+
+ auto TempFileOrErr = createTempFile(WrapperArgs, "response", "txt");
+ if (!TempFileOrErr)
+ return TempFileOrErr.takeError();
+
+ SmallString<256> Contents;
+ raw_svector_ostream OS(Contents);
+ for (StringRef Arg : llvm::drop_begin(Args)) {
+ sys::printArg(OS, Arg, /*Quote=*/true);
+ OS << " ";
+ }
+
+ if (std::error_code EC = sys::writeFileWithEncoding(*TempFileOrErr, Contents))
+ return createStringError("failed to write response file: %s",
+ EC.message().c_str());
+
+ // How nvlink spells its response file support.
+ std::string ResponseFile = ("--options-file=" + *TempFileOrErr).str();
+ SmallVector<StringRef, 2> NewArgs = {Args.front(), ResponseFile};
+ if (sys::ExecuteAndWait(Executable, NewArgs))
+ return createStringError("'%s' failed",
+ sys::path::filename(Executable).str().c_str());
+ return Error::success();
+}
+
/// A minimum symbol interface that provides the necessary information to
/// extract archive members and resolve LTO symbols.
struct Symbol {
@@ -336,13 +376,8 @@ Expected<StringRef> runPTXAs(StringRef File, const ArgList &Args) {
AssemblerArgs.push_back(A->getValue());
AssemblerArgs.append({"-o", *TempFileOrErr});
- if (Args.hasArg(OPT_dry_run) || Args.hasArg(OPT_verbose))
- printCommands(AssemblerArgs);
- if (Args.hasArg(OPT_dry_run))
- return Args.MakeArgString(*TempFileOrErr);
- if (sys::ExecuteAndWait(*PTXAsPath, AssemblerArgs))
- return createStringError("'" + sys::path::filename(*PTXAsPath) + "'" +
- " failed");
+ if (Error Err = executeProgram(*PTXAsPath, AssemblerArgs, Args))
+ return Err;
return Args.MakeArgString(*TempFileOrErr);
}
@@ -753,14 +788,7 @@ Error runNVLink(ArrayRef<StringRef> Files, const ArgList &Args) {
for (StringRef Arg : NewLinkerArgs)
LinkerArgs.push_back(Arg);
- if (Args.hasArg(OPT_dry_run) || Args.hasArg(OPT_verbose))
- printCommands(LinkerArgs);
- if (Args.hasArg(OPT_dry_run))
- return Error::success();
- if (sys::ExecuteAndWait(*NVLinkPath, LinkerArgs))
- return createStringError("'" + sys::path::filename(*NVLinkPath) + "'" +
- " failed");
- return Error::success();
+ return executeProgram(*NVLinkPath, LinkerArgs, Args);
}
} // namespace
More information about the cfe-commits
mailing list