diff options
Diffstat (limited to 'pkgs/development/cuda-modules/setup-hooks')
5 files changed, 119 insertions, 55 deletions
diff --git a/pkgs/development/cuda-modules/setup-hooks/auto-add-cuda-compat-runpath.sh b/pkgs/development/cuda-modules/setup-hooks/auto-add-cuda-compat-runpath.sh index ae25cebaca6f..fc41024f1551 100644 --- a/pkgs/development/cuda-modules/setup-hooks/auto-add-cuda-compat-runpath.sh +++ b/pkgs/development/cuda-modules/setup-hooks/auto-add-cuda-compat-runpath.sh @@ -3,25 +3,25 @@ # coming from the cuda_compat package by adding it to the RUNPATH. echo "Sourcing auto-add-cuda-compat-runpath-hook" -elfHasDynamicSection() { - patchelf --print-rpath "$1" >& /dev/null -} +addCudaCompatRunpath() { + local libPath + local origRpath + + if [[ $# -eq 0 ]]; then + echo "addCudaCompatRunpath: no library path provided" >&2 + exit 1 + elif [[ $# -gt 1 ]]; then + echo "addCudaCompatRunpath: too many arguments" >&2 + exit 1 + elif [[ "$1" == "" ]]; then + echo "addCudaCompatRunpath: empty library path" >&2 + exit 1 + else + libPath="$1" + fi -autoAddCudaCompatRunpathPhase() ( - local outputPaths - mapfile -t outputPaths < <(for o in $(getAllOutputNames); do echo "${!o}"; done) - find "${outputPaths[@]}" -type f -print0 | while IFS= read -rd "" f; do - if isELF "$f"; then - # patchelf returns an error on statically linked ELF files - if elfHasDynamicSection "$f" ; then - echo "autoAddCudaCompatRunpathHook: patching $f" - local origRpath="$(patchelf --print-rpath "$f")" - patchelf --set-rpath "@libcudaPath@:$origRpath" "$f" - elif (( "${NIX_DEBUG:-0}" >= 1 )) ; then - echo "autoAddCudaCompatRunpathHook: skipping a statically-linked ELF file $f" - fi - fi - done -) + origRpath="$(patchelf --print-rpath "$libPath")" + patchelf --set-rpath "@libcudaPath@:$origRpath" "$libPath" +} -postFixupHooks+=(autoAddCudaCompatRunpathPhase) +postFixupHooks+=("autoFixElfFiles addCudaCompatRunpath") diff --git a/pkgs/development/cuda-modules/setup-hooks/auto-add-driver-runpath-hook.sh b/pkgs/development/cuda-modules/setup-hooks/auto-add-driver-runpath-hook.sh new file mode 100644 index 000000000000..ecff2a032d64 --- /dev/null +++ b/pkgs/development/cuda-modules/setup-hooks/auto-add-driver-runpath-hook.sh @@ -0,0 +1,8 @@ +# shellcheck shell=bash +# Run addDriverRunpath on all dynamically linked ELF files +echo "Sourcing auto-add-driver-runpath-hook" + +if [ -z "${dontUseAutoAddDriverRunpath-}" ]; then + echo "Using autoAddDriverRunpath" + postFixupHooks+=("autoFixElfFiles addDriverRunpath") +fi diff --git a/pkgs/development/cuda-modules/setup-hooks/auto-add-opengl-runpath-hook.sh b/pkgs/development/cuda-modules/setup-hooks/auto-add-opengl-runpath-hook.sh deleted file mode 100644 index a6eeef7c7699..000000000000 --- a/pkgs/development/cuda-modules/setup-hooks/auto-add-opengl-runpath-hook.sh +++ /dev/null @@ -1,28 +0,0 @@ -# shellcheck shell=bash -# Run addOpenGLRunpath on all dynamically linked, ELF files -echo "Sourcing auto-add-opengl-runpath-hook" - -elfHasDynamicSection() { - patchelf --print-rpath "$1" >& /dev/null -} - -autoAddOpenGLRunpathPhase() ( - local outputPaths - mapfile -t outputPaths < <(for o in $(getAllOutputNames); do echo "${!o}"; done) - find "${outputPaths[@]}" -type f -print0 | while IFS= read -rd "" f; do - if isELF "$f"; then - # patchelf returns an error on statically linked ELF files - if elfHasDynamicSection "$f" ; then - echo "autoAddOpenGLRunpathHook: patching $f" - addOpenGLRunpath "$f" - elif (( "${NIX_DEBUG:-0}" >= 1 )) ; then - echo "autoAddOpenGLRunpathHook: skipping a statically-linked ELF file $f" - fi - fi - done -) - -if [ -z "${dontUseAutoAddOpenGLRunpath-}" ]; then - echo "Using autoAddOpenGLRunpathPhase" - postFixupHooks+=(autoAddOpenGLRunpathPhase) -fi diff --git a/pkgs/development/cuda-modules/setup-hooks/auto-fix-elf-files.sh b/pkgs/development/cuda-modules/setup-hooks/auto-fix-elf-files.sh new file mode 100644 index 000000000000..1d57dfb17a66 --- /dev/null +++ b/pkgs/development/cuda-modules/setup-hooks/auto-fix-elf-files.sh @@ -0,0 +1,64 @@ +# shellcheck shell=bash +# List all dynamically linked ELF files in the outputs and apply a generic fix +# action provided as a parameter (currently used to add the CUDA or the +# cuda_compat driver to the runpath of binaries) +echo "Sourcing cuda/fix-elf-files.sh" + +# Returns the exit code of patchelf --print-rpath. +# A return code of 0 (success) means the ELF file has a dynamic section, while +# a non-zero return code means the ELF file is statically linked (or is not an +# ELF file). +elfHasDynamicSection() { + local libPath + + if [[ $# -eq 0 ]]; then + echo "elfHasDynamicSection: no library path provided" >&2 + exit 1 + elif [[ $# -gt 1 ]]; then + echo "elfHasDynamicSection: too many arguments" >&2 + exit 1 + elif [[ "$1" == "" ]]; then + echo "elfHasDynamicSection: empty library path" >&2 + exit 1 + else + libPath="$1" + shift 1 + fi + + patchelf --print-rpath "$libPath" >& /dev/null + return $? +} + +# Run a fix action on all dynamically linked ELF files in the outputs. +autoFixElfFiles() { + local fixAction + local outputPaths + + if [[ $# -eq 0 ]]; then + echo "autoFixElfFiles: no fix action provided" >&2 + exit 1 + elif [[ $# -gt 1 ]]; then + echo "autoFixElfFiles: too many arguments" >&2 + exit 1 + elif [[ "$1" == "" ]]; then + echo "autoFixElfFiles: empty fix action" >&2 + exit 1 + else + fixAction="$1" + fi + + mapfile -t outputPaths < <(for o in $(getAllOutputNames); do echo "${!o}"; done) + + find "${outputPaths[@]}" -type f -print0 | while IFS= read -rd "" f; do + if ! isELF "$f"; then + continue + elif elfHasDynamicSection "$f"; then + # patchelf returns an error on statically linked ELF files, and in + # practice fixing actions all involve patchelf + echo "autoFixElfFiles: using $fixAction to fix $f" >&2 + $fixAction "$f" + elif (( "${NIX_DEBUG:-0}" >= 1 )); then + echo "autoFixElfFiles: skipping a statically-linked ELF file $f" + fi + done +} diff --git a/pkgs/development/cuda-modules/setup-hooks/extension.nix b/pkgs/development/cuda-modules/setup-hooks/extension.nix index 9e352bd5b3af..ece70da52b02 100644 --- a/pkgs/development/cuda-modules/setup-hooks/extension.nix +++ b/pkgs/development/cuda-modules/setup-hooks/extension.nix @@ -1,4 +1,19 @@ final: _: { + # Helper hook used in both autoAddCudaCompatRunpath and + # autoAddDriverRunpath that applies a generic patching action to all elf + # files with a dynamic linking section. + autoFixElfFiles = + final.callPackage + ( + {makeSetupHook}: + makeSetupHook + { + name = "auto-fix-elf-files"; + } + ./auto-fix-elf-files.sh + ) + {}; + # Internal hook, used by cudatoolkit and cuda redist packages # to accommodate automatic CUDAToolkit_ROOT construction markForCudatoolkitRootHook = @@ -32,31 +47,36 @@ final: _: { {} ); - autoAddOpenGLRunpathHook = + autoAddDriverRunpath = final.callPackage ( - {addOpenGLRunpath, makeSetupHook}: + {addDriverRunpath, autoFixElfFiles, makeSetupHook}: makeSetupHook { name = "auto-add-opengl-runpath-hook"; - propagatedBuildInputs = [addOpenGLRunpath]; + propagatedBuildInputs = [addDriverRunpath autoFixElfFiles]; } - ./auto-add-opengl-runpath-hook.sh + ./auto-add-driver-runpath-hook.sh ) {}; - # autoAddCudaCompatRunpathHook hook must be added AFTER `setupCudaHook`. Both + # Deprecated: an alias kept for compatibility. Consider removing after 24.11 + autoAddOpenGLRunpathHook = final.autoAddDriverRunpath; + + # autoAddCudaCompatRunpath hook must be added AFTER `setupCudaHook`. Both # hooks prepend a path with `libcuda.so` to the `DT_RUNPATH` section of # patched elf files, but `cuda_compat` path must take precedence (otherwise, # it doesn't have any effect) and thus appear first. Meaning this hook must be # executed last. - autoAddCudaCompatRunpathHook = + autoAddCudaCompatRunpath = final.callPackage ( - {makeSetupHook, cuda_compat ? null }: + {makeSetupHook, autoFixElfFiles, cuda_compat ? null }: makeSetupHook { name = "auto-add-cuda-compat-runpath-hook"; + propagatedBuildInputs = [autoFixElfFiles]; + substitutions = { # Hotfix Ofborg evaluation libcudaPath = if final.flags.isJetsonBuild then "${cuda_compat}/compat" else null; |