@@ -29,6 +29,12 @@ buildRedistHookRegistration() {
2929
3030 postFixupHooks+=(fixupCudaPropagatedBuildOutputsToOut)
3131 nixLog " added fixupCudaPropagatedBuildOutputsToOut to postFixupHooks"
32+
33+ # NOTE: We need to do this in postFixup since we don't write the dependency on removeStubsFromRunpathHook until
34+ # postFixup -- recall recordPropagatedDependencies happens during fixupPhase.
35+ # NOTE: Iff is shorthand for "if and only if" -- the logical biconditional.
36+ postFixupHooks+=(checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook)
37+ nixLog " added checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook to postFixupHooks"
3238}
3339
3440buildRedistHookRegistration
@@ -140,6 +146,62 @@ checkCudaNonEmptyOutputs() {
140146 return 0
141147}
142148
149+ # Any redistributable providing stubs should set includeRemoveStubsFromRunpathHook to true -- since we don't track the
150+ # contents of the redistributables, it's only included by default if there is a stubs output.
151+ # This check additionally requires that any output which has a stubs directory includes a dependency on
152+ # includeRemoveStubsFromRunpathHook -- that way, if *any* of them are used, the hook is brought in as well.
153+ # Since includeRemoveStubsFromRunpathHook only adds the hook to whatever outputStubs resolves to, having stubs present
154+ # across multiple outputs will result in an error.
155+ checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook () {
156+ local outputName
157+ local -i hasStubs
158+ local -i hasRemoveStubsFromRunpathHook
159+ local -a outputNamesWronglyExcludingHook=()
160+ local -a outputNamesWronglyIncludingHook=()
161+
162+ for outputName in $( getAllOutputNames) ; do
163+ # Record the output if it contains a directory named "stubs" and doesn't include a dependency on
164+ # removeStubsFromRunpathHook.
165+ hasStubs=0
166+ if find " ${! outputName:? } " -mindepth 1 -type d -name stubs -print -quit | grep --silent . ; then
167+ hasStubs=1
168+ fi
169+
170+ hasRemoveStubsFromRunpathHook=0
171+ if
172+ grep --silent --no-messages removeStubsFromRunpathHook " ${! outputName:? } /nix-support/propagated-build-inputs"
173+ then
174+ hasRemoveStubsFromRunpathHook=1
175+ fi
176+
177+ if (( hasStubs && ! hasRemoveStubsFromRunpathHook)) ; then
178+ # Outputs with stubs must include the hook.
179+ outputNamesWronglyExcludingHook+=(" ${outputName:? } " )
180+ elif (( ! hasStubs && hasRemoveStubsFromRunpathHook)) ; then
181+ # Outputs without stubs cannot include the hook.
182+ outputNamesWronglyIncludingHook+=(" ${outputName:? } " )
183+ fi
184+ done
185+
186+ if (( ${# outputNamesWronglyExcludingHook[@]} )) ; then
187+ nixErrorLog " includeRemoveStubsFromRunpathHook is false but we detected outputs containing a stubs" \
188+ " directory: ${outputNamesWronglyExcludingHook[*]} "
189+ nixErrorLog " ensure redistributables providing stubs set includeRemoveStubsFromRunpathHook to true"
190+ fi
191+
192+ if (( ${# outputNamesWronglyIncludingHook[@]} )) ; then
193+ nixErrorLog " includeRemoveStubsFromRunpathHook is true but we detected outputs without a stubs" \
194+ " directory: ${outputNamesWronglyIncludingHook[*]} "
195+ nixErrorLog " ensure redistributables without stubs do not set includeRemoveStubsFromRunpathHook to true"
196+ fi
197+
198+ if (( ${# outputNamesWronglyExcludingHook[@]} || ${# outputNamesWronglyIncludingHook[@]} )) ; then
199+ exit 1
200+ fi
201+
202+ return 0
203+ }
204+
143205# TODO(@connorbaker): https://github.com/NixOS/nixpkgs/issues/323126.
144206# _multioutPropagateDev() currently expects a space-separated string rather than an array.
145207# NOTE: Because _multioutPropagateDev is a postFixup hook, we correct it in preFixup.
0 commit comments