summary refs log tree commit diff
path: root/pkgs/build-support/setup-hooks
diff options
context:
space:
mode:
authorFrederik Rietdijk <fridh@fridh.nl>2018-11-29 08:12:56 +0100
committerFrederik Rietdijk <fridh@fridh.nl>2018-11-29 08:12:56 +0100
commit9db2421d1f65beb38911e8133349193db0042a1d (patch)
tree90a2f4a56cf871c74aad86138d85e9631c2c2f86 /pkgs/build-support/setup-hooks
parent9caab8ff4a1ad36fbc0ab866f1b0f7c15d35ba90 (diff)
parent8d88e4f6c7b09fe811d92b346e5eafefe07a47c9 (diff)
Merge master into staging-next
Diffstat (limited to 'pkgs/build-support/setup-hooks')
-rw-r--r--pkgs/build-support/setup-hooks/auto-patchelf.sh67
1 files changed, 58 insertions, 9 deletions
diff --git a/pkgs/build-support/setup-hooks/auto-patchelf.sh b/pkgs/build-support/setup-hooks/auto-patchelf.sh
index d1ae317ff9a44..5bedd1a9f9caf 100644
--- a/pkgs/build-support/setup-hooks/auto-patchelf.sh
+++ b/pkgs/build-support/setup-hooks/auto-patchelf.sh
@@ -147,15 +147,56 @@ autoPatchelfFile() {
     fi
 }
 
+# Can be used to manually add additional directories with shared object files
+# to be included for the next autoPatchelf invocation.
+addAutoPatchelfSearchPath() {
+    local -a findOpts=()
+
+    # XXX: Somewhat similar to the one in the autoPatchelf function, maybe make
+    #      it DRY someday...
+    while [ $# -gt 0 ]; do
+        case "$1" in
+            --) shift; break;;
+            --no-recurse) shift; findOpts+=("-maxdepth" 1);;
+            --*)
+                echo "addAutoPatchelfSearchPath: ERROR: Invalid command line" \
+                     "argument: $1" >&2
+                return 1;;
+            *) break;;
+        esac
+    done
+
+    cachedDependencies+=(
+        $(find "$@" "${findOpts[@]}" \! -type d \
+               \( -name '*.so' -o -name '*.so.*' \))
+    )
+}
+
 autoPatchelf() {
+    local norecurse=
+
+    while [ $# -gt 0 ]; do
+        case "$1" in
+            --) shift; break;;
+            --no-recurse) shift; norecurse=1;;
+            --*)
+                echo "autoPatchelf: ERROR: Invalid command line" \
+                     "argument: $1" >&2
+                return 1;;
+            *) break;;
+        esac
+    done
+
+    if [ $# -eq 0 ]; then
+        echo "autoPatchelf: No paths to patch specified." >&2
+        return 1
+    fi
+
     echo "automatically fixing dependencies for ELF files" >&2
 
     # Add all shared objects of the current output path to the start of
     # cachedDependencies so that it's choosen first in findDependency.
-    cachedDependencies+=(
-        $(find "$prefix" \! -type d \( -name '*.so' -o -name '*.so.*' \))
-    )
-    local elffile
+    addAutoPatchelfSearchPath ${norecurse:+--no-recurse} -- "$@"
 
     # Here we actually have a subshell, which also means that
     # $cachedDependencies is final at this point, so whenever we want to run
@@ -164,12 +205,15 @@ autoPatchelf() {
     # outside of this function.
     while IFS= read -r -d $'\0' file; do
       isELF "$file" || continue
+      segmentHeaders="$(LANG=C readelf -l "$file")"
+      # Skip if the ELF file doesn't have segment headers (eg. object files).
+      echo "$segmentHeaders" | grep -q '^Program Headers:' || continue
       if isExecutable "$file"; then
           # Skip if the executable is statically linked.
-          LANG=C readelf -l "$file" | grep -q "^ *INTERP\\>" || continue
+          echo "$segmentHeaders" | grep -q "^ *INTERP\\>" || continue
       fi
       autoPatchelfFile "$file"
-    done < <(find "$prefix" -type f -print0)
+    done < <(find "$@" ${norecurse:+-maxdepth 1} -type f -print0)
 }
 
 # XXX: This should ultimately use fixupOutputHooks but we currently don't have
@@ -180,6 +224,11 @@ autoPatchelf() {
 # So what we do here is basically run in postFixup and emulate the same
 # behaviour as fixupOutputHooks because the setup hook for patchelf is run in
 # fixupOutput and the postFixup hook runs later.
-postFixupHooks+=(
-    'for output in $outputs; do prefix="${!output}" autoPatchelf; done'
-)
+postFixupHooks+=('
+    if [ -z "$dontAutoPatchelf" ]; then
+        autoPatchelf -- $(for output in $outputs; do
+            [ -e "${!output}" ] || continue
+            echo "${!output}"
+        done)
+    fi
+')