Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at netboot-syslinux-multiplatform 123 lines 4.4 kB view raw
1# This setup hook causes the fixup phase to rewrite all script 2# interpreter file names (`#! /path') to paths found in $PATH. E.g., 3# /bin/sh will be rewritten to /nix/store/<hash>-some-bash/bin/sh. 4# /usr/bin/env gets special treatment so that ".../bin/env python" is 5# rewritten to /nix/store/<hash>/bin/python. Interpreters that are 6# already in the store are left untouched. 7# A script file must be marked as executable, otherwise it will not be 8# considered. 9 10fixupOutputHooks+=(patchShebangsAuto) 11 12# Run patch shebangs on a directory or file. 13# Can take multiple paths as arguments. 14# patchShebangs [--build | --host] PATH... 15 16# Flags: 17# --build : Lookup commands available at build-time 18# --host : Lookup commands available at runtime 19 20# Example use cases, 21# $ patchShebangs --host /nix/store/...-hello-1.0/bin 22# $ patchShebangs --build configure 23 24patchShebangs() { 25 local pathName 26 27 if [[ "$1" == "--host" ]]; then 28 pathName=HOST_PATH 29 shift 30 elif [[ "$1" == "--build" ]]; then 31 pathName=PATH 32 shift 33 fi 34 35 echo "patching script interpreter paths in $@" 36 local f 37 local oldPath 38 local newPath 39 local arg0 40 local args 41 local oldInterpreterLine 42 local newInterpreterLine 43 44 if [[ $# -eq 0 ]]; then 45 echo "No arguments supplied to patchShebangs" >&2 46 return 0 47 fi 48 49 local f 50 while IFS= read -r -d $'\0' f; do 51 isScript "$f" || continue 52 53 read -r oldInterpreterLine < "$f" 54 read -r oldPath arg0 args <<< "${oldInterpreterLine:2}" 55 56 if [[ -z "$pathName" ]]; then 57 if [[ -n $strictDeps && $f == "$NIX_STORE"* ]]; then 58 pathName=HOST_PATH 59 else 60 pathName=PATH 61 fi 62 fi 63 64 if [[ "$oldPath" == *"/bin/env" ]]; then 65 if [[ $arg0 == "-S" ]]; then 66 arg0=${args%% *} 67 args=${args#* } 68 newPath="$(PATH="${!pathName}" command -v "env" || true)" 69 args="-S $(PATH="${!pathName}" command -v "$arg0" || true) $args" 70 71 # Check for unsupported 'env' functionality: 72 # - options: something starting with a '-' besides '-S' 73 # - environment variables: foo=bar 74 elif [[ $arg0 == "-"* || $arg0 == *"="* ]]; then 75 echo "$f: unsupported interpreter directive \"$oldInterpreterLine\" (set dontPatchShebangs=1 and handle shebang patching yourself)" >&2 76 exit 1 77 else 78 newPath="$(PATH="${!pathName}" command -v "$arg0" || true)" 79 fi 80 else 81 if [[ -z $oldPath ]]; then 82 # If no interpreter is specified linux will use /bin/sh. Set 83 # oldpath="/bin/sh" so that we get /nix/store/.../sh. 84 oldPath="/bin/sh" 85 fi 86 87 newPath="$(PATH="${!pathName}" command -v "$(basename "$oldPath")" || true)" 88 89 args="$arg0 $args" 90 fi 91 92 # Strip trailing whitespace introduced when no arguments are present 93 newInterpreterLine="$newPath $args" 94 newInterpreterLine=${newInterpreterLine%${newInterpreterLine##*[![:space:]]}} 95 96 if [[ -n "$oldPath" && "${oldPath:0:${#NIX_STORE}}" != "$NIX_STORE" ]]; then 97 if [[ -n "$newPath" && "$newPath" != "$oldPath" ]]; then 98 echo "$f: interpreter directive changed from \"$oldInterpreterLine\" to \"$newInterpreterLine\"" 99 # escape the escape chars so that sed doesn't interpret them 100 escapedInterpreterLine=${newInterpreterLine//\\/\\\\} 101 102 # Preserve times, see: https://github.com/NixOS/nixpkgs/pull/33281 103 timestamp=$(stat --printf "%y" "$f") 104 sed -i -e "1 s|.*|#\!$escapedInterpreterLine|" "$f" 105 touch --date "$timestamp" "$f" 106 fi 107 fi 108 done < <(find "$@" -type f -perm -0100 -print0) 109} 110 111patchShebangsAuto () { 112 if [[ -z "${dontPatchShebangs-}" && -e "$prefix" ]]; then 113 114 # Dev output will end up being run on the build platform. An 115 # example case of this is sdl2-config. Otherwise, we can just 116 # use the runtime path (--host). 117 if [[ "$output" != out && "$output" = "$outputDev" ]]; then 118 patchShebangs --build "$prefix" 119 else 120 patchShebangs --host "$prefix" 121 fi 122 fi 123}