1args@
2{ version
3, sha256
4, url ? ""
5, name ? ""
6, developerProgram ? false
7, runPatches ? []
8, addOpenGLRunpath
9, alsa-lib
10, expat
11, fetchurl
12, fontconfig
13, freetype
14, gcc
15, gdk-pixbuf
16, glib
17, glibc
18, gtk2
19, lib
20, makeWrapper
21, ncurses5
22, perl
23, python27
24, requireFile
25, stdenv
26, unixODBC
27, xorg
28, zlib
29}:
30
31stdenv.mkDerivation rec {
32 pname = "cudatoolkit";
33 inherit version runPatches;
34
35 dontPatchELF = true;
36 dontStrip = true;
37
38 src =
39 if developerProgram then
40 requireFile {
41 message = ''
42 This nix expression requires that ${args.name} is already part of the store.
43 Register yourself to NVIDIA Accelerated Computing Developer Program, retrieve the CUDA toolkit
44 at https://developer.nvidia.com/cuda-toolkit, and run the following command in the download directory:
45 nix-prefetch-url file://\$PWD/${args.name}
46 '';
47 inherit (args) name sha256;
48 }
49 else
50 fetchurl {
51 inherit (args) url sha256;
52 };
53
54 outputs = [ "out" "lib" "doc" ];
55
56 nativeBuildInputs = [ perl makeWrapper addOpenGLRunpath ];
57 buildInputs = [ gdk-pixbuf ]; # To get $GDK_PIXBUF_MODULE_FILE via setup-hook
58 runtimeDependencies = [
59 ncurses5 expat python27 zlib glibc
60 xorg.libX11 xorg.libXext xorg.libXrender xorg.libXt xorg.libXtst xorg.libXi xorg.libXext
61 gtk2 glib fontconfig freetype unixODBC alsa-lib
62 ];
63
64 unpackPhase = ''
65 sh $src --keep --noexec
66
67 ${lib.optionalString (lib.versionOlder version "10.1") ''
68 cd pkg/run_files
69 sh cuda-linux*.run --keep --noexec
70 sh cuda-samples*.run --keep --noexec
71 mv pkg ../../$(basename $src)
72 cd ../..
73 rm -rf pkg
74
75 for patch in $runPatches; do
76 sh $patch --keep --noexec
77 mv pkg $(basename $patch)
78 done
79 ''}
80 '';
81
82 installPhase = ''
83 runHook preInstall
84 mkdir $out
85 ${lib.optionalString (lib.versionOlder version "10.1") ''
86 cd $(basename $src)
87 export PERL5LIB=.
88 perl ./install-linux.pl --prefix="$out"
89 cd ..
90 for patch in $runPatches; do
91 cd $(basename $patch)
92 perl ./install_patch.pl --silent --accept-eula --installdir="$out"
93 cd ..
94 done
95 ''}
96 ${lib.optionalString (lib.versionAtLeast version "10.1" && lib.versionOlder version "11") ''
97 cd pkg/builds/cuda-toolkit
98 mv * $out/
99 ''}
100 ${lib.optionalString (lib.versionAtLeast version "11") ''
101 mkdir -p $out/bin $out/lib64 $out/include $doc
102 for dir in pkg/builds/* pkg/builds/cuda_nvcc/nvvm pkg/builds/cuda_cupti/extras/CUPTI; do
103 if [ -d $dir/bin ]; then
104 mv $dir/bin/* $out/bin
105 fi
106 if [ -d $dir/doc ]; then
107 (cd $dir/doc && find . -type d -exec mkdir -p $doc/\{} \;)
108 (cd $dir/doc && find . \( -type f -o -type l \) -exec mv \{} $doc/\{} \;)
109 fi
110 if [ -L $dir/include ] || [ -d $dir/include ]; then
111 (cd $dir/include && find . -type d -exec mkdir -p $out/include/\{} \;)
112 (cd $dir/include && find . \( -type f -o -type l \) -exec mv \{} $out/include/\{} \;)
113 fi
114 if [ -L $dir/lib64 ] || [ -d $dir/lib64 ]; then
115 (cd $dir/lib64 && find . -type d -exec mkdir -p $out/lib64/\{} \;)
116 (cd $dir/lib64 && find . \( -type f -o -type l \) -exec mv \{} $out/lib64/\{} \;)
117 fi
118 done
119 mv pkg/builds/cuda_nvcc/nvvm $out/nvvm
120
121 mv pkg/builds/cuda_sanitizer_api $out/cuda_sanitizer_api
122 ln -s $out/cuda_sanitizer_api/compute-sanitizer/compute-sanitizer $out/bin/compute-sanitizer
123
124 mv pkg/builds/nsight_systems/target-linux-x64 $out/target-linux-x64
125 mv pkg/builds/nsight_systems/host-linux-x64 $out/host-linux-x64
126 ''}
127
128 rm -f $out/tools/CUDA_Occupancy_Calculator.xls # FIXME: why?
129
130 ${lib.optionalString (lib.versionOlder version "10.1") ''
131 # let's remove the 32-bit libraries, they confuse the lib64->lib mover
132 rm -rf $out/lib
133 ''}
134
135 # Remove some cruft.
136 ${lib.optionalString ((lib.versionAtLeast version "7.0") && (lib.versionOlder version "10.1"))
137 "rm $out/bin/uninstall*"}
138
139 # Fixup path to samples (needed for cuda 6.5 or else nsight will not find them)
140 if [ -d "$out"/cuda-samples ]; then
141 mv "$out"/cuda-samples "$out"/samples
142 fi
143
144 # Change the #error on GCC > 4.9 to a #warning.
145 sed -i $out/include/host_config.h -e 's/#error\(.*unsupported GNU version\)/#warning\1/'
146
147 # Fix builds with newer glibc version
148 sed -i "1 i#define _BITS_FLOATN_H" "$out/include/host_defines.h"
149
150 # Ensure that cmake can find CUDA.
151 mkdir -p $out/nix-support
152 echo "cmakeFlags+=' -DCUDA_TOOLKIT_ROOT_DIR=$out'" >> $out/nix-support/setup-hook
153
154 # Set the host compiler to be used by nvcc for CMake-based projects:
155 # https://cmake.org/cmake/help/latest/module/FindCUDA.html#input-variables
156 echo "cmakeFlags+=' -DCUDA_HOST_COMPILER=${gcc}/bin'" >> $out/nix-support/setup-hook
157
158 # Move some libraries to the lib output so that programs that
159 # depend on them don't pull in this entire monstrosity.
160 mkdir -p $lib/lib
161 mv -v $out/lib64/libcudart* $lib/lib/
162
163 # Remove OpenCL libraries as they are provided by ocl-icd and driver.
164 rm -f $out/lib64/libOpenCL*
165 ${lib.optionalString (lib.versionAtLeast version "10.1" && (lib.versionOlder version "11")) ''
166 mv $out/lib64 $out/lib
167 mv $out/extras/CUPTI/lib64/libcupti* $out/lib
168 ''}
169
170 # Set compiler for NVCC.
171 wrapProgram $out/bin/nvcc \
172 --prefix PATH : ${gcc}/bin
173
174 # nvprof do not find any program to profile if LD_LIBRARY_PATH is not set
175 wrapProgram $out/bin/nvprof \
176 --prefix LD_LIBRARY_PATH : $out/lib
177 '' + lib.optionalString (lib.versionOlder version "8.0") ''
178 # Hack to fix building against recent Glibc/GCC.
179 echo "NIX_CFLAGS_COMPILE+=' -D_FORCE_INLINES'" >> $out/nix-support/setup-hook
180 '' + ''
181 runHook postInstall
182 '';
183
184 postInstall = ''
185 for b in nvvp ${lib.optionalString (lib.versionOlder version "11") "nsight"}; do
186 wrapProgram "$out/bin/$b" \
187 --set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE"
188 done
189 '';
190
191 preFixup =
192 let rpath = lib.concatStringsSep ":" [
193 (lib.makeLibraryPath (runtimeDependencies ++ [ "$lib" "$out" "$out/nvvm" ]))
194 "${stdenv.cc.cc.lib}/lib64"
195 "$out/jre/lib/amd64/jli"
196 "$out/lib64"
197 "$out/nvvm/lib64"
198 ];
199 in
200 ''
201 while IFS= read -r -d $'\0' i; do
202 if ! isELF "$i"; then continue; fi
203 echo "patching $i..."
204 if [[ ! $i =~ \.so ]]; then
205 patchelf \
206 --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $i
207 fi
208 if [[ $i =~ libcudart ]]; then
209 patchelf --remove-rpath $i
210 else
211 patchelf --set-rpath "${rpath}" --force-rpath $i
212 fi
213 done < <(find $out $lib $doc -type f -print0)
214 '' + lib.optionalString (lib.versionAtLeast version "11") ''
215 for file in $out/target-linux-x64/*.so; do
216 echo "patching $file..."
217 patchelf --set-rpath "${rpath}:\$ORIGIN" $file
218 done
219 '';
220
221 # Set RPATH so that libcuda and other libraries in
222 # /run/opengl-driver(-32)/lib can be found. See the explanation in
223 # addOpenGLRunpath. Don't try to figure out which libraries really need
224 # it, just patch all (but not the stubs libraries). Note that
225 # --force-rpath prevents changing RPATH (set above) to RUNPATH.
226 postFixup = ''
227 addOpenGLRunpath --force-rpath {$out,$lib}/lib/lib*.so
228 '' + lib.optionalString (lib.versionAtLeast version "11") ''
229 addOpenGLRunpath $out/cuda_sanitizer_api/compute-sanitizer/*
230 addOpenGLRunpath $out/cuda_sanitizer_api/compute-sanitizer/x86/*
231 addOpenGLRunpath $out/target-linux-x64/*
232 '';
233
234 # cuda-gdb doesn't run correctly when not using sandboxing, so
235 # temporarily disabling the install check. This should be set to true
236 # when we figure out how to get `cuda-gdb --version` to run correctly
237 # when not using sandboxing.
238 doInstallCheck = false;
239 postInstallCheck = let
240 in ''
241 # Smoke test binaries
242 pushd $out/bin
243 for f in *; do
244 case $f in
245 crt) continue;;
246 nvcc.profile) continue;;
247 nsight_ee_plugins_manage.sh) continue;;
248 uninstall_cuda_toolkit_6.5.pl) continue;;
249 computeprof|nvvp|nsight) continue;; # GUIs don't feature "--version"
250 *) echo "Executing '$f --version':"; ./$f --version;;
251 esac
252 done
253 popd
254 '';
255 passthru = {
256 cc = gcc;
257 majorMinorVersion = lib.versions.majorMinor version;
258 majorVersion = lib.versions.majorMinor version;
259 };
260
261 meta = with lib; {
262 description = "A compiler for NVIDIA GPUs, math libraries, and tools";
263 homepage = "https://developer.nvidia.com/cuda-toolkit";
264 platforms = [ "x86_64-linux" ];
265 license = licenses.unfree;
266 };
267}
268