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