diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index ca650f8c42eda..76cede0949b87 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2977,6 +2977,41 @@ static bool optionMatches(const std::string &Option, static SmallVector getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) { SmallVector LibArgs; + SmallVector LibPaths; + // Add search directories from LIBRARY_PATH env variable + llvm::Optional LibPath = + llvm::sys::Process::GetEnv("LIBRARY_PATH"); + if (LibPath) { + SmallVector SplitPaths; + const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; + llvm::SplitString(*LibPath, SplitPaths, EnvPathSeparatorStr); + for (StringRef Path : SplitPaths) + LibPaths.emplace_back(Path.trim()); + } + // Add directories from user-specified -L options + for (std::string LibDirs : Args.getAllArgValues(options::OPT_L)) + LibPaths.emplace_back(LibDirs); + + // Do processing for any -l options passed and see if any static + // libraries representing the name exists. If so, convert the name and + // use that inline with the rest of the libraries. + // TODO: The static archive processing for SYCL is done in a different + // manner than the OpenMP processing. We should try and refactor this + // to use the OpenMP flow (adding -l to the llvm-link step) + auto resolveStaticLib = [&](StringRef LibName) -> bool { + if (!LibName.startswith("-l")) + return false; + for (auto LPath : LibPaths) { + SmallString<128> FullName(LPath); + llvm::sys::path::append(FullName, + Twine("lib" + LibName.substr(2) + ".a").str()); + if (llvm::sys::fs::exists(FullName)) { + LibArgs.push_back(Args.MakeArgString(FullName)); + return true; + } + } + return false; + }; for (const auto *A : Args) { std::string FileName = A->getAsString(Args); if (A->getOption().getKind() == Option::InputClass) { @@ -3014,6 +3049,7 @@ getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) { LibArgs.push_back(Args.MakeArgString(V)); return; } + resolveStaticLib(V); }; if (Value[0] == '@') { // Found a response file, we want to expand contents to try and @@ -3053,6 +3089,8 @@ getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) { LibArgs.push_back("--no-whole-archive"); continue; } + if (A->getOption().matches(options::OPT_l)) + resolveStaticLib(A->getAsString(Args)); } return LibArgs; } diff --git a/clang/test/Driver/sycl-offload-static-lib-2.cpp b/clang/test/Driver/sycl-offload-static-lib-2.cpp index eb5dbea2d598e..7e31c773f766c 100644 --- a/clang/test/Driver/sycl-offload-static-lib-2.cpp +++ b/clang/test/Driver/sycl-offload-static-lib-2.cpp @@ -34,6 +34,25 @@ // STATIC_LIB_NVPTX: llvm-link{{.*}} "[[OUTFILE]]" // STATIC_LIB: ld{{.*}} "{{.*}}_lib.{{(a|lo)}}" "[[HOSTOBJ]]" +// Test using -l style for passing libraries. +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -L%S/Inputs/SYCL -llin64 -### %t_obj.o 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=STATIC_L_LIB,STATIC_L_LIB_DEF -DBUNDLE_TRIPLE=sycl-spir64-unknown-unknown +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fsycl-targets=nvptx64-nvidia-cuda -L%S/Inputs/SYCL -llin64 -### %t_obj.o 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=STATIC_L_LIB,STATIC_L_LIB_NVPTX -DBUNDLE_TRIPLE=sycl-nvptx64-nvidia-cuda-sm_50 +// STATIC_L_LIB: clang-offload-bundler{{.*}} "-type=o" "-targets={{.*}},[[BUNDLE_TRIPLE]]" "-inputs=[[INPUTO:.+\.o]]" "-outputs=[[HOSTOBJ:.+\.o]],{{.+\.o}}" +// STATIC_L_LIB: clang-offload-deps{{.*}} "-targets=[[BUNDLE_TRIPLE]]" +// STATIC_L_LIB_DEF: clang-offload-bundler{{.*}} "-type=aoo" "-targets=[[BUNDLE_TRIPLE]]" "-inputs={{.*}}liblin64.a" "-outputs=[[OUTFILE:.+\.txt]]" +// STATIC_L_LIB_NVPTX: clang-offload-bundler{{.*}} "-type=a" "-targets=[[BUNDLE_TRIPLE]]" "-inputs={{.*}}liblin64.a" "-outputs=[[OUTFILE:.+\.a]]" +// STATIC_L_LIB_DEF: llvm-foreach{{.*}} "--out-ext=txt" "--in-file-list=[[OUTFILE]]" "--in-replace=[[OUTFILE]]" "--out-file-list=[[IROUTFILE:.+\.txt]]" "--out-replace=[[IROUTFILE]]" "--" {{.*}}spirv-to-ir-wrapper{{.*}} "[[OUTFILE]]" "-o" "[[IROUTFILE]]" +// STATIC_L_LIB_DEF: llvm-link{{.*}} "@[[IROUTFILE]]" +// STATIC_L_LIB_NVPTX: llvm-link{{.*}} "[[OUTFILE]]" +// STATIC_L_LIB: ld{{.*}} "-llin64" "[[HOSTOBJ]]" + +// non-fat libraries should not trigger the unbundling step. +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -lc -lm -ldl -### 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=NO_STATIC_UNBUNDLE +// NO_STATIC_UNBUNDLE-NOT: clang-offload-bundler{{.*}} "-type=aoo" {{.*}} "-inputs={{.*}}lib{{.*}}.a" + /// ########################################################################### /// test behaviors of fat static lib with multiple objects