Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 34 additions & 10 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2992,9 +2992,10 @@ static SmallVector<const char *, 16>
getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) {
SmallVector<const char *, 16> LibArgs;
SmallVector<std::string, 8> LibPaths;
// Add search directories from LIBRARY_PATH env variable
bool IsMSVC = C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
// Add search directories from LIBRARY_PATH/LIB env variable
llvm::Optional<std::string> LibPath =
llvm::sys::Process::GetEnv("LIBRARY_PATH");
llvm::sys::Process::GetEnv(IsMSVC ? "LIB" : "LIBRARY_PATH");
if (LibPath) {
SmallVector<StringRef, 8> SplitPaths;
const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
Expand Down Expand Up @@ -3028,12 +3029,36 @@ getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) {
};
for (const auto *A : Args) {
std::string FileName = A->getAsString(Args);
auto addLibArg = [&](StringRef LibName) -> bool {
if (isStaticArchiveFile(LibName) ||
(IncludeObj && isObjectFile(LibName.str()))) {
LibArgs.push_back(Args.MakeArgString(LibName));
return true;
}
return false;
};
if (A->getOption().getKind() == Option::InputClass) {
StringRef Value(A->getValue());
if (isStaticArchiveFile(Value) ||
(IncludeObj && isObjectFile(Value.str()))) {
LibArgs.push_back(Args.MakeArgString(FileName));
if (addLibArg(FileName))
continue;
}
// Evaluate any libraries passed along after /link. These are typically
// ignored by the driver and sent directly to the linker. When performing
// offload, we should evaluate them at the driver level.
if (A->getOption().matches(options::OPT__SLASH_link)) {
for (const std::string &Value : A->getValues()) {
// Add any libpath values.
StringRef OptCheck(Value);
if (OptCheck.startswith_insensitive("-libpath:") ||
OptCheck.startswith_insensitive("/libpath:"))
LibPaths.emplace_back(Value.substr(std::string("-libpath:").size()));
if (addLibArg(Value))
continue;
for (auto LPath : LibPaths) {
SmallString<128> FullLib(LPath);
llvm::sys::path::append(FullLib, Value);
if (addLibArg(FullLib))
continue;
}
}
}
if (A->getOption().matches(options::OPT_Wl_COMMA) ||
Expand Down Expand Up @@ -3075,9 +3100,8 @@ getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) {
llvm::StringSaver S(A);
llvm::cl::ExpandResponseFiles(
S,
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
? llvm::cl::TokenizeWindowsCommandLine
: llvm::cl::TokenizeGNUCommandLine,
IsMSVC ? llvm::cl::TokenizeWindowsCommandLine
: llvm::cl::TokenizeGNUCommandLine,
ExpandArgs);
for (StringRef EA : ExpandArgs)
addKnownValues(EA);
Expand Down Expand Up @@ -8311,7 +8335,7 @@ bool clang::driver::isStaticArchiveFile(const StringRef &FileName) {
llvm::file_magic Magic;
llvm::identify_magic(FileName, Magic);
// Only .lib and archive files are to be considered.
return (Ext == "lib" || Magic == llvm::file_magic::archive);
return (Magic == llvm::file_magic::archive);
}

bool clang::driver::willEmitRemarks(const ArgList &Args) {
Expand Down
20 changes: 20 additions & 0 deletions clang/test/Driver/sycl-offload-win.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,32 @@
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t-orig.lib %t-orig.obj -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fno-sycl-device-lib=all %t-orig.obj -### /link %t-orig.lib 2>&1 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB
// 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"
// FOFFLOAD_STATIC_LIB: clang-offload-bundler{{(.exe)?}}{{.+}} "-type=aoo" "-targets=sycl-spir64-{{.+}}" "-inputs={{.*}}-orig.lib" "-outputs=[[OUTLIB:.+\.txt]]" "-unbundle"
// 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]]"
// FOFFLOAD_STATIC_LIB: llvm-link{{(.exe)?}}{{.*}} "@[[OUTLIST]]"
// FOFFLOAD_STATIC_LIB: link{{(.exe)?}}{{.+}} "{{.*}}-orig.lib"

// RUN: mkdir -p %t_dir
// RUN: llvm-ar cr %t_dir/%basename_t-orig2.lib %t-orig.obj
// 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 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
// 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 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
// 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 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
// 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 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
// 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 \
// RUN: | FileCheck %s -check-prefix=FOFFLOAD_STATIC_LIB2
// 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"
// FOFFLOAD_STATIC_LIB2: clang-offload-bundler{{(.exe)?}}{{.+}} "-type=aoo" "-targets=sycl-spir64-{{.+}}" "-inputs={{.*}}-orig2.lib" "-outputs=[[OUTLIB:.+\.txt]]" "-unbundle"
// 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]]"
// FOFFLOAD_STATIC_LIB2: llvm-link{{(.exe)?}}{{.*}} "@[[OUTLIST]]"
// FOFFLOAD_STATIC_LIB2: link{{(.exe)?}}{{.+}} "{{.*}}-orig2.lib"

/// ###########################################################################

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