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