diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 07d1f97b02d85..5acc548a4c5c6 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2992,9 +2992,10 @@ static SmallVector getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) { SmallVector LibArgs; SmallVector 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 LibPath = - llvm::sys::Process::GetEnv("LIBRARY_PATH"); + llvm::sys::Process::GetEnv(IsMSVC ? "LIB" : "LIBRARY_PATH"); if (LibPath) { SmallVector SplitPaths; const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; @@ -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) || @@ -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); @@ -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) { diff --git a/clang/test/Driver/sycl-offload-win.c b/clang/test/Driver/sycl-offload-win.c index 86ead0b659f61..b19fed3a778cb 100644 --- a/clang/test/Driver/sycl-offload-win.c +++ b/clang/test/Driver/sycl-offload-win.c @@ -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= with multiple objects.