nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1# shellcheck shell=bash
2
3if [[ -n ${strictDeps:-} && ${hostOffset:-0} -ne -1 ]]; then
4 nixLog "skipping sourcing buildRedistHook.bash (hostOffset=${hostOffset:-0}) (targetOffset=${targetOffset:-0})"
5 return 0
6fi
7nixLog "sourcing buildRedistHook.bash (hostOffset=${hostOffset:-0}) (targetOffset=${targetOffset:-0})"
8
9buildRedistHookRegistration() {
10 postUnpackHooks+=(unpackCudaLibSubdir)
11 nixLog "added unpackCudaLibSubdir to postUnpackHooks"
12
13 postUnpackHooks+=(unpackCudaPkgConfigDirs)
14 nixLog "added unpackCudaPkgConfigDirs to postUnpackHooks"
15
16 prePatchHooks+=(patchCudaPkgConfig)
17 nixLog "added patchCudaPkgConfig to prePatchHooks"
18
19 if [[ -z ${allowFHSReferences-} ]]; then
20 postInstallCheckHooks+=(checkCudaFhsRefs)
21 nixLog "added checkCudaFhsRefs to postInstallCheckHooks"
22 fi
23
24 postInstallCheckHooks+=(checkCudaNonEmptyOutputs)
25 nixLog "added checkCudaNonEmptyOutputs to postInstallCheckHooks"
26
27 preFixupHooks+=(fixupPropagatedBuildOutputsForMultipleOutputs)
28 nixLog "added fixupPropagatedBuildOutputsForMultipleOutputs to preFixupHooks"
29
30 postFixupHooks+=(fixupCudaPropagatedBuildOutputsToOut)
31 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"
38}
39
40buildRedistHookRegistration
41
42unpackCudaLibSubdir() {
43 local -r cudaLibDir="${NIX_BUILD_TOP:?}/${sourceRoot:?}/lib"
44 local -r versionedCudaLibDir="$cudaLibDir/${cudaMajorVersion:?}"
45
46 if [[ ! -d $versionedCudaLibDir ]]; then
47 return 0
48 fi
49
50 nixLog "found versioned CUDA lib dir: $versionedCudaLibDir"
51
52 mv \
53 --verbose \
54 --no-clobber \
55 "$versionedCudaLibDir" \
56 "${cudaLibDir}-new"
57 rm --verbose --recursive "$cudaLibDir" || {
58 nixErrorLog "could not delete $cudaLibDir: $(ls -laR "$cudaLibDir")"
59 exit 1
60 }
61 mv \
62 --verbose \
63 --no-clobber \
64 "${cudaLibDir}-new" \
65 "$cudaLibDir"
66
67 return 0
68}
69
70# Pkg-config's setup hook expects configuration files in $out/share/pkgconfig
71unpackCudaPkgConfigDirs() {
72 local path
73 local -r pkgConfigDir="${NIX_BUILD_TOP:?}/${sourceRoot:?}/share/pkgconfig"
74
75 for path in "${NIX_BUILD_TOP:?}/${sourceRoot:?}"/{pkg-config,pkgconfig}; do
76 [[ -d $path ]] || continue
77 mkdir -p "$pkgConfigDir"
78 mv \
79 --verbose \
80 --no-clobber \
81 --target-directory "$pkgConfigDir" \
82 "$path"/*
83 rm --recursive --dir "$path" || {
84 nixErrorLog "$path contains non-empty directories: $(ls -laR "$path")"
85 exit 1
86 }
87 done
88
89 return 0
90}
91
92patchCudaPkgConfig() {
93 local pc
94
95 for pc in "${NIX_BUILD_TOP:?}/${sourceRoot:?}"/share/pkgconfig/*.pc; do
96 nixLog "patching $pc"
97 sed -i \
98 -e "s|^cudaroot\s*=.*\$|cudaroot=${!outputDev:?}|" \
99 -e "s|^libdir\s*=.*/lib\$|libdir=${!outputLib:?}/lib|" \
100 -e "s|^includedir\s*=.*/include\$|includedir=${!outputInclude:?}/include|" \
101 "$pc"
102 done
103
104 for pc in "${NIX_BUILD_TOP:?}/${sourceRoot:?}"/share/pkgconfig/*-"${cudaMajorMinorVersion:?}.pc"; do
105 nixLog "creating unversioned symlink for $pc"
106 ln -s "$(basename "$pc")" "${pc%-"${cudaMajorMinorVersion:?}".pc}".pc
107 done
108
109 return 0
110}
111
112checkCudaFhsRefs() {
113 nixLog "checking for FHS references..."
114 local -a outputPaths=()
115 local firstMatches
116
117 mapfile -t outputPaths < <(for outputName in $(getAllOutputNames); do echo "${!outputName:?}"; done)
118 firstMatches="$(grep --max-count=5 --recursive --exclude=LICENSE /usr/ "${outputPaths[@]}")" || true
119 if [[ -n $firstMatches ]]; then
120 nixErrorLog "detected references to /usr: $firstMatches"
121 exit 1
122 fi
123
124 return 0
125}
126
127checkCudaNonEmptyOutputs() {
128 local outputName
129 local dirs
130 local -a failingOutputNames=()
131
132 for outputName in $(getAllOutputNames); do
133 # NOTE: Reminder that outputDev is the name of the dev output, so we compare it as-is against outputName rather
134 # than using !outputDev, which would give us the path to the dev output.
135 [[ ${outputName:?} == "out" || ${outputName:?} == "${outputDev:?}" ]] && continue
136 dirs="$(find "${!outputName:?}" -mindepth 1 -maxdepth 1)" || true
137 if [[ -z $dirs || $dirs == "${!outputName:?}/nix-support" ]]; then
138 failingOutputNames+=("${outputName:?}")
139 fi
140 done
141
142 if ((${#failingOutputNames[@]})); then
143 nixErrorLog "detected empty (excluding nix-support) outputs: ${failingOutputNames[*]}"
144 nixErrorLog "this typically indicates a failure in packaging or moveToOutput ordering"
145 exit 1
146 fi
147
148 return 0
149}
150
151checkCudaHasStubsIffIncludeRemoveStubsFromRunpathHook() {
152 local outputName
153 local -i hasStubs
154 local -i hasRemoveStubsFromRunpathHook
155 local -a outputNamesWronglyExcludingHook=()
156 local -a outputNamesWronglyIncludingHook=()
157
158 for outputName in $(getAllOutputNames); do
159 hasStubs=0
160 if [[ $outputName == "stubs" ]] ||
161 find "${!outputName:?}" -mindepth 1 -type d -name stubs -print -quit | grep --silent .; then
162 hasStubs=1
163 fi
164
165 hasRemoveStubsFromRunpathHook=0
166 if grep --silent --no-messages removeStubsFromRunpathHook "${!outputName:?}/nix-support/propagated-build-inputs"; then
167 hasRemoveStubsFromRunpathHook=1
168 fi
169
170 if ((hasStubs && !hasRemoveStubsFromRunpathHook)); then
171 outputNamesWronglyExcludingHook+=("${outputName:?}")
172 elif ((!hasStubs && hasRemoveStubsFromRunpathHook)); then
173 outputNamesWronglyIncludingHook+=("${outputName:?}")
174 fi
175 done
176
177 if ((${#outputNamesWronglyExcludingHook[@]})); then
178 nixErrorLog "we detected outputs containing a stubs directory without a dependency on" \
179 "removeStubsFromRunpathHook: ${outputNamesWronglyExcludingHook[*]}"
180 nixErrorLog "ensure redistributables providing stubs set includeRemoveStubsFromRunpathHook to true"
181 fi
182
183 if ((${#outputNamesWronglyIncludingHook[@]})); then
184 nixErrorLog "we detected outputs without a stubs directory with a dependency on" \
185 "removeStubsFromRunpathHook: ${outputNamesWronglyIncludingHook[*]}"
186 nixErrorLog "ensure redistributables without stubs do not set includeRemoveStubsFromRunpathHook to true"
187 fi
188
189 if ((${#outputNamesWronglyExcludingHook[@]} || ${#outputNamesWronglyIncludingHook[@]})); then
190 exit 1
191 fi
192
193 return 0
194}
195
196# TODO(@connorbaker): https://github.com/NixOS/nixpkgs/issues/323126.
197# _multioutPropagateDev() currently expects a space-separated string rather than an array.
198# NOTE: Because _multioutPropagateDev is a postFixup hook, we correct it in preFixup.
199fixupPropagatedBuildOutputsForMultipleOutputs() {
200 nixLog "converting propagatedBuildOutputs to a space-separated string"
201 # shellcheck disable=SC2124
202 export propagatedBuildOutputs="${propagatedBuildOutputs[@]}"
203 return 0
204}
205
206# The multiple outputs setup hook only propagates build outputs to dev.
207# We want to propagate them to out as well, in case the user interpolates
208# the package into a string -- in such a case, the dev output is not selected
209# and no propagation occurs.
210# NOTE: This must run in postFixup because fixupPhase nukes the propagated dependency files.
211fixupCudaPropagatedBuildOutputsToOut() {
212 local output
213
214 # The `out` output should largely be empty save for nix-support/propagated-build-inputs.
215 # In effect, this allows us to make `out` depend on all the other components.
216 # NOTE: It may have been deleted if it was empty, which is why we must recreate it.
217 mkdir -p "${out:?}/nix-support"
218
219 # NOTE: We must use printWords to ensure the output is a single line.
220 for output in $propagatedBuildOutputs; do
221 # Propagate the other components to the out output
222 nixLog "adding ${!output:?} to propagatedBuildInputs of ${out:?}"
223 printWords "${!output:?}" >>"${out:?}/nix-support/propagated-build-inputs"
224 done
225
226 return 0
227}