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