|
| 1 | +# shellcheck shell=bash |
| 2 | +# List all dynamically linked ELF files in the outputs and apply a generic fix |
| 3 | +# action provided as a parameter (currently used to add the CUDA or the |
| 4 | +# cuda_compat driver to the runpath of binaries) |
| 5 | +echo "Sourcing fix-elf-files.sh" |
| 6 | + |
| 7 | +# Returns the exit code of patchelf --print-rpath. |
| 8 | +# A return code of 0 (success) means the ELF file has a dynamic section, while |
| 9 | +# a non-zero return code means the ELF file is statically linked (or is not an |
| 10 | +# ELF file). |
| 11 | +elfHasDynamicSection() { |
| 12 | + local libPath |
| 13 | + |
| 14 | + if [[ $# -eq 0 ]]; then |
| 15 | + echo "elfHasDynamicSection: no library path provided" >&2 |
| 16 | + exit 1 |
| 17 | + elif [[ $# -gt 1 ]]; then |
| 18 | + echo "elfHasDynamicSection: too many arguments" >&2 |
| 19 | + exit 1 |
| 20 | + elif [[ "$1" == "" ]]; then |
| 21 | + echo "elfHasDynamicSection: empty library path" >&2 |
| 22 | + exit 1 |
| 23 | + else |
| 24 | + libPath="$1" |
| 25 | + shift 1 |
| 26 | + fi |
| 27 | + |
| 28 | + patchelf --print-rpath "$libPath" >& /dev/null |
| 29 | + return $? |
| 30 | +} |
| 31 | + |
| 32 | +# Run a fix action on all dynamically linked ELF files in the outputs. |
| 33 | +autoFixElfFiles() { |
| 34 | + local fixAction |
| 35 | + local outputPaths |
| 36 | + |
| 37 | + if [[ $# -eq 0 ]]; then |
| 38 | + echo "autoFixElfFiles: no fix action provided" >&2 |
| 39 | + exit 1 |
| 40 | + elif [[ $# -gt 1 ]]; then |
| 41 | + echo "autoFixElfFiles: too many arguments" >&2 |
| 42 | + exit 1 |
| 43 | + elif [[ "$1" == "" ]]; then |
| 44 | + echo "autoFixElfFiles: empty fix action" >&2 |
| 45 | + exit 1 |
| 46 | + else |
| 47 | + fixAction="$1" |
| 48 | + fi |
| 49 | + |
| 50 | + mapfile -t outputPaths < <(for o in $(getAllOutputNames); do echo "${!o}"; done) |
| 51 | + |
| 52 | + find "${outputPaths[@]}" -type f -print0 | while IFS= read -rd "" f; do |
| 53 | + if ! isELF "$f"; then |
| 54 | + continue |
| 55 | + elif elfHasDynamicSection "$f"; then |
| 56 | + # patchelf returns an error on statically linked ELF files, and in |
| 57 | + # practice fixing actions all involve patchelf |
| 58 | + echo "autoFixElfFiles: using $fixAction to fix $f" >&2 |
| 59 | + $fixAction "$f" |
| 60 | + elif (( "${NIX_DEBUG:-0}" >= 1 )); then |
| 61 | + echo "autoFixElfFiles: skipping a statically-linked ELF file $f" |
| 62 | + fi |
| 63 | + done |
| 64 | +} |
0 commit comments