Skip to content

Commit 271ef40

Browse files
authored
[Driver][SYCL] Expand ability to pick up fat static archives after /link (#5768)
On Windows, users can use the /link [opts] to specify any options you want to pass directly to the link step. Typically these options are not processed by the driver as they should be linker specific. Modify the driver to do additional checks for libraries after the /link option to discover any fat static archives that need to be processed by the driver (i.e. unbundled, etc).
1 parent 45ab7c9 commit 271ef40

File tree

2 files changed

+54
-10
lines changed

2 files changed

+54
-10
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2992,9 +2992,10 @@ static SmallVector<const char *, 16>
29922992
getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) {
29932993
SmallVector<const char *, 16> LibArgs;
29942994
SmallVector<std::string, 8> LibPaths;
2995-
// Add search directories from LIBRARY_PATH env variable
2995+
bool IsMSVC = C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
2996+
// Add search directories from LIBRARY_PATH/LIB env variable
29962997
llvm::Optional<std::string> LibPath =
2997-
llvm::sys::Process::GetEnv("LIBRARY_PATH");
2998+
llvm::sys::Process::GetEnv(IsMSVC ? "LIB" : "LIBRARY_PATH");
29982999
if (LibPath) {
29993000
SmallVector<StringRef, 8> SplitPaths;
30003001
const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
@@ -3028,12 +3029,36 @@ getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) {
30283029
};
30293030
for (const auto *A : Args) {
30303031
std::string FileName = A->getAsString(Args);
3032+
auto addLibArg = [&](StringRef LibName) -> bool {
3033+
if (isStaticArchiveFile(LibName) ||
3034+
(IncludeObj && isObjectFile(LibName.str()))) {
3035+
LibArgs.push_back(Args.MakeArgString(LibName));
3036+
return true;
3037+
}
3038+
return false;
3039+
};
30313040
if (A->getOption().getKind() == Option::InputClass) {
3032-
StringRef Value(A->getValue());
3033-
if (isStaticArchiveFile(Value) ||
3034-
(IncludeObj && isObjectFile(Value.str()))) {
3035-
LibArgs.push_back(Args.MakeArgString(FileName));
3041+
if (addLibArg(FileName))
30363042
continue;
3043+
}
3044+
// Evaluate any libraries passed along after /link. These are typically
3045+
// ignored by the driver and sent directly to the linker. When performing
3046+
// offload, we should evaluate them at the driver level.
3047+
if (A->getOption().matches(options::OPT__SLASH_link)) {
3048+
for (const std::string &Value : A->getValues()) {
3049+
// Add any libpath values.
3050+
StringRef OptCheck(Value);
3051+
if (OptCheck.startswith_insensitive("-libpath:") ||
3052+
OptCheck.startswith_insensitive("/libpath:"))
3053+
LibPaths.emplace_back(Value.substr(std::string("-libpath:").size()));
3054+
if (addLibArg(Value))
3055+
continue;
3056+
for (auto LPath : LibPaths) {
3057+
SmallString<128> FullLib(LPath);
3058+
llvm::sys::path::append(FullLib, Value);
3059+
if (addLibArg(FullLib))
3060+
continue;
3061+
}
30373062
}
30383063
}
30393064
if (A->getOption().matches(options::OPT_Wl_COMMA) ||
@@ -3075,9 +3100,8 @@ getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) {
30753100
llvm::StringSaver S(A);
30763101
llvm::cl::ExpandResponseFiles(
30773102
S,
3078-
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
3079-
? llvm::cl::TokenizeWindowsCommandLine
3080-
: llvm::cl::TokenizeGNUCommandLine,
3103+
IsMSVC ? llvm::cl::TokenizeWindowsCommandLine
3104+
: llvm::cl::TokenizeGNUCommandLine,
30813105
ExpandArgs);
30823106
for (StringRef EA : ExpandArgs)
30833107
addKnownValues(EA);
@@ -8311,7 +8335,7 @@ bool clang::driver::isStaticArchiveFile(const StringRef &FileName) {
83118335
llvm::file_magic Magic;
83128336
llvm::identify_magic(FileName, Magic);
83138337
// Only .lib and archive files are to be considered.
8314-
return (Ext == "lib" || Magic == llvm::file_magic::archive);
8338+
return (Magic == llvm::file_magic::archive);
83158339
}
83168340

83178341
bool clang::driver::willEmitRemarks(const ArgList &Args) {

clang/test/Driver/sycl-offload-win.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,32 @@
1414
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
1515
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t-orig.lib %t-orig.obj -### 2>&1 \
1616
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
17+
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t-orig.obj -### /link %t-orig.lib 2>&1 \
18+
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
1719
// FOFFLOAD_STATIC_LIB: clang-offload-bundler{{(.exe)?}}{{.+}} "-type=o" "-targets=host-x86_64-pc-windows-msvc,sycl-spir64-unknown-unknown" "-inputs={{.*}}-orig.obj" "-outputs={{.+}}.{{(o|obj)}},{{.+}}.{{(o|obj)}}" "-unbundle"
1820
// FOFFLOAD_STATIC_LIB: clang-offload-bundler{{(.exe)?}}{{.+}} "-type=aoo" "-targets=sycl-spir64-{{.+}}" "-inputs={{.*}}-orig.lib" "-outputs=[[OUTLIB:.+\.txt]]" "-unbundle"
1921
// FOFFLOAD_STATIC_LIB: llvm-foreach{{.*}} "--out-ext=txt" "--in-file-list=[[OUTLIB]]" "--in-replace=[[OUTLIB]]" "--out-file-list=[[OUTLIST:.+\.txt]]" "--out-replace=[[OUTLIST]]" "--" {{.*}}spirv-to-ir-wrapper{{.*}} "[[OUTLIB]]" "-o" "[[OUTLIST]]"
2022
// FOFFLOAD_STATIC_LIB: llvm-link{{(.exe)?}}{{.*}} "@[[OUTLIST]]"
2123
// FOFFLOAD_STATIC_LIB: link{{(.exe)?}}{{.+}} "{{.*}}-orig.lib"
2224

25+
// RUN: mkdir -p %t_dir
26+
// RUN: llvm-ar cr %t_dir/%basename_t-orig2.lib %t-orig.obj
27+
// RUN: %clang --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t_dir/%basename_t-orig2.lib %t-orig.obj -### 2>&1 \
28+
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
29+
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t_dir/%basename_t-orig2.lib %t-orig.obj -### 2>&1 \
30+
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
31+
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t-orig.obj -### /link %t_dir/%basename_t-orig2.lib 2>&1 \
32+
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
33+
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t-orig.obj -### /link -libpath:%t_dir %basename_t-orig2.lib 2>&1 \
34+
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
35+
// RUN: env LIB=%t_dir %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t-orig.obj -### /link %basename_t-orig2.lib 2>&1 \
36+
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
37+
// FOFFLOAD_STATIC_LIB2: clang-offload-bundler{{(.exe)?}}{{.+}} "-type=o" "-targets=host-x86_64-pc-windows-msvc,sycl-spir64-unknown-unknown" "-inputs={{.*}}-orig.obj" "-outputs={{.+}}.{{(o|obj)}},{{.+}}.{{(o|obj)}}" "-unbundle"
38+
// FOFFLOAD_STATIC_LIB2: clang-offload-bundler{{(.exe)?}}{{.+}} "-type=aoo" "-targets=sycl-spir64-{{.+}}" "-inputs={{.*}}-orig2.lib" "-outputs=[[OUTLIB:.+\.txt]]" "-unbundle"
39+
// FOFFLOAD_STATIC_LIB2: llvm-foreach{{.*}} "--out-ext=txt" "--in-file-list=[[OUTLIB]]" "--in-replace=[[OUTLIB]]" "--out-file-list=[[OUTLIST:.+\.txt]]" "--out-replace=[[OUTLIST]]" "--" {{.*}}spirv-to-ir-wrapper{{.*}} "[[OUTLIB]]" "-o" "[[OUTLIST]]"
40+
// FOFFLOAD_STATIC_LIB2: llvm-link{{(.exe)?}}{{.*}} "@[[OUTLIST]]"
41+
// FOFFLOAD_STATIC_LIB2: link{{(.exe)?}}{{.+}} "{{.*}}-orig2.lib"
42+
2343
/// ###########################################################################
2444

2545
/// Test behaviors of -foffload-static-lib=<lib> with multiple objects.

0 commit comments

Comments
 (0)