From 3530837417da13076a2c8412de2c0c385dfbd648 Mon Sep 17 00:00:00 2001 From: sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> Date: Tue, 18 May 2021 16:15:03 +0200 Subject: [PATCH] llvmPackages*.clang: fix linker invocation with LLVMgold plugin When using GNU binutils, clang passes the LLVMgold.so plugin to the linker for certain operations that require special support in the linker like doing link time optimization (LTO). When passing the plugin to the linker's command line, clang assumes that llvm and itself are installed in the same prefix and thus `/path/to/clang/bin/../lib/LLVMgold.so` is the plugin. Since we install clang and llvm to separate store paths, this assumption does not hold. When clang-unwrapped only had a single output, we worked around this issue by symlinking `$out/lib/LLVMgold.so` to `${llvm}/lib/LLVMgold.so`. However since we split all llvm packages into multiple outputs clang's `$out` no longer has a lib directory and clang can't discover clangs lib output on its own. As a result LTO was broken. Instead of introducing yet another hack and having a symlink to LLVMgold.so in `$out/lib` (despite having `$lib/lib` as well), we patch clang to use a hard coded path to `${libllvm.lib}/lib` for discovering `LLVMgold.so`. Resolves #123361. --- .../compilers/llvm/10/clang/default.nix | 11 +++++------ .../compilers/llvm/11/clang/default.nix | 11 +++++------ .../compilers/llvm/12/clang/default.nix | 11 +++++------ .../compilers/llvm/5/clang/LLVMgold-path.patch | 14 ++++++++++++++ .../compilers/llvm/5/clang/default.nix | 11 +++++------ .../compilers/llvm/6/clang/default.nix | 11 +++++------ .../compilers/llvm/7/clang/default.nix | 11 +++++------ .../compilers/llvm/8/clang/default.nix | 11 +++++------ .../compilers/llvm/9/clang/default.nix | 11 +++++------ .../llvm/clang-11-12-LLVMgold-path.patch | 13 +++++++++++++ .../compilers/llvm/clang-6-10-LLVMgold-path.patch | 15 +++++++++++++++ 11 files changed, 82 insertions(+), 48 deletions(-) create mode 100644 pkgs/development/compilers/llvm/5/clang/LLVMgold-path.patch create mode 100644 pkgs/development/compilers/llvm/clang-11-12-LLVMgold-path.patch create mode 100644 pkgs/development/compilers/llvm/clang-6-10-LLVMgold-path.patch diff --git a/pkgs/development/compilers/llvm/10/clang/default.nix b/pkgs/development/compilers/llvm/10/clang/default.nix index e0c52651cad..b42f40b9694 100644 --- a/pkgs/development/compilers/llvm/10/clang/default.nix +++ b/pkgs/development/compilers/llvm/10/clang/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, llvm_meta, fetch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 +{ lib, stdenv, llvm_meta, fetch, substituteAll, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 , buildLlvmTools , fixDarwinDylibNames , enableManpages ? false @@ -46,6 +46,10 @@ let # https://reviews.llvm.org/D51899 ./compiler-rt-baremetal.patch ./gnu-install-dirs.patch + (substituteAll { + src = ../../clang-6-10-LLVMgold-path.patch; + libllvmLibdir = "${libllvm.lib}/lib"; + }) ]; postPatch = '' @@ -64,12 +68,7 @@ let outputs = [ "out" "lib" "dev" "python" ]; - # Clang expects to find LLVMgold in its own prefix postInstall = '' - if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then - ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib - fi - ln -sv $out/bin/clang $out/bin/cpp # Move libclang to 'lib' output diff --git a/pkgs/development/compilers/llvm/11/clang/default.nix b/pkgs/development/compilers/llvm/11/clang/default.nix index f23394a8b75..07e5326128a 100644 --- a/pkgs/development/compilers/llvm/11/clang/default.nix +++ b/pkgs/development/compilers/llvm/11/clang/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, llvm_meta, fetch, fetchpatch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 +{ lib, stdenv, llvm_meta, fetch, fetchpatch, substituteAll, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 , buildLlvmTools , fixDarwinDylibNames , enableManpages ? false @@ -57,6 +57,10 @@ let excludes = [ "docs/*" "test/*" ]; sha256 = "0gxgmi0qbm89mq911dahallhi8m6wa9vpklklqmxafx4rplrr8ph"; }) + (substituteAll { + src = ../../clang-11-12-LLVMgold-path.patch; + libllvmLibdir = "${libllvm.lib}/lib"; + }) ]; postPatch = '' @@ -75,12 +79,7 @@ let outputs = [ "out" "lib" "dev" "python" ]; - # Clang expects to find LLVMgold in its own prefix postInstall = '' - if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then - ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib - fi - ln -sv $out/bin/clang $out/bin/cpp # Move libclang to 'lib' output diff --git a/pkgs/development/compilers/llvm/12/clang/default.nix b/pkgs/development/compilers/llvm/12/clang/default.nix index 3d1106dbc52..dbd6ea1e1ac 100644 --- a/pkgs/development/compilers/llvm/12/clang/default.nix +++ b/pkgs/development/compilers/llvm/12/clang/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, llvm_meta, fetch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 +{ lib, stdenv, llvm_meta, fetch, substituteAll, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 , buildLlvmTools , fixDarwinDylibNames , enableManpages ? false @@ -44,6 +44,10 @@ let ./purity.patch # https://reviews.llvm.org/D51899 ./gnu-install-dirs.patch + (substituteAll { + src = ../../clang-11-12-LLVMgold-path.patch; + libllvmLibdir = "${libllvm.lib}/lib"; + }) ]; postPatch = '' @@ -59,12 +63,7 @@ let outputs = [ "out" "lib" "dev" "python" ]; - # Clang expects to find LLVMgold in its own prefix postInstall = '' - if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then - ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib - fi - ln -sv $out/bin/clang $out/bin/cpp # Move libclang to 'lib' output diff --git a/pkgs/development/compilers/llvm/5/clang/LLVMgold-path.patch b/pkgs/development/compilers/llvm/5/clang/LLVMgold-path.patch new file mode 100644 index 00000000000..6a09c91b513 --- /dev/null +++ b/pkgs/development/compilers/llvm/5/clang/LLVMgold-path.patch @@ -0,0 +1,14 @@ +diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp +index 00bd60bc24bb..17416b0bd3c0 100644 +--- a/lib/Driver/ToolChains/CommonArgs.cpp ++++ b/lib/Driver/ToolChains/CommonArgs.cpp +@@ -376,8 +376,7 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, + // as gold requires -plugin to come before any -plugin-opt that -Wl might + // forward. + CmdArgs.push_back("-plugin"); +- std::string Plugin = +- ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so"; ++ std::string Plugin = "@libllvmLibdir@" "/LLVMgold.so"; + CmdArgs.push_back(Args.MakeArgString(Plugin)); + + // Try to pass driver level flags relevant to LTO code generation down to diff --git a/pkgs/development/compilers/llvm/5/clang/default.nix b/pkgs/development/compilers/llvm/5/clang/default.nix index b5887a23c65..df3d2613986 100644 --- a/pkgs/development/compilers/llvm/5/clang/default.nix +++ b/pkgs/development/compilers/llvm/5/clang/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, llvm_meta, fetch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 +{ lib, stdenv, llvm_meta, fetch, substituteAll, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 , buildLlvmTools , fixDarwinDylibNames , enableManpages ? false @@ -43,6 +43,10 @@ let patches = [ ./purity.patch ./gnu-install-dirs.patch + (substituteAll { + src = ./LLVMgold-path.patch; + libllvmLibdir = "${libllvm.lib}/lib"; + }) ]; postPatch = '' @@ -58,12 +62,7 @@ let outputs = [ "out" "lib" "dev" "python" ]; - # Clang expects to find LLVMgold in its own prefix postInstall = '' - if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then - ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib - fi - ln -sv $out/bin/clang $out/bin/cpp # Move libclang to 'lib' output diff --git a/pkgs/development/compilers/llvm/6/clang/default.nix b/pkgs/development/compilers/llvm/6/clang/default.nix index eba9111d9d3..ee8859c159a 100644 --- a/pkgs/development/compilers/llvm/6/clang/default.nix +++ b/pkgs/development/compilers/llvm/6/clang/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, llvm_meta, fetch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 +{ lib, stdenv, llvm_meta, fetch, substituteAll, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 , buildLlvmTools , fixDarwinDylibNames , enableManpages ? false @@ -43,6 +43,10 @@ let patches = [ ./purity.patch ./gnu-install-dirs.patch + (substituteAll { + src = ../../clang-6-10-LLVMgold-path.patch; + libllvmLibdir = "${libllvm.lib}/lib"; + }) ]; postPatch = '' @@ -58,12 +62,7 @@ let outputs = [ "out" "lib" "dev" "python" ]; - # Clang expects to find LLVMgold in its own prefix postInstall = '' - if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then - ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib - fi - ln -sv $out/bin/clang $out/bin/cpp # Move libclang to 'lib' output diff --git a/pkgs/development/compilers/llvm/7/clang/default.nix b/pkgs/development/compilers/llvm/7/clang/default.nix index e1b031ad352..afa1669ace6 100644 --- a/pkgs/development/compilers/llvm/7/clang/default.nix +++ b/pkgs/development/compilers/llvm/7/clang/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, llvm_meta, fetch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 +{ lib, stdenv, llvm_meta, fetch, substituteAll, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 , buildLlvmTools , fixDarwinDylibNames , enableManpages ? false @@ -52,6 +52,10 @@ let # needed for our bootstrapping to not interfere with C. ./unwindlib.patch ./gnu-install-dirs.patch + (substituteAll { + src = ../../clang-6-10-LLVMgold-path.patch; + libllvmLibdir = "${libllvm.lib}/lib"; + }) ]; postPatch = '' @@ -70,12 +74,7 @@ let outputs = [ "out" "lib" "dev" "python" ]; - # Clang expects to find LLVMgold in its own prefix postInstall = '' - if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then - ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib - fi - ln -sv $out/bin/clang $out/bin/cpp # Move libclang to 'lib' output diff --git a/pkgs/development/compilers/llvm/8/clang/default.nix b/pkgs/development/compilers/llvm/8/clang/default.nix index c3399dccd1d..5cb7720d026 100644 --- a/pkgs/development/compilers/llvm/8/clang/default.nix +++ b/pkgs/development/compilers/llvm/8/clang/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, llvm_meta, fetch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 +{ lib, stdenv, llvm_meta, fetch, substituteAll, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 , buildLlvmTools , fixDarwinDylibNames , enableManpages ? false @@ -59,6 +59,10 @@ let # make clang -xhip use $PATH to find executables ./HIP-use-PATH-8.patch ./gnu-install-dirs.patch + (substituteAll { + src = ../../clang-6-10-LLVMgold-path.patch; + libllvmLibdir = "${libllvm.lib}/lib"; + }) ]; postPatch = '' @@ -77,12 +81,7 @@ let outputs = [ "out" "lib" "dev" "python" ]; - # Clang expects to find LLVMgold in its own prefix postInstall = '' - if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then - ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib - fi - ln -sv $out/bin/clang $out/bin/cpp # Move libclang to 'lib' output diff --git a/pkgs/development/compilers/llvm/9/clang/default.nix b/pkgs/development/compilers/llvm/9/clang/default.nix index 700fcb414fc..c98b4a830c4 100644 --- a/pkgs/development/compilers/llvm/9/clang/default.nix +++ b/pkgs/development/compilers/llvm/9/clang/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, llvm_meta, fetch, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 +{ lib, stdenv, llvm_meta, fetch, substituteAll, cmake, libxml2, libllvm, version, clang-tools-extra_src, python3 , buildLlvmTools , fixDarwinDylibNames , enableManpages ? false @@ -52,6 +52,10 @@ let # make clang -xhip use $PATH to find executables ./HIP-use-PATH-9.patch ./gnu-install-dirs.patch + (substituteAll { + src = ../../clang-6-10-LLVMgold-path.patch; + libllvmLibdir = "${libllvm.lib}/lib"; + }) ]; postPatch = '' @@ -70,12 +74,7 @@ let outputs = [ "out" "lib" "dev" "python" ]; - # Clang expects to find LLVMgold in its own prefix postInstall = '' - if [ -e ${libllvm.lib}/lib/LLVMgold.so ]; then - ln -sv ${libllvm.lib}/lib/LLVMgold.so $lib/lib - fi - ln -sv $out/bin/clang $out/bin/cpp # Move libclang to 'lib' output diff --git a/pkgs/development/compilers/llvm/clang-11-12-LLVMgold-path.patch b/pkgs/development/compilers/llvm/clang-11-12-LLVMgold-path.patch new file mode 100644 index 00000000000..8f8991976f3 --- /dev/null +++ b/pkgs/development/compilers/llvm/clang-11-12-LLVMgold-path.patch @@ -0,0 +1,13 @@ +diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp +index 6b6e276b8ce7..7896542a1202 100644 +--- a/lib/Driver/ToolChains/CommonArgs.cpp ++++ b/lib/Driver/ToolChains/CommonArgs.cpp +@@ -409,7 +409,7 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, + + SmallString<1024> Plugin; + llvm::sys::path::native( +- Twine(D.Dir) + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + Suffix, ++ Twine("@libllvmLibdir@" "/LLVMgold") + Suffix, + Plugin); + CmdArgs.push_back(Args.MakeArgString(Plugin)); + } diff --git a/pkgs/development/compilers/llvm/clang-6-10-LLVMgold-path.patch b/pkgs/development/compilers/llvm/clang-6-10-LLVMgold-path.patch new file mode 100644 index 00000000000..93504316edf --- /dev/null +++ b/pkgs/development/compilers/llvm/clang-6-10-LLVMgold-path.patch @@ -0,0 +1,15 @@ +diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp +index 37ec73468570..b73e75aa6e59 100644 +--- a/lib/Driver/ToolChains/CommonArgs.cpp ++++ b/lib/Driver/ToolChains/CommonArgs.cpp +@@ -370,8 +370,8 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, + #endif + + SmallString<1024> Plugin; +- llvm::sys::path::native(Twine(ToolChain.getDriver().Dir) + +- "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + ++ llvm::sys::path::native(Twine("@libllvmLibdir@" ++ "/LLVMgold") + + Suffix, + Plugin); + CmdArgs.push_back(Args.MakeArgString(Plugin));