From 58d0c43ef829874f8ee25423ea86571045fb96ed Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Sun, 23 Nov 2025 21:43:57 +0000 Subject: [PATCH 01/11] cudaPackages.buildRedist: fix incorrect nameref comparison Signed-off-by: Connor Baker --- .../buildRedist/buildRedistHook.bash | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash index 6ca8f3d19dccf..22e219cf6319d 100644 --- a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash +++ b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash @@ -108,7 +108,7 @@ checkCudaFhsRefs() { local -a outputPaths=() local firstMatches - mapfile -t outputPaths < <(for o in $(getAllOutputNames); do echo "${!o}"; done) + mapfile -t outputPaths < <(for outputName in $(getAllOutputNames); do echo "${!outputName:?}"; done) firstMatches="$(grep --max-count=5 --recursive --exclude=LICENSE /usr/ "${outputPaths[@]}")" || true if [[ -n $firstMatches ]]; then nixErrorLog "detected references to /usr: $firstMatches" @@ -119,20 +119,22 @@ checkCudaFhsRefs() { } checkCudaNonEmptyOutputs() { - local output + local outputName local dirs - local -a failingOutputs=() - - for output in $(getAllOutputNames); do - [[ ${!output:?} == "out" || ${!output:?} == "${!outputDev:?}" ]] && continue - dirs="$(find "${!output:?}" -mindepth 1 -maxdepth 1)" || true - if [[ -z $dirs || $dirs == "${!output:?}/nix-support" ]]; then - failingOutputs+=("$output") + local -a failingOutputNames=() + + for outputName in $(getAllOutputNames); do + # NOTE: Reminder that outputDev is the name of the dev output, so we compare it as-is against outputName rather + # than using !outputDev, which would give us the path to the dev output. + [[ ${outputName:?} == "out" || ${outputName:?} == "${outputDev:?}" ]] && continue + dirs="$(find "${!outputName:?}" -mindepth 1 -maxdepth 1)" || true + if [[ -z $dirs || $dirs == "${!outputName:?}/nix-support" ]]; then + failingOutputNames+=("${outputName:?}") fi done - if ((${#failingOutputs[@]})); then - nixErrorLog "detected empty (excluding nix-support) outputs: ${failingOutputs[*]}" + if ((${#failingOutputNames[@]})); then + nixErrorLog "detected empty (excluding nix-support) outputs: ${failingOutputNames[*]}" nixErrorLog "this typically indicates a failure in packaging or moveToOutput ordering" exit 1 fi From bd6334ffd2b8eff4a6085fcfdfc1196495bdfd80 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Tue, 25 Nov 2025 01:13:14 +0000 Subject: [PATCH 02/11] cudaPackages.buildRedist: remove unused arguments Signed-off-by: Connor Baker --- pkgs/development/cuda-modules/buildRedist/default.nix | 2 -- pkgs/development/cuda-modules/default.nix | 2 -- 2 files changed, 4 deletions(-) diff --git a/pkgs/development/cuda-modules/buildRedist/default.nix b/pkgs/development/cuda-modules/buildRedist/default.nix index 3cf532859a326..53482ce2bec08 100644 --- a/pkgs/development/cuda-modules/buildRedist/default.nix +++ b/pkgs/development/cuda-modules/buildRedist/default.nix @@ -6,7 +6,6 @@ autoAddDriverRunpath, autoPatchelfHook, backendStdenv, - config, cudaMajorMinorVersion, cudaMajorVersion, cudaNamePrefix, @@ -14,7 +13,6 @@ lib, manifests, markForCudatoolkitRootHook, - setupCudaHook, srcOnly, stdenv, stdenvNoCC, diff --git a/pkgs/development/cuda-modules/default.nix b/pkgs/development/cuda-modules/default.nix index 4e288ab8058a6..2ee63486f237a 100644 --- a/pkgs/development/cuda-modules/default.nix +++ b/pkgs/development/cuda-modules/default.nix @@ -132,7 +132,6 @@ let buildRedist = import ./buildRedist { inherit _cuda - config lib ; inherit (pkgs) @@ -151,7 +150,6 @@ let cudaNamePrefix manifests markForCudatoolkitRootHook - setupCudaHook ; }; From caac26618a611d589842681d007b93f28f44eb3f Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Fri, 7 Nov 2025 09:23:29 +0000 Subject: [PATCH 03/11] arrayUtilities.getRunpathEntries: init Signed-off-by: Connor Baker --- .../getRunpathEntries/getRunpathEntries.bash | 49 +++++++++ .../getRunpathEntries/package.nix | 15 +++ .../getRunpathEntries/tests.nix | 101 ++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/getRunpathEntries.bash create mode 100644 pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/package.nix create mode 100644 pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/tests.nix diff --git a/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/getRunpathEntries.bash b/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/getRunpathEntries.bash new file mode 100644 index 0000000000000..d52291eb5354c --- /dev/null +++ b/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/getRunpathEntries.bash @@ -0,0 +1,49 @@ +# shellcheck shell=bash + +# getRunpathEntries +# Append the runpath entries of the dynamically linked ELF file at path to the indexed array referenced by +# outputArrRef. +# +# NOTE: This function does not check if path is a valid ELF file. +# +# Arguments: +# - path: a path to an ELF file with a dynamic section +# - outputArrRef: a reference to an indexed array (mutated only by appending) +# +# Returns 0 if the file is dynamically linked and the runpath was appended to the output array. +# Returns 1 if patchelf fails (e.g., the ELF file is not dynamically linked, so patchelf fails to print the rpath). +getRunpathEntries() { + if (($# != 2)); then + nixErrorLog "expected two arguments!" + nixErrorLog "usage: getRunpathEntries path outputArrRef" + exit 1 + fi + + local -r path="$1" + local -rn outputArrRef="$2" + + if [[ ! -f $path ]]; then + nixErrorLog "first argument path $path is not a file" + exit 1 + elif ! isDeclaredArray "${!outputArrRef}"; then + nixErrorLog "second argument outputArrRef must be a reference to an indexed array" + exit 1 + fi + + # Declare runpath separately to avoid masking the return value of patchelf. + local runpath + # Files that are not dynamically linked cause patchelf to exit with a non-zero status and print to stderr. + # If patchelf fails to print the rpath, we assume the file is not dynamically linked. + runpath="$(patchelf --print-rpath "$path" 2>/dev/null)" || return 1 + + # If the runpath is empty and we feed it to mapfile, it gives us a singleton array with an empty string. + # We want to avoid that, so we check if the runpath is empty before trying to populate runpathEntries. + local -a runpathEntries=() + if [[ -n $runpath ]]; then + mapfile -d ':' -t runpathEntries < <(echo -n "$runpath") + fi + + outputArrRef+=("${runpathEntries[@]}") + + return 0 +} diff --git a/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/package.nix b/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/package.nix new file mode 100644 index 0000000000000..8214a85052f2b --- /dev/null +++ b/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/package.nix @@ -0,0 +1,15 @@ +{ + callPackages, + isDeclaredArray, + makeSetupHook, + patchelf, +}: +makeSetupHook { + name = "getRunpathEntries"; + propagatedBuildInputs = [ + isDeclaredArray + patchelf + ]; + passthru.tests = callPackages ./tests.nix { }; + meta.description = "Appends runpath entries of a file to an array"; +} ./getRunpathEntries.bash diff --git a/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/tests.nix b/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/tests.nix new file mode 100644 index 0000000000000..d6d84ba5f485e --- /dev/null +++ b/pkgs/build-support/setup-hooks/arrayUtilities/getRunpathEntries/tests.nix @@ -0,0 +1,101 @@ +# NOTE: Tests related to getRunpathEntries go here. +{ + emptyFile, + getRunpathEntries, + hello, + lib, + pkgsStatic, + stdenv, + testers, +}: +let + inherit (lib.attrsets) recurseIntoAttrs; + inherit (testers) + shellcheck + shfmt + testBuildFailure' + testEqualArrayOrMap + ; + + check = + { + name, + elfFile, + runpathEntries, + }: + (testEqualArrayOrMap { + inherit name; + expectedArray = runpathEntries; + script = '' + set -eu + nixLog "running getRunpathEntries with ''${elfFile@Q} to populate actualArray" + getRunpathEntries "$elfFile" actualArray || { + nixErrorLog "getRunpathEntries failed" + exit 1 + } + ''; + }).overrideAttrs + (prevAttrs: { + inherit elfFile; + nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [ getRunpathEntries ]; + meta = prevAttrs.meta or { } // { + platforms = lib.platforms.linux; + }; + }); +in +recurseIntoAttrs { + shellcheck = shellcheck { + name = "getRunpathEntries"; + src = ./getRunpathEntries.bash; + }; + + shfmt = shfmt { + name = "getRunpathEntries"; + src = ./getRunpathEntries.bash; + }; +} +# Only tested on Linux. +// lib.optionalAttrs stdenv.hostPlatform.isLinux { + # Not an ELF file + notElfFileFails = testBuildFailure' { + name = "notElfFileFails"; + drv = check { + name = "notElfFile"; + elfFile = emptyFile; + runpathEntries = [ ]; + }; + expectedBuilderLogEntries = [ + "getRunpathEntries failed" + ]; + }; + + # Not a dynamic ELF file + staticElfFileFails = testBuildFailure' { + name = "staticElfFileFails"; + drv = check { + name = "staticElfFile"; + elfFile = lib.getExe pkgsStatic.hello; + runpathEntries = [ ]; + }; + expectedBuilderLogEntries = [ + "getRunpathEntries failed" + ]; + }; + + hello = check { + name = "hello"; + elfFile = lib.getExe hello; + runpathEntries = [ + "${lib.getLib stdenv.cc.libc}/lib" + ]; + }; + + libstdcplusplus = check { + name = "libstdcplusplus"; + elfFile = "${lib.getLib stdenv.cc.cc}/lib/libstdc++.so"; + runpathEntries = [ + "${lib.getLib stdenv.cc.cc}/lib" + "${lib.getLib stdenv.cc.libc}/lib" + ]; + }; +} From ee1f087ca267ee2f17172db15a2ba59e5b5cb9c2 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Fri, 7 Nov 2025 09:27:03 +0000 Subject: [PATCH 04/11] cudaPackages.removeStubsFromRunpathHook: init Signed-off-by: Connor Baker --- .../removeStubsFromRunpathHook/package.nix | 17 ++++ .../removeStubsFromRunpathHook.bash | 93 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/package.nix create mode 100644 pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash diff --git a/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/package.nix b/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/package.nix new file mode 100644 index 0000000000000..f864f288280a7 --- /dev/null +++ b/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/package.nix @@ -0,0 +1,17 @@ +{ + addDriverRunpath, + arrayUtilities, + autoFixElfFiles, + makeSetupHook, +}: +makeSetupHook { + name = "removeStubsFromRunpathHook"; + propagatedBuildInputs = [ + arrayUtilities.getRunpathEntries + autoFixElfFiles + ]; + + substitutions = { + driverLinkLib = addDriverRunpath.driverLink + "/lib"; + }; +} ./removeStubsFromRunpathHook.bash diff --git a/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash b/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash new file mode 100644 index 0000000000000..da55951fa1ca8 --- /dev/null +++ b/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash @@ -0,0 +1,93 @@ +# shellcheck shell=bash + +# Only run the hook from nativeBuildInputs when strictDeps is set +if [[ -n ${removeStubsFromRunpathHookOnce-} ]]; then + # shellcheck disable=SC2154 + nixDebugLog "skipping sourcing removeStubsFromRunpathHook.bash (hostOffset=$hostOffset) (targetOffset=$targetOffset)" \ + "because it has already been sourced" + return 0 +elif [[ -n ${strictDeps:-} ]] && ! ((hostOffset == -1 && targetOffset == 0)); then + nixDebugLog "skipping sourcing removeStubsFromRunpathHook.bash (hostOffset=$hostOffset) (targetOffset=$targetOffset)" \ + "because it is not in nativeBuildInputs" + return 0 +fi + +declare -g removeStubsFromRunpathHookOnce=1 + +nixLog "sourcing removeStubsFromRunpathHook.bash (hostOffset=$hostOffset) (targetOffset=$targetOffset)" + +# NOTE: Adding to prePhases to ensure all setup hooks are sourced prior to adding our hook. +appendToVar prePhases removeStubsFromRunpathHookRegistration +nixLog "added removeStubsFromRunpathHookRegistration to prePhases" + +# Registering during prePhases ensures that all setup hooks are sourced prior to installing ours, +# allowing us to always go after autoAddDriverRunpath and autoPatchelfHook. +removeStubsFromRunpathHookRegistration() { + local postFixupHook + + for postFixupHook in "${postFixupHooks[@]}"; do + if [[ $postFixupHook == "autoFixElfFiles addDriverRunpath" ]]; then + nixLog "discovered 'autoFixElfFiles addDriverRunpath' in postFixupHooks; this hook should be unnecessary when" \ + "linking against stub files!" + fi + done + + postFixupHooks+=("autoFixElfFiles removeStubsFromRunpath") + nixLog "added removeStubsFromRunpath to postFixupHooks" + + return 0 +} + +removeStubsFromRunpath() { + local libPath + local runpathEntry + local -a origRunpathEntries=() + local -a newRunpathEntries=() + local -r driverLinkLib="@driverLinkLib@" + local -i driverLinkLibSightings=0 + + if [[ $# -eq 0 ]]; then + nixErrorLog "no library path provided" >&2 + exit 1 + elif [[ $# -gt 1 ]]; then + nixErrorLog "too many arguments" >&2 + exit 1 + elif [[ $1 == "" ]]; then + nixErrorLog "empty library path" >&2 + exit 1 + else + libPath="$1" + fi + + getRunpathEntries "$libPath" origRunpathEntries + + # NOTE: Always pre-increment since (( 0 )) sets an exit code of 1. + for runpathEntry in "${origRunpathEntries[@]}"; do + case $runpathEntry in + # NOTE: This assumes all CUDA redistributables with stubs use cudaNamePrefix in name; + # that should be safe given the redistributables are built with buildRedist, which does + # this automatically. + # Match on (sub)directories named stubs or lib inside a stubs output. + *-cuda*/stubs|*-cuda*-stubs/lib*) + if ((driverLinkLibSightings)); then + # No need to add another copy of the driverLinkLib; just drop the stubs entry. + nixDebugLog "dropping $libPath runpath entry: $runpathEntry" + else + # We haven't observed a driverLinkLib yet, so replace the stubs entry with one. + nixDebugLog "replacing $libPath runpath entry: $runpathEntry -> $driverLinkLib" + newRunpathEntries+=("$driverLinkLib") + ((++driverLinkLibSightings)) + fi + ;; + + *) + nixDebugLog "keeping $libPath runpath entry: $runpathEntry" + newRunpathEntries+=("$runpathEntry") + [[ $runpathEntry == "$driverLinkLib" ]] && ((++driverLinkLibSightings)) + ;; + esac + done + + local -r newRunpath=$(concatStringsSep ":" newRunpathEntries) + patchelf --set-rpath "$newRunpath" "$libPath" +} From 9d38d180dba19909a6058a4e16ffa1803536c4d8 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Fri, 7 Nov 2025 07:35:57 +0000 Subject: [PATCH 05/11] cudaPackages.buildRedist: include removeStubsFromRunpathHook Signed-off-by: Connor Baker --- .../buildRedist/buildRedistHook.bash | 55 +++++++++++++++++++ .../cuda-modules/buildRedist/default.nix | 25 ++++++++- pkgs/development/cuda-modules/default.nix | 1 + .../cuda-modules/packages/cuda_cudart.nix | 3 + .../cuda-modules/packages/libnvfatbin.nix | 3 + 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash index 22e219cf6319d..d4393e0ae2340 100644 --- a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash +++ b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash @@ -29,6 +29,12 @@ buildRedistHookRegistration() { postFixupHooks+=(fixupCudaPropagatedBuildOutputsToOut) nixLog "added fixupCudaPropagatedBuildOutputsToOut to postFixupHooks" + + # NOTE: We need to do this in postFixup since we don't write the dependency on removeStubsFromRunpathHook until + # postFixup -- recall recordPropagatedDependencies happens during fixupPhase. + # NOTE: Iff is shorthand for "if and only if" -- the logical biconditional. + postFixupHooks+=(checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook) + nixLog "added checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook to postFixupHooks" } buildRedistHookRegistration @@ -142,6 +148,55 @@ checkCudaNonEmptyOutputs() { return 0 } +checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook() { + local outputName + local -i hasStubs + local -i hasRemoveStubsFromRunpathHook + local -a outputNamesWronglyExcludingHook=() + local -a outputNamesWronglyIncludingHook=() + + for outputName in $(getAllOutputNames); do + hasStubs=0 + if find "${!outputName:?}" -mindepth 1 -type d -name stubs -print -quit | grep --silent .; then + hasStubs=1 + fi + + # The dependency should be recorded in both propagated-native-build-inputs and propagated-build-inputs, so the + # hook is propagated regardless of which dependency array includes the stubs-providing output. + hasRemoveStubsFromRunpathHook=0 + if + grep --silent --no-messages removeStubsFromRunpathHook "${!outputName:?}/nix-support/propagated-native-build-inputs" && + grep --silent --no-messages removeStubsFromRunpathHook "${!outputName:?}/nix-support/propagated-build-inputs" + then + hasRemoveStubsFromRunpathHook=1 + fi + + if ((hasStubs && !hasRemoveStubsFromRunpathHook)); then + outputNamesWronglyExcludingHook+=("${outputName:?}") + elif ((!hasStubs && hasRemoveStubsFromRunpathHook)); then + outputNamesWronglyIncludingHook+=("${outputName:?}") + fi + done + + if ((${#outputNamesWronglyExcludingHook[@]})); then + nixErrorLog "we detected outputs containing a stubs directory without a dependency on" \ + "removeStubsFromRunpathHook: ${outputNamesWronglyExcludingHook[*]}" + nixErrorLog "ensure redistributables providing stubs set includeRemoveStubsFromRunpathHook to true" + fi + + if ((${#outputNamesWronglyIncludingHook[@]})); then + nixErrorLog "we detected outputs without a stubs directory with a dependency on" \ + "removeStubsFromRunpathHook: ${outputNamesWronglyIncludingHook[*]}" + nixErrorLog "ensure redistributables without stubs do not set includeRemoveStubsFromRunpathHook to true" + fi + + if ((${#outputNamesWronglyExcludingHook[@]} || ${#outputNamesWronglyIncludingHook[@]})); then + exit 1 + fi + + return 0 +} + # TODO(@connorbaker): https://github.com/NixOS/nixpkgs/issues/323126. # _multioutPropagateDev() currently expects a space-separated string rather than an array. # NOTE: Because _multioutPropagateDev is a postFixup hook, we correct it in preFixup. diff --git a/pkgs/development/cuda-modules/buildRedist/default.nix b/pkgs/development/cuda-modules/buildRedist/default.nix index 53482ce2bec08..ce9c6a7e7a5a8 100644 --- a/pkgs/development/cuda-modules/buildRedist/default.nix +++ b/pkgs/development/cuda-modules/buildRedist/default.nix @@ -13,6 +13,7 @@ lib, manifests, markForCudatoolkitRootHook, + removeStubsFromRunpathHook, srcOnly, stdenv, stdenvNoCC, @@ -22,6 +23,7 @@ let inherit (_cuda.lib) getNixSystems _mkCudaVariant mkRedistUrl; inherit (lib.attrsets) foldlAttrs + getDev hasAttr isAttrs attrNames @@ -53,6 +55,7 @@ let ; inherit (lib.strings) concatMapStringsSep + optionalString toUpper stringLength substring @@ -136,6 +139,8 @@ extendMkDerivation { # Fixups appendRunpaths ? [ ], + includeRemoveStubsFromRunpathHook ? elem "stubs" finalAttrs.outputs, + postFixup ? "", # Extra passthru ? { }, @@ -199,7 +204,10 @@ extendMkDerivation { outputPython = [ "python" ]; outputSamples = [ "samples" ]; outputStatic = [ "static" ]; - outputStubs = [ "stubs" ]; + outputStubs = [ + "stubs" + "lib" + ]; }, ... }: @@ -264,6 +272,9 @@ extendMkDerivation { # in typically /lib/opengl-driver by adding that # directory to the rpath of all ELF binaries. # Check e.g. with `patchelf --print-rpath path/to/my/binary + # TODO(@connorbaker): Given we'll have stubs available, we can switch from autoPatchelfIgnoreMissingDeps to + # allowing autoPatchelf to find and link against the stub files and rely on removeStubsFromRunpathHook to + # automatically find and replace those references with ones to the driver link lib directory. autoAddDriverRunpath markForCudatoolkitRootHook ] @@ -330,6 +341,18 @@ extendMkDerivation { inherit doInstallCheck; inherit allowFHSReferences; + inherit includeRemoveStubsFromRunpathHook; + + postFixup = + postFixup + + optionalString finalAttrs.includeRemoveStubsFromRunpathHook '' + nixLog "installing stub removal runpath hook" + mkdir -p "''${!outputStubs:?}/nix-support" + printWords >>"''${!outputStubs:?}/nix-support/propagated-native-build-inputs" \ + "${getDev removeStubsFromRunpathHook.__spliced.buildHost or removeStubsFromRunpathHook}" + printWords >>"''${!outputStubs:?}/nix-support/propagated-build-inputs" \ + "${getDev removeStubsFromRunpathHook.__spliced.hostTarget or removeStubsFromRunpathHook}" + ''; passthru = passthru // { inherit redistName release; diff --git a/pkgs/development/cuda-modules/default.nix b/pkgs/development/cuda-modules/default.nix index 2ee63486f237a..734075a502f29 100644 --- a/pkgs/development/cuda-modules/default.nix +++ b/pkgs/development/cuda-modules/default.nix @@ -150,6 +150,7 @@ let cudaNamePrefix manifests markForCudatoolkitRootHook + removeStubsFromRunpathHook ; }; diff --git a/pkgs/development/cuda-modules/packages/cuda_cudart.nix b/pkgs/development/cuda-modules/packages/cuda_cudart.nix index ff647525aad31..364140719d365 100644 --- a/pkgs/development/cuda-modules/packages/cuda_cudart.nix +++ b/pkgs/development/cuda-modules/packages/cuda_cudart.nix @@ -22,6 +22,9 @@ buildRedist (finalAttrs: { "out" ]; + # We have stubs but we don't have an explicit stubs output. + includeRemoveStubsFromRunpathHook = true; + propagatedBuildOutputs = # required by CMake lib.optionals (lib.elem "static" finalAttrs.outputs) [ "static" ] diff --git a/pkgs/development/cuda-modules/packages/libnvfatbin.nix b/pkgs/development/cuda-modules/packages/libnvfatbin.nix index 965bd22d18cb6..612903164650a 100644 --- a/pkgs/development/cuda-modules/packages/libnvfatbin.nix +++ b/pkgs/development/cuda-modules/packages/libnvfatbin.nix @@ -5,6 +5,9 @@ buildRedist { outputs = [ "out" ]; + # Includes stubs. + includeRemoveStubsFromRunpathHook = true; + meta = { description = "APIs which can be used at runtime to combine multiple CUDA objects into one CUDA fat binary (fatbin)"; homepage = "https://docs.nvidia.com/cuda/nvfatbin"; From 85ff7758948c7555bcc6c6d5c2f11057c2569780 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Tue, 25 Nov 2025 19:27:38 +0000 Subject: [PATCH 06/11] cudaPackages.removeStubsFromRunpathHook: remove guard for platform offsets Signed-off-by: Connor Baker --- .../removeStubsFromRunpathHook.bash | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash b/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash index da55951fa1ca8..34a77a2ba43df 100644 --- a/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash +++ b/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash @@ -6,10 +6,6 @@ if [[ -n ${removeStubsFromRunpathHookOnce-} ]]; then nixDebugLog "skipping sourcing removeStubsFromRunpathHook.bash (hostOffset=$hostOffset) (targetOffset=$targetOffset)" \ "because it has already been sourced" return 0 -elif [[ -n ${strictDeps:-} ]] && ! ((hostOffset == -1 && targetOffset == 0)); then - nixDebugLog "skipping sourcing removeStubsFromRunpathHook.bash (hostOffset=$hostOffset) (targetOffset=$targetOffset)" \ - "because it is not in nativeBuildInputs" - return 0 fi declare -g removeStubsFromRunpathHookOnce=1 From 6d9255a8f266f01da399bc75ff79ed55f95834af Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Tue, 25 Nov 2025 19:31:58 +0000 Subject: [PATCH 07/11] cudaPackages.buildRedist: put removeStubsFromRunpathHook in propagated-build-inputs Signed-off-by: Connor Baker --- .../cuda-modules/buildRedist/buildRedistHook.bash | 4 +--- .../development/cuda-modules/buildRedist/default.nix | 12 +++++------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash index d4393e0ae2340..30b5ab5ca1e88 100644 --- a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash +++ b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash @@ -164,9 +164,7 @@ checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook() { # The dependency should be recorded in both propagated-native-build-inputs and propagated-build-inputs, so the # hook is propagated regardless of which dependency array includes the stubs-providing output. hasRemoveStubsFromRunpathHook=0 - if - grep --silent --no-messages removeStubsFromRunpathHook "${!outputName:?}/nix-support/propagated-native-build-inputs" && - grep --silent --no-messages removeStubsFromRunpathHook "${!outputName:?}/nix-support/propagated-build-inputs" + if grep --silent --no-messages removeStubsFromRunpathHook "${!outputName:?}/nix-support/propagated-build-inputs" then hasRemoveStubsFromRunpathHook=1 fi diff --git a/pkgs/development/cuda-modules/buildRedist/default.nix b/pkgs/development/cuda-modules/buildRedist/default.nix index ce9c6a7e7a5a8..831920a57e300 100644 --- a/pkgs/development/cuda-modules/buildRedist/default.nix +++ b/pkgs/development/cuda-modules/buildRedist/default.nix @@ -343,16 +343,14 @@ extendMkDerivation { inherit allowFHSReferences; inherit includeRemoveStubsFromRunpathHook; - postFixup = - postFixup - + optionalString finalAttrs.includeRemoveStubsFromRunpathHook '' + postFixup = postFixup + '' + if [[ -n "''${includeRemoveStubsFromRunpathHook:-}" ]] ; then nixLog "installing stub removal runpath hook" mkdir -p "''${!outputStubs:?}/nix-support" - printWords >>"''${!outputStubs:?}/nix-support/propagated-native-build-inputs" \ - "${getDev removeStubsFromRunpathHook.__spliced.buildHost or removeStubsFromRunpathHook}" printWords >>"''${!outputStubs:?}/nix-support/propagated-build-inputs" \ - "${getDev removeStubsFromRunpathHook.__spliced.hostTarget or removeStubsFromRunpathHook}" - ''; + "${getDev removeStubsFromRunpathHook}" + fi + ''; passthru = passthru // { inherit redistName release; From d2f2407e650cce7d8144324023087d2bda132588 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Tue, 25 Nov 2025 19:39:53 +0000 Subject: [PATCH 08/11] cudaPackages.removeStubsFromRunpathHook: make comment more terse Signed-off-by: Connor Baker --- .../removeStubsFromRunpathHook.bash | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash b/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash index 34a77a2ba43df..56ea1b9bd585e 100644 --- a/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash +++ b/pkgs/development/cuda-modules/packages/removeStubsFromRunpathHook/removeStubsFromRunpathHook.bash @@ -60,9 +60,7 @@ removeStubsFromRunpath() { # NOTE: Always pre-increment since (( 0 )) sets an exit code of 1. for runpathEntry in "${origRunpathEntries[@]}"; do case $runpathEntry in - # NOTE: This assumes all CUDA redistributables with stubs use cudaNamePrefix in name; - # that should be safe given the redistributables are built with buildRedist, which does - # this automatically. + # NOTE: This assumes stubs have "-cuda" (`cudaNamePrefix` in `buildRedist`) in name. # Match on (sub)directories named stubs or lib inside a stubs output. *-cuda*/stubs|*-cuda*-stubs/lib*) if ((driverLinkLibSightings)); then From 413abbfe75a776b3db48510dab358766486ea800 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Wed, 26 Nov 2025 01:26:36 +0000 Subject: [PATCH 09/11] cudaPackages.buildRedist: conditionally depend on removeStubsFromRunpathHook Signed-off-by: Connor Baker --- pkgs/development/cuda-modules/buildRedist/default.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/development/cuda-modules/buildRedist/default.nix b/pkgs/development/cuda-modules/buildRedist/default.nix index 831920a57e300..e04ca914ad9d0 100644 --- a/pkgs/development/cuda-modules/buildRedist/default.nix +++ b/pkgs/development/cuda-modules/buildRedist/default.nix @@ -343,14 +343,14 @@ extendMkDerivation { inherit allowFHSReferences; inherit includeRemoveStubsFromRunpathHook; - postFixup = postFixup + '' - if [[ -n "''${includeRemoveStubsFromRunpathHook:-}" ]] ; then + postFixup = + postFixup + + optionalString finalAttrs.includeRemoveStubsFromRunpathHook '' nixLog "installing stub removal runpath hook" mkdir -p "''${!outputStubs:?}/nix-support" printWords >>"''${!outputStubs:?}/nix-support/propagated-build-inputs" \ "${getDev removeStubsFromRunpathHook}" - fi - ''; + ''; passthru = passthru // { inherit redistName release; From eca21ba0990d1a2cf3c22643bf8eb01944ff4b72 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Wed, 26 Nov 2025 01:28:15 +0000 Subject: [PATCH 10/11] cudaPackages.buildRedist: remove outdated comment and format Signed-off-by: Connor Baker --- .../cuda-modules/buildRedist/buildRedistHook.bash | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash index 30b5ab5ca1e88..afd838df4e31d 100644 --- a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash +++ b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash @@ -161,11 +161,8 @@ checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook() { hasStubs=1 fi - # The dependency should be recorded in both propagated-native-build-inputs and propagated-build-inputs, so the - # hook is propagated regardless of which dependency array includes the stubs-providing output. hasRemoveStubsFromRunpathHook=0 - if grep --silent --no-messages removeStubsFromRunpathHook "${!outputName:?}/nix-support/propagated-build-inputs" - then + if grep --silent --no-messages removeStubsFromRunpathHook "${!outputName:?}/nix-support/propagated-build-inputs"; then hasRemoveStubsFromRunpathHook=1 fi From 4944bbd7ae604d82e48c5f894abe89e67b5d20f5 Mon Sep 17 00:00:00 2001 From: Connor Baker Date: Wed, 26 Nov 2025 01:29:45 +0000 Subject: [PATCH 11/11] cudaPackages.buildRedist: check stubs output for removeStubsFromRunpathHook Signed-off-by: Connor Baker --- pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash index afd838df4e31d..2a2ca6d257a44 100644 --- a/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash +++ b/pkgs/development/cuda-modules/buildRedist/buildRedistHook.bash @@ -157,7 +157,8 @@ checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook() { for outputName in $(getAllOutputNames); do hasStubs=0 - if find "${!outputName:?}" -mindepth 1 -type d -name stubs -print -quit | grep --silent .; then + if [[ $outputName == "stubs" ]] || + find "${!outputName:?}" -mindepth 1 -type d -name stubs -print -quit | grep --silent .; then hasStubs=1 fi