···1-# This setup hook strips libraries and executables in the fixup phase.
2-3-fixupOutputHooks+=(_doStrip)
4-5-_doStrip() {
6- # We don't bother to strip build platform code because it shouldn't make it
7- # to $out anyways---if it does, that's a bigger problem that a lack of
8- # stripping will help catch.
9- local -ra flags=(dontStripHost dontStripTarget)
10- local -ra debugDirs=(stripDebugList stripDebugListTarget)
11- local -ra allDirs=(stripAllList stripAllListTarget)
12- local -ra stripCmds=(STRIP STRIP_FOR_TARGET)
13- local -ra ranlibCmds=(RANLIB RANLIB_FOR_TARGET)
14-15- # TODO(structured-attrs): This doesn't work correctly if one of
16- # the items in strip*List or strip*Flags contains a space,
17- # even with structured attrs enabled. This is OK for now
18- # because very few packages set any of these, and it doesn't
19- # affect any of them.
20- #
21- # After __structuredAttrs = true is universal, come back and
22- # push arrays all the way through this logic.
23-24- # Strip only host paths by default. Leave targets as is.
25- stripDebugList=${stripDebugList[*]:-lib lib32 lib64 libexec bin sbin}
26- stripDebugListTarget=${stripDebugListTarget[*]:-}
27- stripAllList=${stripAllList[*]:-}
28- stripAllListTarget=${stripAllListTarget[*]:-}
29-30- local i
31- for i in ${!stripCmds[@]}; do
32- local -n flag="${flags[$i]}"
33- local -n debugDirList="${debugDirs[$i]}"
34- local -n allDirList="${allDirs[$i]}"
35- local -n stripCmd="${stripCmds[$i]}"
36- local -n ranlibCmd="${ranlibCmds[$i]}"
37-38- # `dontStrip` disables them all
39- if [[ "${dontStrip-}" || "${flag-}" ]] || ! type -f "${stripCmd-}" 2>/dev/null 1>&2
40- then continue; fi
41-42- stripDirs "$stripCmd" "$ranlibCmd" "$debugDirList" "${stripDebugFlags[*]:--S -p}"
43- stripDirs "$stripCmd" "$ranlibCmd" "$allDirList" "${stripAllFlags[*]:--s -p}"
44- done
45-}
46-47-stripDirs() {
48- local cmd="$1"
49- local ranlibCmd="$2"
50- local paths="$3"
51- local stripFlags="$4"
52- local pathsNew=
53-54- [ -z "$cmd" ] && echo "stripDirs: Strip command is empty" 1>&2 && exit 1
55- [ -z "$ranlibCmd" ] && echo "stripDirs: Ranlib command is empty" 1>&2 && exit 1
56-57- local p
58- for p in ${paths}; do
59- if [ -e "$prefix/$p" ]; then
60- pathsNew="${pathsNew} $prefix/$p"
61- fi
62- done
63- paths=${pathsNew}
64-65- if [ -n "${paths}" ]; then
66- echo "stripping (with command $cmd and flags $stripFlags) in $paths"
67- local striperr
68- striperr="$(mktemp 'striperr.XXXXXX')"
69- # Do not strip lib/debug. This is a directory used by setup-hooks/separate-debug-info.sh.
70- find $paths -type f -a '!' -path "$prefix/lib/debug/*" -print0 |
71- # Make sure we process files under symlinks only once. Otherwise
72- # 'strip` can corrupt files when writes to them in parallel:
73- # https://github.com/NixOS/nixpkgs/issues/246147#issuecomment-1657072039
74- xargs -r -0 -n1 -- realpath -z | sort -u -z |
75-76- xargs -r -0 -n1 -P "$NIX_BUILD_CORES" -- $cmd $stripFlags 2>"$striperr" || exit_code=$?
77- # xargs exits with status code 123 if some but not all of the
78- # processes fail. We don't care if some of the files couldn't
79- # be stripped, so ignore specifically this code.
80- [[ "$exit_code" = 123 || -z "$exit_code" ]] || (cat "$striperr" 1>&2 && exit 1)
81-82- rm "$striperr"
83- # 'strip' does not normally preserve archive index in .a files.
84- # This usually causes linking failures against static libs like:
85- # ld: ...-i686-w64-mingw32-stage-final-gcc-13.0.0-lib/i686-w64-mingw32/lib/libstdc++.dll.a:
86- # error adding symbols: archive has no index; run ranlib to add one
87- # Restore the index by running 'ranlib'.
88- find $paths -name '*.a' -type f -exec $ranlibCmd '{}' \; 2>/dev/null
89- fi
90-}