From 58a97dfb491be6ae92499c3f819440f281d826a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sun, 23 Sep 2018 14:45:32 +0100 Subject: [PATCH 1/4] autoPatchelfHook: do not patch statically linked files Also speed up quite significantly due less forking. --- .../setup-hooks/auto-patchelf.sh | 25 ++++++------------- pkgs/top-level/all-packages.nix | 3 +-- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/pkgs/build-support/setup-hooks/auto-patchelf.sh b/pkgs/build-support/setup-hooks/auto-patchelf.sh index 32fdb1000e2..94ea3e4e98e 100644 --- a/pkgs/build-support/setup-hooks/auto-patchelf.sh +++ b/pkgs/build-support/setup-hooks/auto-patchelf.sh @@ -7,21 +7,7 @@ gatherLibraries() { addEnvHooks "$targetOffset" gatherLibraries isExecutable() { - [ "$(file -b -N --mime-type "$1")" = application/x-executable ] -} - -findElfs() { - find "$1" -type f -exec "$SHELL" -c ' - while [ -n "$1" ]; do - mimeType="$(file -b -N --mime-type "$1")" - if [ "$mimeType" = application/x-executable \ - -o "$mimeType" = application/x-pie-executable \ - -o "$mimeType" = application/x-sharedlib ]; then - echo "$1" - fi - shift - done - ' -- {} + + readelf -h "$1" | grep -q '^ *Type: *EXEC\>' } # We cache dependencies so that we don't need to search through all of them on @@ -167,9 +153,12 @@ autoPatchelf() { # findDependency outside of this, the dependency cache needs to be rebuilt # from scratch, so keep this in mind if you want to run findDependency # outside of this function. - findElfs "$prefix" | while read -r elffile; do - autoPatchelfFile "$elffile" - done + while IFS= read -r -d $'\0' file; do + isELF "$file" || continue + # dynamically linked? + readelf -l "$file" | grep -q "^ *INTERP\\>" || continue + autoPatchelfFile "$file" + done < <(find "$prefix" -type f -print0) } # XXX: This should ultimately use fixupOutputHooks but we currently don't have diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index ae19c6d650d..76564b38c01 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -81,8 +81,7 @@ with pkgs; { deps = [ autoconf264 automake111x gettext libtool ]; } ../build-support/setup-hooks/autoreconf.sh; - autoPatchelfHook = makeSetupHook - { name = "auto-patchelf-hook"; deps = [ file ]; } + autoPatchelfHook = makeSetupHook { name = "auto-patchelf-hook"; } ../build-support/setup-hooks/auto-patchelf.sh; ensureNewerSourcesHook = { year }: makeSetupHook {} From 9920215d005db148564e826478474faa236a4e75 Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 25 Sep 2018 04:11:33 +0200 Subject: [PATCH 2/4] autoPatchelfHook: Only check PT_INTERP on execs If the ELF file is not an executable, we do not get a PT_INTERP section, because after all, it's a *shared* library. So instead of checking for PT_INTERP (to avoid statically linked executables) for all ELF files, we add another check to see if it's an executable and *only* skip it when it is and there's no PT_INTERP. Signed-off-by: aszlig --- pkgs/build-support/setup-hooks/auto-patchelf.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkgs/build-support/setup-hooks/auto-patchelf.sh b/pkgs/build-support/setup-hooks/auto-patchelf.sh index 94ea3e4e98e..f808cd9f78d 100644 --- a/pkgs/build-support/setup-hooks/auto-patchelf.sh +++ b/pkgs/build-support/setup-hooks/auto-patchelf.sh @@ -155,8 +155,10 @@ autoPatchelf() { # outside of this function. while IFS= read -r -d $'\0' file; do isELF "$file" || continue - # dynamically linked? - readelf -l "$file" | grep -q "^ *INTERP\\>" || continue + if isExecutable "$file"; then + # Skip if the executable is statically linked. + readelf -l "$file" | grep -q "^ *INTERP\\>" || continue + fi autoPatchelfFile "$file" done < <(find "$prefix" -type f -print0) } From b4526040a21303a1822fcad348e9b9e39a3876b9 Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 25 Sep 2018 04:48:12 +0200 Subject: [PATCH 3/4] autoPatchelfHook: Silence errors in isExecutable The "maxx" package recursively runs isExecutable on a bunch of files and since the change to use "readelf" instead of "file" a lot of errors like this one are printed during build: readelf: Error: Not an ELF file - it has the wrong magic bytes at the start While the isExecutable was never meant to be used outside of the autoPatchelfHook, it's still a good idea to silence the errors because whenever readelf fails, it clearly indicates that the file in question is not a valid ELF file. Signed-off-by: aszlig --- pkgs/build-support/setup-hooks/auto-patchelf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/build-support/setup-hooks/auto-patchelf.sh b/pkgs/build-support/setup-hooks/auto-patchelf.sh index f808cd9f78d..7c165627f72 100644 --- a/pkgs/build-support/setup-hooks/auto-patchelf.sh +++ b/pkgs/build-support/setup-hooks/auto-patchelf.sh @@ -7,7 +7,7 @@ gatherLibraries() { addEnvHooks "$targetOffset" gatherLibraries isExecutable() { - readelf -h "$1" | grep -q '^ *Type: *EXEC\>' + readelf -h "$1" 2> /dev/null | grep -q '^ *Type: *EXEC\>' } # We cache dependencies so that we don't need to search through all of them on From 8df68a93e636ce5c67a79713c35eb55a9dfd1bba Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 25 Sep 2018 05:00:44 +0200 Subject: [PATCH 4/4] elasticsearch: Add zlib to buildInputs for unfree The unfree variant of elasticsearch uses autoPatchelfHook and since we removed the dependency on file for the hook itself in 58a97dfb491be6ae92499c3f819440f281d826a1 we no longer have zlib propagated. So we need to explicitly state that dependency here. Signed-off-by: aszlig Cc: @apeschar, @basvandijk --- pkgs/servers/search/elasticsearch/default.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/servers/search/elasticsearch/default.nix b/pkgs/servers/search/elasticsearch/default.nix index 84872649c49..5a43a30257e 100644 --- a/pkgs/servers/search/elasticsearch/default.nix +++ b/pkgs/servers/search/elasticsearch/default.nix @@ -29,7 +29,8 @@ stdenv.mkDerivation (rec { sed -i "s|ES_CLASSPATH=\"\$ES_HOME/lib/\*\"|ES_CLASSPATH=\"$out/lib/*\"|" ./bin/elasticsearch-env ''; - buildInputs = [ makeWrapper jre_headless utillinux ]; + buildInputs = [ makeWrapper jre_headless utillinux ] + ++ optional enableUnfree zlib; installPhase = '' mkdir -p $out