1{
2 cudaMajorMinorVersion,
3 runPatches ? [ ],
4 autoPatchelfHook,
5 autoAddDriverRunpath,
6 addDriverRunpath,
7 alsa-lib,
8 curlMinimal,
9 expat,
10 fetchurl,
11 fontconfig,
12 freetype,
13 gdk-pixbuf,
14 glib,
15 glibc,
16 gst_all_1,
17 gtk2,
18 lib,
19 libxcrypt-legacy,
20 libxkbcommon,
21 libkrb5,
22 krb5,
23 makeWrapper,
24 markForCudatoolkitRootHook,
25 ncurses5,
26 ncurses6,
27 numactl,
28 nss,
29 patchelf,
30 perl,
31 python3, # FIXME: CUDAToolkit 10 may still need python27
32 python310,
33 python311,
34 pulseaudio,
35 setupCudaHook,
36 stdenv,
37 backendStdenv, # E.g. gcc11Stdenv, set in extension.nix
38 unixODBC,
39 wayland,
40 xorg,
41 zlib,
42 libglut,
43 libGLU,
44 libsForQt5,
45 libtiff,
46 qt6Packages,
47 qt6,
48 rdma-core,
49 ucx,
50 rsync,
51 libglvnd,
52}:
53
54let
55 # Version info for the classic cudatoolkit packages that contain everything that is in redist.
56 releases = builtins.import ./releases.nix;
57 release = releases.${cudaMajorMinorVersion};
58in
59
60backendStdenv.mkDerivation rec {
61 pname = "cudatoolkit";
62 inherit (release) version;
63 inherit runPatches;
64
65 dontPatchELF = true;
66 dontStrip = true;
67
68 src = fetchurl { inherit (release) url sha256; };
69
70 outputs = [
71 "out"
72 "lib"
73 "doc"
74 ];
75
76 nativeBuildInputs = [
77 perl
78 makeWrapper
79 rsync
80 addDriverRunpath
81 autoPatchelfHook
82 autoAddDriverRunpath
83 markForCudatoolkitRootHook
84 ] ++ lib.optionals (lib.versionAtLeast version "11.8") [ qt6Packages.wrapQtAppsHook ];
85 propagatedBuildInputs = [ setupCudaHook ];
86 buildInputs =
87 [
88 # To get $GDK_PIXBUF_MODULE_FILE via setup-hook
89 gdk-pixbuf
90
91 # For autoPatchelf
92 ncurses5
93 expat
94 python3
95 zlib
96 glibc
97 xorg.libX11
98 xorg.libXext
99 xorg.libXrender
100 xorg.libXt
101 xorg.libXtst
102 xorg.libXi
103 xorg.libXext
104 xorg.libXdamage
105 xorg.libxcb
106 xorg.xcbutilimage
107 xorg.xcbutilrenderutil
108 xorg.xcbutilwm
109 xorg.xcbutilkeysyms
110 pulseaudio
111 libxkbcommon
112 libkrb5
113 krb5
114 gtk2
115 glib
116 fontconfig
117 freetype
118 numactl
119 nss
120 unixODBC
121 alsa-lib
122 wayland
123 libglvnd
124 ]
125 ++ lib.optionals (lib.versionAtLeast version "11.8") [
126 (lib.getLib libtiff)
127 qt6Packages.qtwayland
128 rdma-core
129 (ucx.override { enableCuda = false; }) # Avoid infinite recursion
130 xorg.libxshmfence
131 xorg.libxkbfile
132 ]
133 ++ (lib.optionals (lib.versionAtLeast version "12") (
134 map lib.getLib ([
135 # Used by `/target-linux-x64/CollectX/clx` and `/target-linux-x64/CollectX/libclx_api.so` for:
136 # - `libcurl.so.4`
137 curlMinimal
138
139 # Used by `/host-linux-x64/Scripts/WebRTCContainer/setup/neko/server/bin/neko`
140 gst_all_1.gstreamer
141 gst_all_1.gst-plugins-base
142 ])
143 ++ (with qt6; [
144 qtmultimedia
145 qttools
146 qtpositioning
147 qtscxml
148 qtsvg
149 qtwebchannel
150 qtwebengine
151 ])
152 ))
153 ++ lib.optionals (lib.versionAtLeast version "12.6") [
154 # libcrypt.so.1
155 libxcrypt-legacy
156 ncurses6
157 python310
158 python311
159 ];
160
161 # Prepended to runpaths by autoPatchelf.
162 # The order inherited from older rpath preFixup code
163 runtimeDependencies = [
164 (placeholder "lib")
165 (placeholder "out")
166 "${placeholder "out"}/nvvm"
167 # NOTE: use the same libstdc++ as the rest of nixpkgs, not from backendStdenv
168 "${lib.getLib stdenv.cc.cc}/lib64"
169 "${placeholder "out"}/jre/lib/amd64/jli"
170 "${placeholder "out"}/lib64"
171 "${placeholder "out"}/nvvm/lib64"
172 ];
173
174 autoPatchelfIgnoreMissingDeps = [
175 # This is the hardware-dependent userspace driver that comes from
176 # nvidia_x11 package. It must be deployed at runtime in
177 # /run/opengl-driver/lib or pointed at by LD_LIBRARY_PATH variable, rather
178 # than pinned in runpath
179 "libcuda.so.1"
180
181 # The krb5 expression ships libcom_err.so.3 but cudatoolkit asks for the
182 # older
183 # This dependency is asked for by target-linux-x64/CollectX/RedHat/x86_64/libssl.so.10
184 # - do we even want to use nvidia-shipped libssl?
185 "libcom_err.so.2"
186 ];
187
188 preFixup = ''
189 ${lib.getExe' patchelf "patchelf"} $out/lib64/libnvrtc.so --add-needed libnvrtc-builtins.so
190 '';
191
192 unpackPhase = ''
193 sh $src --keep --noexec
194 '';
195
196 installPhase =
197 ''
198 runHook preInstall
199 mkdir $out
200 mkdir -p $out/bin $out/lib64 $out/include $doc
201 for dir in pkg/builds/* pkg/builds/cuda_nvcc/nvvm pkg/builds/cuda_cupti/extras/CUPTI; do
202 if [ -d $dir/bin ]; then
203 mv $dir/bin/* $out/bin
204 fi
205 if [ -d $dir/doc ]; then
206 (cd $dir/doc && find . -type d -exec mkdir -p $doc/\{} \;)
207 (cd $dir/doc && find . \( -type f -o -type l \) -exec mv \{} $doc/\{} \;)
208 fi
209 if [ -L $dir/include ] || [ -d $dir/include ]; then
210 (cd $dir/include && find . -type d -exec mkdir -p $out/include/\{} \;)
211 (cd $dir/include && find . \( -type f -o -type l \) -exec mv \{} $out/include/\{} \;)
212 fi
213 if [ -L $dir/lib64 ] || [ -d $dir/lib64 ]; then
214 (cd $dir/lib64 && find . -type d -exec mkdir -p $out/lib64/\{} \;)
215 (cd $dir/lib64 && find . \( -type f -o -type l \) -exec mv \{} $out/lib64/\{} \;)
216 fi
217 done
218 mv pkg/builds/cuda_nvcc/nvvm $out/nvvm
219
220 mv pkg/builds/cuda_sanitizer_api $out/cuda_sanitizer_api
221 ln -s $out/cuda_sanitizer_api/compute-sanitizer/compute-sanitizer $out/bin/compute-sanitizer
222
223 mv pkg/builds/nsight_systems/target-linux-x64 $out/target-linux-x64
224 mv pkg/builds/nsight_systems/host-linux-x64 $out/host-linux-x64
225 rm $out/host-linux-x64/libstdc++.so*
226 ${lib.optionalString (lib.versionAtLeast version "11.8" && lib.versionOlder version "12")
227 # error: auto-patchelf could not satisfy dependency libtiff.so.5 wanted by /nix/store/.......-cudatoolkit-12.0.1/host-linux-x64/Plugins/imageformats/libqtiff.so
228 # we only ship libtiff.so.6, so let's use qt plugins built by Nix.
229 # TODO: don't copy, come up with a symlink-based "merge"
230 ''
231 rsync ${lib.getLib qt6Packages.qtimageformats}/lib/qt-6/plugins/ $out/host-linux-x64/Plugins/ -aP
232 ''
233 }
234 ${lib.optionalString (lib.versionAtLeast version "12")
235 # Use Qt plugins built by Nix.
236 ''
237 for qtlib in $out/host-linux-x64/Plugins/*/libq*.so; do
238 qtdir=$(basename $(dirname $qtlib))
239 filename=$(basename $qtlib)
240 for qtpkgdir in ${
241 lib.concatMapStringsSep " " (x: qt6Packages.${x}) [
242 "qtbase"
243 "qtimageformats"
244 "qtsvg"
245 "qtwayland"
246 ]
247 }; do
248 if [ -e $qtpkgdir/lib/qt-6/plugins/$qtdir/$filename ]; then
249 ln -snf $qtpkgdir/lib/qt-6/plugins/$qtdir/$filename $qtlib
250 fi
251 done
252 done
253 ''
254 }
255
256 rm -f $out/tools/CUDA_Occupancy_Calculator.xls # FIXME: why?
257
258 ${lib.optionalString (lib.versionAtLeast version "12.0") ''
259 rm $out/host-linux-x64/libQt6*
260 ''}
261
262 # Fixup path to samples (needed for cuda 6.5 or else nsight will not find them)
263 if [ -d "$out"/cuda-samples ]; then
264 mv "$out"/cuda-samples "$out"/samples
265 fi
266
267 # Change the #error on GCC > 4.9 to a #warning.
268 sed -i $out/include/host_config.h -e 's/#error\(.*unsupported GNU version\)/#warning\1/'
269
270 # Fix builds with newer glibc version
271 sed -i "1 i#define _BITS_FLOATN_H" "$out/include/host_defines.h"
272 ''
273 +
274 # Point NVCC at a compatible compiler
275 # CUDA_TOOLKIT_ROOT_DIR is legacy,
276 # Cf. https://cmake.org/cmake/help/latest/module/FindCUDA.html#input-variables
277 ''
278 mkdir -p $out/nix-support
279 cat <<EOF >> $out/nix-support/setup-hook
280 cmakeFlags+=' -DCUDA_TOOLKIT_ROOT_DIR=$out'
281 EOF
282
283 # Move some libraries to the lib output so that programs that
284 # depend on them don't pull in this entire monstrosity.
285 mkdir -p $lib/lib
286 mv -v $out/lib64/libcudart* $lib/lib/
287
288 # Remove OpenCL libraries as they are provided by ocl-icd and driver.
289 rm -f $out/lib64/libOpenCL*
290
291 # nvprof do not find any program to profile if LD_LIBRARY_PATH is not set
292 wrapProgram $out/bin/nvprof \
293 --prefix LD_LIBRARY_PATH : $out/lib
294 ''
295 # 11.8 includes a broken symlink, include/include, pointing to targets/x86_64-linux/include
296 + lib.optionalString (lib.versions.majorMinor version == "11.8") ''
297 rm $out/include/include
298 ''
299 # Python 3.8 is not in nixpkgs anymore, delete Python 3.8 cuda-gdb support
300 # to avoid autopatchelf failing to find libpython3.8.so.
301 + lib.optionalString (lib.versionAtLeast version "12.6") ''
302 find $out -name '*python3.8*' -delete
303 ''
304 + ''
305 runHook postInstall
306 '';
307
308 postInstall = ''
309 for b in nvvp; do
310 wrapProgram "$out/bin/$b" \
311 --set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE"
312 done
313 ${lib.optionalString (lib.versionAtLeast version "12")
314 # Check we don't have any lurking vendored qt libraries that weren't
315 # replaced during installPhase
316 ''
317 qtlibfiles=$(find $out -name "libq*.so" -type f)
318 if [ ! -z "$qtlibfiles" ]; then
319 echo "Found unexpected vendored Qt library files in $out" >&2
320 echo $qtlibfiles >&2
321 echo "These should be replaced with symlinks in installPhase" >&2
322 exit 1
323 fi
324 ''
325 }
326 '';
327
328 # cuda-gdb doesn't run correctly when not using sandboxing, so
329 # temporarily disabling the install check. This should be set to true
330 # when we figure out how to get `cuda-gdb --version` to run correctly
331 # when not using sandboxing.
332 doInstallCheck = false;
333 postInstallCheck = ''
334 # Smoke test binaries
335 pushd $out/bin
336 for f in *; do
337 case $f in
338 crt) continue;;
339 nvcc.profile) continue;;
340 nsight_ee_plugins_manage.sh) continue;;
341 uninstall_cuda_toolkit_6.5.pl) continue;;
342 computeprof|nvvp|nsight) continue;; # GUIs don't feature "--version"
343 *) echo "Executing '$f --version':"; ./$f --version;;
344 esac
345 done
346 popd
347 '';
348 passthru = {
349 inherit (backendStdenv) cc;
350 majorMinorVersion = lib.versions.majorMinor version;
351 majorVersion = lib.versions.majorMinor version;
352 };
353
354 meta = with lib; {
355 description = "Deprecated runfile-based CUDAToolkit installation (a compiler for NVIDIA GPUs, math libraries, and tools)";
356 homepage = "https://developer.nvidia.com/cuda-toolkit";
357 platforms = [ "x86_64-linux" ];
358 license = licenses.nvidiaCuda;
359 teams = [ teams.cuda ];
360 };
361}