about summary refs log tree commit diff
path: root/pkgs/build-support/setup-hooks
diff options
context:
space:
mode:
authorThomas Watson <twatson52@icloud.com>2024-05-23 23:11:50 -0500
committerThomas Watson <twatson52@icloud.com>2024-05-24 16:53:14 -0500
commit4d6d293fad1a84b953e6decb32959425fb9d2043 (patch)
tree3386feec6bca4809f2e615f97f01038bed033851 /pkgs/build-support/setup-hooks
parent3254cacae49864ee588fa9d8e9401b9fb77e5c04 (diff)
setup-hooks/strip: uniqify files by inode number before stripping
https://github.com/NixOS/nixpkgs/pull/246164 but for hardlinks.

Mesa, among other packages, has binaries that are linked together and
can end up corrupted when the same binary is stripped through two
different names.

To resolve this, print out the device and inode number before each file
name, sort/uniq based on that, then cut it back out before stripping.

The symlink resolution logic is removed as the same file accessed
through two different links in `$paths` will necessarily have the same
numbers. File/directory within the paths listed in `$paths` are
correctly not (and were never) processed due to the `-type f` predicate
and (implied) `-P` option to `find`.
Diffstat (limited to 'pkgs/build-support/setup-hooks')
-rw-r--r--pkgs/build-support/setup-hooks/strip.sh16
1 files changed, 10 insertions, 6 deletions
diff --git a/pkgs/build-support/setup-hooks/strip.sh b/pkgs/build-support/setup-hooks/strip.sh
index ce41e6ea0562a..49a350af1fa5c 100644
--- a/pkgs/build-support/setup-hooks/strip.sh
+++ b/pkgs/build-support/setup-hooks/strip.sh
@@ -74,13 +74,17 @@ stripDirs() {
         echo "stripping (with command $cmd and flags $stripFlags) in $paths"
         local striperr
         striperr="$(mktemp --tmpdir="$TMPDIR" 'striperr.XXXXXX')"
-        # Do not strip lib/debug. This is a directory used by setup-hooks/separate-debug-info.sh.
-        find $paths -type f "${excludeFlags[@]}" -a '!' -path "$prefix/lib/debug/*" -print0 |
-            # Make sure we process files under symlinks only once. Otherwise
-            # 'strip` can corrupt files when writes to them in parallel:
-            #   https://github.com/NixOS/nixpkgs/issues/246147#issuecomment-1657072039
-            xargs -r -0 -n1 -- realpath -z | sort -u -z |
+        # Make sure we process files only once. `strip`ping the same file through different
+        # links in parallel can corrupt it:
+        #   https://github.com/NixOS/nixpkgs/issues/246147#issuecomment-1657072039
 
+        # Do not strip lib/debug. This is a directory used by setup-hooks/separate-debug-info.sh.
+        # Print out each file's device and inode (which will be the same if two files are hardlinked
+        # or are the same file found through different symlinks), followed by its path...
+        find $paths -type f "${excludeFlags[@]}" -a '!' -path "$prefix/lib/debug/*" -printf '%D-%i,%p\0' |
+            # ... sort/uniq by device/inode, then cut them out and keep the path, ...
+            sort -t, -k1,1 -u -z | cut -d, -f2- -z |
+            # and finally strip each unique path in parallel.
             xargs -r -0 -n1 -P "$NIX_BUILD_CORES" -- $cmd $stripFlags 2>"$striperr" || exit_code=$?
         # xargs exits with status code 123 if some but not all of the
         # processes fail. We don't care if some of the files couldn't