nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 lapack-reference,
5 openblas,
6 isILP64 ? false,
7 blasProvider ? openblas,
8}:
9
10let
11 blasFortranSymbols = [
12 "caxpy"
13 "ccopy"
14 "cdotc"
15 "cdotu"
16 "cgbmv"
17 "cgemm"
18 "cgemv"
19 "cgerc"
20 "cgeru"
21 "chbmv"
22 "chemm"
23 "chemv"
24 "cher"
25 "cher2"
26 "cher2k"
27 "cherk"
28 "chpmv"
29 "chpr"
30 "chpr2"
31 "crotg"
32 "cscal"
33 "csrot"
34 "csscal"
35 "cswap"
36 "csymm"
37 "csyr2k"
38 "csyrk"
39 "ctbmv"
40 "ctbsv"
41 "ctpmv"
42 "ctpsv"
43 "ctrmm"
44 "ctrmv"
45 "ctrsm"
46 "ctrsv"
47 "dasum"
48 "daxpy"
49 "dcabs1"
50 "dcopy"
51 "ddot"
52 "dgbmv"
53 "dgemm"
54 "dgemv"
55 "dger"
56 "dnrm2"
57 "drot"
58 "drotg"
59 "drotm"
60 "drotmg"
61 "dsbmv"
62 "dscal"
63 "dsdot"
64 "dspmv"
65 "dspr"
66 "dspr2"
67 "dswap"
68 "dsymm"
69 "dsymv"
70 "dsyr"
71 "dsyr2"
72 "dsyr2k"
73 "dsyrk"
74 "dtbmv"
75 "dtbsv"
76 "dtpmv"
77 "dtpsv"
78 "dtrmm"
79 "dtrmv"
80 "dtrsm"
81 "dtrsv"
82 "dzasum"
83 "dznrm2"
84 "icamax"
85 "idamax"
86 "isamax"
87 "izamax"
88 "lsame"
89 "sasum"
90 "saxpy"
91 "scabs1"
92 "scasum"
93 "scnrm2"
94 "scopy"
95 "sdot"
96 "sdsdot"
97 "sgbmv"
98 "sgemm"
99 "sgemv"
100 "sger"
101 "snrm2"
102 "srot"
103 "srotg"
104 "srotm"
105 "srotmg"
106 "ssbmv"
107 "sscal"
108 "sspmv"
109 "sspr"
110 "sspr2"
111 "sswap"
112 "ssymm"
113 "ssymv"
114 "ssyr"
115 "ssyr2"
116 "ssyr2k"
117 "ssyrk"
118 "stbmv"
119 "stbsv"
120 "stpmv"
121 "stpsv"
122 "strmm"
123 "strmv"
124 "strsm"
125 "strsv"
126 "xerbla"
127 "xerbla_array"
128 "zaxpy"
129 "zcopy"
130 "zdotc"
131 "zdotu"
132 "zdrot"
133 "zdscal"
134 "zgbmv"
135 "zgemm"
136 "zgemv"
137 "zgerc"
138 "zgeru"
139 "zhbmv"
140 "zhemm"
141 "zhemv"
142 "zher"
143 "zher2"
144 "zher2k"
145 "zherk"
146 "zhpmv"
147 "zhpr"
148 "zhpr2"
149 "zrotg"
150 "zscal"
151 "zswap"
152 "zsymm"
153 "zsyr2k"
154 "zsyrk"
155 "ztbmv"
156 "ztbsv"
157 "ztpmv"
158 "ztpsv"
159 "ztrmm"
160 "ztrmv"
161 "ztrsm"
162 "ztrsv"
163 ];
164
165 version = "3";
166 canonicalExtension =
167 if stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isStatic then
168 "${stdenv.hostPlatform.extensions.sharedLibrary}.${version}"
169 else
170 stdenv.hostPlatform.extensions.sharedLibrary or ".a";
171
172 blasImplementation = lib.getName blasProvider;
173 blasProvider' =
174 if blasImplementation == "mkl" then blasProvider else blasProvider.override { blas64 = isILP64; };
175
176in
177
178assert isILP64 -> blasImplementation == "mkl" || blasProvider'.blas64;
179
180stdenv.mkDerivation {
181 pname = "blas";
182 inherit version;
183
184 outputs = [
185 "out"
186 "dev"
187 ];
188
189 meta = (blasProvider'.meta or { }) // {
190 description = "${lib.getName blasProvider} with just the BLAS C and FORTRAN ABI";
191 };
192
193 passthru = {
194 inherit isILP64;
195 provider = blasProvider';
196 implementation = blasImplementation;
197 };
198
199 dontBuild = true;
200 dontConfigure = true;
201 unpackPhase = "src=$PWD";
202
203 dontPatchELF = true;
204
205 installPhase = (
206 ''
207 mkdir -p $out/lib $dev/include $dev/lib/pkgconfig
208
209 libblas="${lib.getLib blasProvider'}/lib/libblas${canonicalExtension}"
210
211 if ! [ -e "$libblas" ]; then
212 echo "$libblas does not exist, ${blasProvider'.name} does not provide libblas."
213 exit 1
214 fi
215 ''
216 + lib.optionalString (!stdenv.hostPlatform.isStatic) ''
217 $NM -an "$libblas" | cut -f3 -d' ' > symbols
218 for symbol in ${toString blasFortranSymbols}; do
219 grep -q "^$symbol_$" symbols || { echo "$symbol" was not found in "$libblas"; exit 1; }
220 done
221 ''
222 + ''
223 cp -L "$libblas" $out/lib/libblas${canonicalExtension}
224 chmod +w $out/lib/libblas${canonicalExtension}
225
226 ''
227 + (
228 if (stdenv.hostPlatform.isElf && !stdenv.hostPlatform.isStatic) then
229 ''
230 patchelf --set-soname libblas${canonicalExtension} $out/lib/libblas${canonicalExtension}
231 patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libblas${canonicalExtension}):${lib.getLib blasProvider'}/lib" $out/lib/libblas${canonicalExtension}
232 ''
233 else
234 lib.optionalString (stdenv.hostPlatform.isDarwin) ''
235 install_name_tool \
236 -id $out/lib/libblas${canonicalExtension} \
237 -add_rpath ${lib.getLib blasProvider'}/lib \
238 $out/lib/libblas${canonicalExtension}
239 ''
240 )
241 + ''
242
243 if [ "$out/lib/libblas${canonicalExtension}" != "$out/lib/libblas${
244 stdenv.hostPlatform.extensions.sharedLibrary or ".a"
245 }" ]; then
246 ln -s $out/lib/libblas${canonicalExtension} "$out/lib/libblas${
247 stdenv.hostPlatform.extensions.sharedLibrary or ".a"
248 }"
249 fi
250
251 cat <<EOF > $dev/lib/pkgconfig/blas.pc
252 Name: blas
253 Version: ${version}
254 Description: BLAS FORTRAN implementation
255 Libs: -L$out/lib -lblas
256 Cflags: -I$dev/include
257 EOF
258
259 libcblas="${lib.getLib blasProvider'}/lib/libcblas${canonicalExtension}"
260
261 if ! [ -e "$libcblas" ]; then
262 echo "$libcblas does not exist, ${blasProvider'.name} does not provide libcblas."
263 exit 1
264 fi
265
266 cp -L "$libcblas" $out/lib/libcblas${canonicalExtension}
267 chmod +w $out/lib/libcblas${canonicalExtension}
268
269 ''
270 + (
271 if (stdenv.hostPlatform.isElf && !stdenv.hostPlatform.isStatic) then
272 ''
273 patchelf --set-soname libcblas${canonicalExtension} $out/lib/libcblas${canonicalExtension}
274 patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libcblas${canonicalExtension}):${lib.getLib blasProvider'}/lib" $out/lib/libcblas${canonicalExtension}
275 ''
276 else
277 lib.optionalString stdenv.hostPlatform.isDarwin ''
278 install_name_tool \
279 -id $out/lib/libcblas${canonicalExtension} \
280 -add_rpath ${lib.getLib blasProvider'}/lib \
281 $out/lib/libcblas${canonicalExtension}
282 ''
283 )
284 + ''
285 if [ "$out/lib/libcblas${canonicalExtension}" != "$out/lib/libcblas${
286 stdenv.hostPlatform.extensions.sharedLibrary or ".a"
287 }" ]; then
288 ln -s $out/lib/libcblas${canonicalExtension} "$out/lib/libcblas${
289 stdenv.hostPlatform.extensions.sharedLibrary or ".a"
290 }"
291 fi
292
293 cp ${lib.getDev lapack-reference}/include/cblas{,_mangling}.h $dev/include
294
295 cat <<EOF > $dev/lib/pkgconfig/cblas.pc
296 Name: cblas
297 Version: ${version}
298 Description: BLAS C implementation
299 Cflags: -I$dev/include
300 Libs: -L$out/lib -lcblas
301 EOF
302 ''
303 + lib.optionalString (blasImplementation == "mkl") ''
304 mkdir -p $out/nix-support
305 echo 'export MKL_INTERFACE_LAYER=${lib.optionalString isILP64 "I"}LP64,GNU' > $out/nix-support/setup-hook
306 ln -s $out/lib/libblas${canonicalExtension} $out/lib/libmkl_rt${
307 stdenv.hostPlatform.extensions.sharedLibrary or ".a"
308 }
309 ln -sf ${blasProvider'}/include/* $dev/include
310 ''
311 );
312}