···
7
-
inherit (lib) attrsets lists strings;
8
-
# cudaVersionOlder : Version -> Boolean
9
-
cudaVersionOlder = strings.versionOlder cudaVersion;
10
-
# cudaVersionAtLeast : Version -> Boolean
11
-
cudaVersionAtLeast = strings.versionAtLeast cudaVersion;
2
+
filterAndCreateOverrides =
3
+
createOverrideAttrs: final: prev:
5
+
# It is imperative that we use `final.callPackage` to perform overrides,
6
+
# so the final package set is available to the override functions.
7
+
inherit (final) callPackage;
9
+
# NOTE(@connorbaker): We MUST use `lib` from `prev` because the attribute
10
+
# names CAN NOT depend on `final`.
11
+
inherit (prev.lib.attrsets) filterAttrs mapAttrs;
12
+
inherit (prev.lib.trivial) pipe;
15
-
drv.overrideAttrs (prevAttrs: {
16
-
buildInputs = prevAttrs.buildInputs ++ buildInputs;
14
+
# NOTE: Filter out attributes that are not present in the previous version of
15
+
# the package set. This is necessary to prevent the appearance of attributes
16
+
# like `cuda_nvcc` in `cudaPackages_10_0, which predates redistributables.
17
+
filterOutNewAttrs = filterAttrs (name: _: prev ? ${name});
19
+
# Apply callPackage to each attribute value, yielding a value to be passed
21
+
callPackageThenOverrideAttrs = mapAttrs (
22
+
name: value: prev.${name}.overrideAttrs (callPackage value { })
25
+
pipe createOverrideAttrs [
27
+
callPackageThenOverrideAttrs
19
-
# NOTE: Filter out attributes that are not present in the previous version of
20
-
# the package set. This is necessary to prevent the appearance of attributes
21
-
# like `cuda_nvcc` in `cudaPackages_10_0, which predates redistributables.
23
-
attrsets.filterAttrs (attr: _: (builtins.hasAttr attr prev)) {
24
-
libcufile = prev.libcufile.overrideAttrs (prevAttrs: {
25
-
buildInputs = prevAttrs.buildInputs ++ [
28
-
final.pkgs.rdma-core
30
-
# Before 11.7 libcufile depends on itself for some reason.
31
-
autoPatchelfIgnoreMissingDeps =
32
-
prevAttrs.autoPatchelfIgnoreMissingDeps
33
-
++ lists.optionals (cudaVersionOlder "11.7") [ "libcufile.so.0" ];
30
+
# Each attribute name is the name of an existing package in the previous version
31
+
# of the package set.
32
+
# The value is a function (to be provided to callPackage), which yields a value
33
+
# to be provided to overrideAttrs. This allows us to override the attributes of
34
+
# a package without losing access to the fixed point of the package set --
35
+
# especially useful given that some packages may depend on each other!
36
+
filterAndCreateOverrides {
46
+
buildInputs = prevAttrs.buildInputs ++ [
51
+
# Before 11.7 libcufile depends on itself for some reason.
52
+
autoPatchelfIgnoreMissingDeps =
53
+
prevAttrs.autoPatchelfIgnoreMissingDeps
54
+
++ lib.lists.optionals (cudaOlder "11.7") [ "libcufile.so.0" ];
36
-
libcusolver = addBuildInputs prev.libcusolver (
37
-
# Always depends on this
38
-
[ final.libcublas.lib ]
39
-
# Dependency from 12.0 and on
40
-
++ lists.optionals (cudaVersionAtLeast "12.0") [ final.libnvjitlink.lib ]
41
-
# Dependency from 12.1 and on
42
-
++ lists.optionals (cudaVersionAtLeast "12.1") [ final.libcusparse.lib ]
63
+
libnvjitlink ? null,
67
+
prevAttrs.buildInputs
68
+
# Always depends on this
69
+
++ [ libcublas.lib ]
70
+
# Dependency from 12.0 and on
71
+
++ lib.lists.optionals (cudaAtLeast "12.0") [ libnvjitlink.lib ]
72
+
# Dependency from 12.1 and on
73
+
++ lib.lists.optionals (cudaAtLeast "12.1") [ libcusparse.lib ];
75
+
brokenConditions = prevAttrs.brokenConditions // {
76
+
"libnvjitlink missing (CUDA >= 12.0)" =
77
+
!(cudaAtLeast "12.0" -> (libnvjitlink != null && libnvjitlink.lib != null));
78
+
"libcusparse missing (CUDA >= 12.1)" =
79
+
!(cudaAtLeast "12.1" -> (libcusparse != null && libcusparse.lib != null));
87
+
libnvjitlink ? null,
91
+
prevAttrs.buildInputs
92
+
# Dependency from 12.0 and on
93
+
++ lib.lists.optionals (cudaAtLeast "12.0") [ libnvjitlink.lib ];
45
-
libcusparse = addBuildInputs prev.libcusparse (
46
-
lists.optionals (cudaVersionAtLeast "12.0") [ final.libnvjitlink.lib ]
95
+
brokenConditions = prevAttrs.brokenConditions // {
96
+
"libnvjitlink missing (CUDA >= 12.0)" =
97
+
!(cudaAtLeast "12.0" -> (libnvjitlink != null && libnvjitlink.lib != null));
49
-
cuda_cudart = prev.cuda_cudart.overrideAttrs (prevAttrs: {
50
-
# Remove once cuda-find-redist-features has a special case for libcuda
53
-
++ lists.optionals (!(builtins.elem "stubs" prevAttrs.outputs)) [ "stubs" ];
101
+
# TODO(@connorbaker): cuda_cudart.dev depends on crt/host_config.h, which is from
102
+
# cuda_nvcc.dev. It would be nice to be able to encode that.
104
+
{ addDriverRunpath, lib }:
106
+
# Remove once cuda-find-redist-features has a special case for libcuda
109
+
++ lib.lists.optionals (!(builtins.elem "stubs" prevAttrs.outputs)) [ "stubs" ];
55
-
allowFHSReferences = false;
111
+
allowFHSReferences = false;
57
-
# The libcuda stub's pkg-config doesn't follow the general pattern:
59
-
prevAttrs.postPatch or ""
61
-
while IFS= read -r -d $'\0' path ; do
63
-
-e "s|^libdir\s*=.*/lib\$|libdir=''${!outputLib}/lib/stubs|" \
64
-
-e "s|^Libs\s*:\(.*\)\$|Libs: \1 -Wl,-rpath,${addDriverRunpath.driverLink}/lib|" \
66
-
done < <(find -iname 'cuda-*.pc' -print0)
113
+
# The libcuda stub's pkg-config doesn't follow the general pattern:
115
+
prevAttrs.postPatch or ""
117
+
while IFS= read -r -d $'\0' path; do
119
+
-e "s|^libdir\s*=.*/lib\$|libdir=''${!outputLib}/lib/stubs|" \
120
+
-e "s|^Libs\s*:\(.*\)\$|Libs: \1 -Wl,-rpath,${addDriverRunpath.driverLink}/lib|" \
122
+
done < <(find -iname 'cuda-*.pc' -print0)
# Namelink may not be enough, add a soname.
# Cf. https://gitlab.kitware.com/cmake/cmake/-/issues/25536
71
-
if [[ -f lib/stubs/libcuda.so && ! -f lib/stubs/libcuda.so.1 ]] ; then
72
-
ln -s libcuda.so lib/stubs/libcuda.so.1
77
-
prevAttrs.postFixup or ""
79
-
moveToOutput lib/stubs "$stubs"
80
-
ln -s "$stubs"/lib/stubs/* "$stubs"/lib/
81
-
ln -s "$stubs"/lib/stubs "''${!outputLib}/lib/stubs"
127
+
if [[ -f lib/stubs/libcuda.so && ! -f lib/stubs/libcuda.so.1 ]]; then
128
+
ln -s libcuda.so lib/stubs/libcuda.so.1
85
-
cuda_compat = prev.cuda_compat.overrideAttrs (prevAttrs: {
86
-
autoPatchelfIgnoreMissingDeps = prevAttrs.autoPatchelfIgnoreMissingDeps ++ [
89
-
"libnvdla_runtime.so"
91
-
# `cuda_compat` only works on aarch64-linux, and only when building for Jetson devices.
92
-
badPlatformsConditions = prevAttrs.badPlatformsConditions // {
93
-
"Trying to use cuda_compat on aarch64-linux targeting non-Jetson devices" =
94
-
!final.flags.isJetsonBuild;
133
+
prevAttrs.postFixup or ""
135
+
moveToOutput lib/stubs "$stubs"
136
+
ln -s "$stubs"/lib/stubs/* "$stubs"/lib/
137
+
ln -s "$stubs"/lib/stubs "''${!outputLib}/lib/stubs"
98
-
cuda_gdb = addBuildInputs prev.cuda_gdb (
99
-
# x86_64 only needs gmp from 12.0 and on
100
-
lists.optionals (cudaVersionAtLeast "12.0") [ final.pkgs.gmp ]
103
-
cuda_nvcc = prev.cuda_nvcc.overrideAttrs (
106
-
# This replicates the logic in stdenvAdapters.useLibsFrom, except we use
107
-
# gcc from pkgsHostTarget and not from buildPackages.
108
-
ccForLibs-wrapper = final.pkgs.stdenv.cc;
109
-
gccMajorVersion = final.nvccCompatibilities.${cudaVersion}.gccMaxMajorVersion;
110
-
cc = final.pkgs.wrapCCWith {
111
-
cc = final.pkgs."gcc${gccMajorVersion}".cc;
112
-
useCcForLibs = true;
113
-
gccForLibs = ccForLibs-wrapper.cc;
144
+
autoPatchelfIgnoreMissingDeps = prevAttrs.autoPatchelfIgnoreMissingDeps ++ [
147
+
"libnvdla_runtime.so"
149
+
# `cuda_compat` only works on aarch64-linux, and only when building for Jetson devices.
150
+
badPlatformsConditions = prevAttrs.badPlatformsConditions // {
151
+
"Trying to use cuda_compat on aarch64-linux targeting non-Jetson devices" = !flags.isJetsonBuild;
163
+
prevAttrs.buildInputs
164
+
# x86_64 only needs gmp from 12.0 and on
165
+
++ lib.lists.optionals (cudaAtLeast "12.0") [ gmp ];
118
-
outputs = oldAttrs.outputs ++ lists.optionals (!(builtins.elem "lib" oldAttrs.outputs)) [ "lib" ];
# Patch the nvcc.profile.
···
134
-
(oldAttrs.postPatch or "")
190
+
(prevAttrs.postPatch or "")
substituteInPlace bin/nvcc.profile \
139
-
"''${!outputLib}/lib" \
'$(TOP)/$(_NVVM_BRANCH_)' \
···
cat << EOF >> bin/nvcc.profile
# Fix a compatible backend compiler
150
-
PATH += ${lib.getBin cc}/bin:
203
+
PATH += "${backendStdenv.cc}/bin":
# Expose the split-out nvvm
153
-
LIBRARIES =+ -L''${!outputBin}/nvvm/lib
154
-
INCLUDES =+ -I''${!outputBin}/nvvm/include
156
-
# Expose cudart and the libcuda stubs
157
-
LIBRARIES =+ -L$static/lib" "-L${final.cuda_cudart.lib}/lib -L${final.cuda_cudart.lib}/lib/stubs
158
-
INCLUDES =+ -I${final.cuda_cudart.dev}/include
206
+
LIBRARIES =+ "-L''${!outputBin}/nvvm/lib"
207
+
INCLUDES =+ "-I''${!outputBin}/nvvm/include"
162
-
propagatedBuildInputs = [ final.setupCudaHook ];
211
+
# NOTE(@connorbaker):
212
+
# Though it might seem odd or counter-intuitive to add the setup hook to `propagatedBuildInputs` instead of
213
+
# `propagatedNativeBuildInputs`, it is necessary! If you move the setup hook from `propagatedBuildInputs` to
214
+
# `propagatedNativeBuildInputs`, it stops being propagated to downstream packages during their build because
215
+
# setup hooks in `propagatedNativeBuildInputs` are not designed to affect the runtime or build environment of
216
+
# dependencies; they are only meant to affect the build environment of the package that directly includes them.
217
+
propagatedBuildInputs = (prevAttrs.propagatedBuildInputs or [ ]) ++ [ setupCudaHook ];
165
-
(oldAttrs.postInstall or "")
220
+
(prevAttrs.postInstall or "")
moveToOutput "nvvm" "''${!outputBin}"
···
# The nvcc and cicc binaries contain hard-coded references to /usr
allowFHSReferences = true;
173
-
meta = (oldAttrs.meta or { }) // {
228
+
meta = (prevAttrs.meta or { }) // {
179
-
cuda_nvprof = prev.cuda_nvprof.overrideAttrs (prevAttrs: {
180
-
buildInputs = prevAttrs.buildInputs ++ [ final.cuda_cupti.lib ];
234
+
{ cuda_cupti }: prevAttrs: { buildInputs = prevAttrs.buildInputs ++ [ cuda_cupti.lib ]; };
183
-
cuda_demo_suite = addBuildInputs prev.cuda_demo_suite [
184
-
final.pkgs.freeglut
186
-
final.pkgs.libglvnd
189
-
final.libcurand.lib
246
+
buildInputs = prevAttrs.buildInputs ++ [
192
-
nsight_compute = prev.nsight_compute.overrideAttrs (prevAttrs: {
193
-
nativeBuildInputs =
194
-
prevAttrs.nativeBuildInputs
196
-
if (strings.versionOlder prev.nsight_compute.version "2022.2.0") then
197
-
[ final.pkgs.qt5.wrapQtAppsHook ]
199
-
[ final.pkgs.qt6.wrapQtAppsHook ]
202
-
prevAttrs.buildInputs
204
-
if (strings.versionOlder prev.nsight_compute.version "2022.2.0") then
205
-
[ final.pkgs.qt5.qtwebview ]
207
-
[ final.pkgs.qt6.qtwebview ]
264
+
inherit (lib.strings) versionOlder versionAtLeast;
265
+
inherit (prevAttrs) version;
266
+
qt = if versionOlder version "2022.2.0" then qt5 else qt6;
267
+
inherit (qt) wrapQtAppsHook qtwebview;
270
+
nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ wrapQtAppsHook ];
271
+
buildInputs = prevAttrs.buildInputs ++ [ qtwebview ];
272
+
brokenConditions = prevAttrs.brokenConditions // {
273
+
"Qt 5 missing (<2022.2.0)" = !(versionOlder version "2022.2.0" -> qt5 != null);
274
+
"Qt 6 missing (>=2022.2.0)" = !(versionAtLeast version "2022.2.0" -> qt6 != null);
211
-
nsight_systems = prev.nsight_systems.overrideAttrs (
214
-
qt = if lib.versionOlder prevAttrs.version "2022.4.2.1" then final.pkgs.qt5 else final.pkgs.qt6;
296
+
inherit (lib.strings) versionOlder versionAtLeast;
297
+
inherit (prevAttrs) version;
298
+
qt = if lib.strings.versionOlder prevAttrs.version "2022.4.2.1" then qt5 else qt6;
if lib.versions.major qt.qtbase.version == "5" then
···
# An ad hoc replacement for
# https://github.com/ConnorBaker/cuda-redist-find-features/issues/11
env.rmPatterns = toString [
310
+
"nsight-systems/*/*/lib{arrow,jpeg}*"
311
+
"nsight-systems/*/*/lib{ssl,ssh,crypto}*"
312
+
"nsight-systems/*/*/libboost*"
313
+
"nsight-systems/*/*/libexec"
"nsight-systems/*/*/libQt*"
"nsight-systems/*/*/libstdc*"
228
-
"nsight-systems/*/*/libboost*"
229
-
"nsight-systems/*/*/lib{ssl,ssh,crypto}*"
230
-
"nsight-systems/*/*/lib{arrow,jpeg}*"
"nsight-systems/*/*/Mesa"
317
+
"nsight-systems/*/*/Plugins"
"nsight-systems/*/*/python/bin/python"
233
-
"nsight-systems/*/*/libexec"
234
-
"nsight-systems/*/*/Plugins"
prevAttrs.postPatch or ""
239
-
for path in $rmPatterns ; do
323
+
for path in $rmPatterns; do
nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ qt.wrapQtAppsHook ];
buildInputs = prevAttrs.buildInputs ++ [
245
-
final.cuda_cudart.stubs
246
-
final.pkgs.alsa-lib
247
-
final.pkgs.boost178
248
-
final.pkgs.e2fsprogs
249
-
final.pkgs.gst_all_1.gst-plugins-base
250
-
final.pkgs.gst_all_1.gstreamer
253
-
final.pkgs.pulseaudio
254
-
final.pkgs.rdma-core
257
-
final.pkgs.xorg.libXcursor
258
-
final.pkgs.xorg.libXdamage
259
-
final.pkgs.xorg.libXrandr
260
-
final.pkgs.xorg.libXtst
(qt.qtdeclarative or qt.full)
332
+
gst_all_1.gst-plugins-base
333
+
gst_all_1.gstreamer
267
-
# Older releases require boost 1.70 deprecated in Nixpkgs
268
-
meta.broken = prevAttrs.meta.broken or false || lib.versionOlder final.cudaVersion "11.8";
348
+
brokenConditions = prevAttrs.brokenConditions // {
349
+
# Older releases require boost 1.70, which is deprecated in Nixpkgs
350
+
"CUDA too old (<11.8)" = cudaOlder "11.8";
351
+
"Qt 5 missing (<2022.4.2.1)" = !(versionOlder version "2022.4.2.1" -> qt5 != null);
352
+
"Qt 6 missing (>=2022.4.2.1)" = !(versionAtLeast version "2022.4.2.1" -> qt6 != null);
272
-
nvidia_driver = prev.nvidia_driver.overrideAttrs {
273
-
# No need to support this package as we have drivers already
274
-
# in linuxPackages.
275
-
meta.broken = true;
359
+
brokenConditions = prevAttrs.brokenConditions // {
360
+
"Package is not supported; use drivers from linuxPackages" = true;