From 3e8eec42d9407fd56cdf34733442f7e7ba745aeb Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Thu, 27 Jan 2022 17:20:47 -0800 Subject: [PATCH 1/2] [Driver][SYCL] Initial support for allowing fat static -lname processing When processing for fat static libraries, add searches for -lname type libraries passed on the command line. This also takes advantage of the -Ldir options and LIBRARY_PATH environment variable for locating the libraries. When a library is found (with a .a extension) that is what is used for unbundling and added to the device link. NOTE: This behavior does not match the recent implementation done for OpenMP offloading with fat static libraries. That implementation is directly integrated into the llvm-link call. It would be good to also follow this for consistency, but will require some refactoring to accomplish. --- clang/lib/Driver/Driver.cpp | 38 +++++++++++++++++++ .../test/Driver/sycl-offload-static-lib-2.cpp | 19 ++++++++++ 2 files changed, 57 insertions(+) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index ca650f8c42eda..e15abe551bae9 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 From 32e0d8a1cc03d9b4254a92cff70c87003a2845e2 Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Thu, 27 Jan 2022 17:29:59 -0800 Subject: [PATCH 2/2] clang format --- clang/lib/Driver/Driver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index e15abe551bae9..76cede0949b87 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3003,8 +3003,8 @@ getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) { return false; for (auto LPath : LibPaths) { SmallString<128> FullName(LPath); - llvm::sys::path::append( - FullName, Twine("lib" + LibName.substr(2) + ".a").str()); + 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;