From 9061f5d5abb1aab25df9a33f989d85870328f133 Mon Sep 17 00:00:00 2001 From: Linus Heckemann Date: Mon, 30 Oct 2017 18:45:29 +0100 Subject: [PATCH 1/3] stdenv: set soname for libraries to absolute path Fixes #24844 --- pkgs/build-support/setup-hooks/set-soname.sh | 8 ++++++++ pkgs/development/compilers/gcc/6/default.nix | 2 ++ pkgs/development/libraries/glibc/common.nix | 2 ++ pkgs/development/tools/misc/binutils/default.nix | 1 + pkgs/stdenv/generic/default.nix | 1 + 5 files changed, 14 insertions(+) create mode 100644 pkgs/build-support/setup-hooks/set-soname.sh diff --git a/pkgs/build-support/setup-hooks/set-soname.sh b/pkgs/build-support/setup-hooks/set-soname.sh new file mode 100644 index 00000000000000..5a408905e8ae01 --- /dev/null +++ b/pkgs/build-support/setup-hooks/set-soname.sh @@ -0,0 +1,8 @@ +[[ -z "$noAbsoluteSoname" ]] && fixupOutputHooks+=(_doAbsoluteSoname) + +_doAbsoluteSoname() { + echo "Making sonames absolute" + if test -d "$prefix" ; then + find "$prefix" -type f '(' -name "lib*.so.*" -or -name 'lib*.so' ')' -not -name 'ld*' -exec patchelf --set-soname {} {} ';' + fi +} diff --git a/pkgs/development/compilers/gcc/6/default.nix b/pkgs/development/compilers/gcc/6/default.nix index 0fb390758954ac..060b8123c185d3 100644 --- a/pkgs/development/compilers/gcc/6/default.nix +++ b/pkgs/development/compilers/gcc/6/default.nix @@ -162,6 +162,8 @@ stdenv.mkDerivation ({ builder = ../builder.sh; + noAbsoluteSoname = true; + src = fetchurl { url = "mirror://gnu/gcc/gcc-${version}/gcc-${version}.tar.xz"; sha256 = "1m0lr7938lw5d773dkvwld90hjlcq2282517d1gwvrfzmwgg42w5"; diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix index 8b4a213aae0517..8a6c18140278ca 100644 --- a/pkgs/development/libraries/glibc/common.nix +++ b/pkgs/development/libraries/glibc/common.nix @@ -145,6 +145,8 @@ stdenv.mkDerivation ({ # prevent a retained dependency on the bootstrap tools in the stdenv-linux # bootstrap. BASH_SHELL = "/bin/sh"; + + noAbsoluteSoname = true; } // (removeAttrs args [ "withLinuxHeaders" "withGd" ]) // diff --git a/pkgs/development/tools/misc/binutils/default.nix b/pkgs/development/tools/misc/binutils/default.nix index 890ff7b64a9153..ddc895b8900e34 100644 --- a/pkgs/development/tools/misc/binutils/default.nix +++ b/pkgs/development/tools/misc/binutils/default.nix @@ -78,6 +78,7 @@ stdenv.mkDerivation rec { buildInputs = [ zlib ]; inherit noSysDirs; + noAbsoluteSoname = true; preConfigure = '' # Clear the default library search path. diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index 2eac9e58daa643..a7d0d33686abd1 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -47,6 +47,7 @@ let ../../build-support/setup-hooks/compress-man-pages.sh ../../build-support/setup-hooks/strip.sh ../../build-support/setup-hooks/patch-shebangs.sh + ../../build-support/setup-hooks/set-soname.sh ] # FIXME this on Darwin; see # https://github.com/NixOS/nixpkgs/commit/94d164dd7#commitcomment-22030369 From 12b6e84555648f557b652ac3049003ec64ce488e Mon Sep 17 00:00:00 2001 From: Linus Heckemann Date: Thu, 16 Aug 2018 10:28:22 +0200 Subject: [PATCH 2/3] Partly fix initrd building for soname change --- nixos/modules/system/boot/stage-1.nix | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 2caab69cbb95ce..c61e8606c703b1 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -61,6 +61,13 @@ let ld*.so.?) continue;; esac + # $next might be an absolute path + if [ -f "$next" ]; then + echo "$next" + add_needed "$next" + continue + fi + IFS=: read -ra paths <<< $rpath res= for path in "''${paths[@]}"; do @@ -166,16 +173,25 @@ let stripDirs "$STRIP" "lib bin" "-s" # Run patchelf to make the programs refer to the copied libraries. - find $out/bin $out/lib -type f | while read i; do + ( find $out/bin -type f ; find $out/lib -type f -not -name "ld*" ) | while read i; do if ! test -L $i; then - nuke-refs -e $out $i + echo "patching $i..." + libs=$(patchelf --print-needed $i) + replacements="" + for library in $libs; do + [[ library = */ld* ]] && continue + replacements+="--replace-needed $library $(basename $library) " + done + patchelf $replacements $i || true + patchelf --set-rpath $out/lib $i || true + [[ $i = $out/bin/* ]] && patchelf --set-interpreter $out/lib/ld*.so.? $i || true fi done - find $out/bin -type f | while read i; do + # Remove any remaining refs to the outside + find $out/bin $out/lib -type f | while read i; do if ! test -L $i; then - echo "patching $i..." - patchelf --set-interpreter $out/lib/ld*.so.? --set-rpath $out/lib $i || true + nuke-refs -e $out $i fi done From e87c9b6349c4dfcfa85b455f01b5f5d39452cd49 Mon Sep 17 00:00:00 2001 From: Linus Heckemann Date: Thu, 16 Aug 2018 11:36:07 +0200 Subject: [PATCH 3/3] doc: document noAbsoluteSoname --- doc/stdenv.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/stdenv.xml b/doc/stdenv.xml index 94bd7365dd9a6f..0b5dabb06d27d5 100644 --- a/doc/stdenv.xml +++ b/doc/stdenv.xml @@ -1499,6 +1499,15 @@ installTargets = "install-bin install-doc"; dependencies. + + + On Linux, it uses patchelf on all libraries in + the lib tree to make the DT_SONAME + an absolute path to the library. This makes other binaries that + link against it access it directly rather than searching through + DT_RUNPATH, which increases efficiency. + + It rewrites the interpreter paths of shell scripts to paths found in @@ -1621,6 +1630,18 @@ installTargets = "install-bin install-doc"; + + + noAbsoluteSoname + + + + If set, the DT_SONAME entries of the shared + libraries in the output will be left unmodified. Only applies + to Linux. + + + dontPatchShebangs