Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{
2 lib,
3 stdenv,
4 icu,
5 zlib,
6 bzip2,
7 zstd,
8 xz,
9 python ? null,
10 fixDarwinDylibNames,
11 libiconv,
12 libxcrypt,
13 sanitiseHeaderPathsHook,
14 makePkgconfigItem,
15 copyPkgconfigItems,
16 boost-build,
17 fetchpatch,
18 which,
19 toolset ?
20 if stdenv.cc.isClang then
21 "clang"
22 else if stdenv.cc.isGNU then
23 "gcc"
24 else
25 null,
26 enableRelease ? true,
27 enableDebug ? false,
28 enableSingleThreaded ? false,
29 enableMultiThreaded ? true,
30 enableShared ? !(with stdenv.hostPlatform; isStatic || isMinGW), # problems for now
31 enableStatic ? !enableShared,
32 enablePython ? false,
33 enableNumpy ? false,
34 enableIcu ? stdenv.hostPlatform == stdenv.buildPlatform,
35 taggedLayout ? (
36 (enableRelease && enableDebug)
37 || (enableSingleThreaded && enableMultiThreaded)
38 || (enableShared && enableStatic)
39 ),
40 patches ? [ ],
41 boostBuildPatches ? [ ],
42 useMpi ? false,
43 mpi,
44 extraB2Args ? [ ],
45
46 # Attributes inherit from specific versions
47 version,
48 src,
49 ...
50}:
51
52# We must build at least one type of libraries
53assert enableShared || enableStatic;
54
55assert enableNumpy -> enablePython;
56
57let
58
59 variant = lib.concatStringsSep "," (
60 lib.optional enableRelease "release" ++ lib.optional enableDebug "debug"
61 );
62
63 threading = lib.concatStringsSep "," (
64 lib.optional enableSingleThreaded "single" ++ lib.optional enableMultiThreaded "multi"
65 );
66
67 link = lib.concatStringsSep "," (
68 lib.optional enableShared "shared" ++ lib.optional enableStatic "static"
69 );
70
71 runtime-link = if enableShared then "shared" else "static";
72
73 # To avoid library name collisions
74 layout = if taggedLayout then "tagged" else "system";
75
76 needUserConfig =
77 stdenv.hostPlatform != stdenv.buildPlatform
78 || useMpi
79 || (stdenv.hostPlatform.isDarwin && enableShared);
80
81 b2Args = lib.concatStringsSep " " (
82 [
83 "--includedir=$dev/include"
84 "--libdir=$out/lib"
85 "-j$NIX_BUILD_CORES"
86 "--layout=${layout}"
87 "variant=${variant}"
88 "threading=${threading}"
89 "link=${link}"
90 ]
91 ++ lib.optionals (lib.versionAtLeast version "1.85") [
92 (
93 # The stacktrace from exception feature causes memory leaks when built
94 # with libc++. For all other standard library implementations, i.e.
95 # libstdc++, we must acknowledge this or stacktrace refuses to compile.
96 # Issue upstream: https://github.com/boostorg/stacktrace/issues/163
97 if (stdenv.cc.libcxx != null) then
98 "boost.stacktrace.from_exception=off"
99 else
100 "define=BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK"
101 )
102 ]
103 # TODO: make this unconditional
104 ++
105 lib.optionals
106 (
107 stdenv.hostPlatform != stdenv.buildPlatform
108 ||
109 # required on mips; see 61d9f201baeef4c4bb91ad8a8f5f89b747e0dfe4
110 (stdenv.hostPlatform.isMips && lib.versionAtLeast version "1.79")
111 )
112 [
113 "address-model=${toString stdenv.hostPlatform.parsed.cpu.bits}"
114 "architecture=${
115 if stdenv.hostPlatform.isMips64 then
116 if lib.versionOlder version "1.78" then "mips1" else "mips"
117 else if stdenv.hostPlatform.isS390 then
118 "s390x"
119 else
120 toString stdenv.hostPlatform.parsed.cpu.family
121 }"
122 # env in host triplet for Mach-O is "macho", but boost binary format for Mach-O is "mach-o"
123 "binary-format=${
124 if stdenv.hostPlatform.isMacho then
125 "mach-o"
126 else
127 toString stdenv.hostPlatform.parsed.kernel.execFormat.name
128 }"
129 "target-os=${toString stdenv.hostPlatform.parsed.kernel.name}"
130
131 # adapted from table in boost manual
132 # https://www.boost.org/doc/libs/1_66_0/libs/context/doc/html/context/architectures.html
133 "abi=${
134 if stdenv.hostPlatform.parsed.cpu.family == "arm" then
135 "aapcs"
136 else if stdenv.hostPlatform.isWindows then
137 "ms"
138 else if stdenv.hostPlatform.isMips32 then
139 "o32"
140 else if stdenv.hostPlatform.isMips64n64 then
141 "n64"
142 else
143 "sysv"
144 }"
145 ]
146 ++ lib.optional (link != "static") "runtime-link=${runtime-link}"
147 ++ lib.optional (variant == "release") "debug-symbols=off"
148 ++ lib.optional (toolset != null) "toolset=${toolset}"
149 ++ lib.optional (!enablePython) "--without-python"
150 ++ lib.optional needUserConfig "--user-config=user-config.jam"
151 ++ lib.optional (stdenv.buildPlatform.isDarwin && stdenv.hostPlatform.isLinux) "pch=off"
152 ++ lib.optionals stdenv.hostPlatform.isMinGW [
153 "threadapi=win32"
154 ]
155 ++ extraB2Args
156 );
157
158in
159
160stdenv.mkDerivation {
161 pname = "boost";
162
163 inherit src version;
164
165 patchFlags = [ ];
166
167 patches =
168 patches
169 ++ lib.optional (
170 lib.versionOlder version "1.88" && stdenv.hostPlatform.isDarwin
171 ) ./darwin-no-system-python.patch
172 ++ lib.optional (lib.versionOlder version "1.88") ./cmake-paths-173.patch
173 ++ lib.optional (lib.versionAtLeast version "1.88") ./cmake-paths-188.patch
174 ++ lib.optional (version == "1.77.0") (fetchpatch {
175 url = "https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch";
176 relative = "include";
177 sha256 = "sha256-KlmIbixcds6GyKYt1fx5BxDIrU7msrgDdYo9Va/KJR4=";
178 })
179 # Fixes ABI detection
180 ++ lib.optional (version == "1.83.0") (fetchpatch {
181 url = "https://github.com/boostorg/context/commit/6fa6d5c50d120e69b2d8a1c0d2256ee933e94b3b.patch";
182 stripLen = 1;
183 extraPrefix = "libs/context/";
184 sha256 = "sha256-bCfLL7bD1Rn4Ie/P3X+nIcgTkbXdCX6FW7B9lHsmVW8=";
185 })
186 # This fixes another issue regarding ill-formed constant expressions, which is a default error
187 # in clang 16 and will be a hard error in clang 17.
188 ++ lib.optional (lib.versionOlder version "1.80") (fetchpatch {
189 url = "https://github.com/boostorg/log/commit/77f1e20bd69c2e7a9e25e6a9818ae6105f7d070c.patch";
190 relative = "include";
191 hash = "sha256-6qOiGJASm33XzwoxVZfKJd7sTlQ5yd+MMFQzegXm5RI=";
192 })
193 ++ lib.optionals (lib.versionOlder version "1.81") [
194 # libc++ 15 dropped support for `std::unary_function` and `std::binary_function` in C++17+.
195 # C++17 is the default for clang 16, but clang 15 is also affected in that language mode.
196 # This patch is for Boost 1.80, but it also applies to earlier versions.
197 (fetchpatch {
198 url = "https://www.boost.org/patches/1_80_0/0005-config-libcpp15.patch";
199 hash = "sha256-ULFMzKphv70unvPZ3o4vSP/01/xbSM9a2TlIV67eXDQ=";
200 })
201 # This fixes another ill-formed contant expressions issue flagged by clang 16.
202 (fetchpatch {
203 url = "https://github.com/boostorg/numeric_conversion/commit/50a1eae942effb0a9b90724323ef8f2a67e7984a.patch";
204 relative = "include";
205 hash = "sha256-dq4SVgxkPJSC7Fvr59VGnXkM4Lb09kYDaBksCHo9C0s=";
206 })
207 # This fixes an issue in Python 3.11 about Py_TPFLAGS_HAVE_GC
208 (fetchpatch {
209 name = "python311-compatibility.patch";
210 url = "https://github.com/boostorg/python/commit/a218babc8daee904a83f550fb66e5cb3f1cb3013.patch";
211 hash = "sha256-IHxLtJBx0xSy7QEr8FbCPofsjcPuSYzgtPwDlx1JM+4=";
212 stripLen = 1;
213 extraPrefix = "libs/python/";
214 })
215 ]
216
217 ++ lib.optional (
218 lib.versionAtLeast version "1.81" && lib.versionOlder version "1.88" && stdenv.cc.isClang
219 ) ./fix-clang-target.patch
220 ++ lib.optional (lib.versionAtLeast version "1.86" && lib.versionOlder version "1.87") [
221 # Backport fix for NumPy 2 support.
222 (fetchpatch {
223 name = "boost-numpy-2-compatibility.patch";
224 url = "https://github.com/boostorg/python/commit/0474de0f6cc9c6e7230aeb7164af2f7e4ccf74bf.patch";
225 stripLen = 1;
226 extraPrefix = "libs/python/";
227 hash = "sha256-0IHK55JSujYcwEVOuLkwOa/iPEkdAKQlwVWR42p/X2U=";
228 })
229 ]
230 ++ lib.optional (version == "1.87.0") [
231 # Fix operator<< for shared_ptr and intrusive_ptr
232 # https://github.com/boostorg/smart_ptr/issues/115
233 (fetchpatch {
234 url = "https://github.com/boostorg/smart_ptr/commit/e7433ba54596da97cb7859455cd37ca140305a9c.patch";
235 relative = "include";
236 hash = "sha256-9JvKQOAB19wQpWLNAhuB9eL8qKqXWTQHAJIXdLYMNG8=";
237 })
238 # Fixes ABI detection on some platforms (like loongarch64)
239 (fetchpatch {
240 url = "https://github.com/boostorg/context/commit/63996e427b4470c7b99b0f4cafb94839ea3670b6.patch";
241 stripLen = 1;
242 extraPrefix = "libs/context/";
243 hash = "sha256-Z8uw2+4IEybqVcU25i/0XJKS16hi/+3MXUxs53ghjL0=";
244 })
245 ];
246
247 meta = with lib; {
248 homepage = "http://boost.org/";
249 description = "Collection of C++ libraries";
250 license = licenses.boost;
251 platforms = platforms.unix ++ platforms.windows;
252 # boost-context lacks support for the N32 ABI on mips64. The build
253 # will succeed, but packages depending on boost-context will fail with
254 # a very cryptic error message.
255 badPlatforms = [ lib.systems.inspect.patterns.isMips64n32 ];
256 maintainers = with maintainers; [ hjones2199 ];
257 broken =
258 enableNumpy && lib.versionOlder version "1.86" && lib.versionAtLeast python.pkgs.numpy.version "2";
259 };
260
261 passthru = {
262 inherit boostBuildPatches;
263 };
264
265 preConfigure =
266 lib.optionalString useMpi ''
267 cat << EOF >> user-config.jam
268 using mpi : ${lib.getDev mpi}/bin/mpiCC ;
269 EOF
270 ''
271 # On darwin we need to add the `$out/lib` to the libraries' rpath explicitly,
272 # otherwise the dynamic linker is unable to resolve the reference to @rpath
273 # when the boost libraries want to load each other at runtime.
274 + lib.optionalString (stdenv.hostPlatform.isDarwin && enableShared) ''
275 cat << EOF >> user-config.jam
276 using clang-darwin : : ${stdenv.cc.targetPrefix}c++
277 : <linkflags>"-rpath $out/lib/"
278 <archiver>$AR
279 <ranlib>$RANLIB
280 ;
281 EOF
282 ''
283 # b2 has trouble finding the correct compiler and tools for cross compilation
284 # since it apparently ignores $CC, $AR etc. Thus we need to set everything
285 # in user-config.jam. To keep things simple we just set everything in an
286 # uniform way for clang and gcc (which works thanks to our cc-wrapper).
287 # We pass toolset later which will make b2 invoke everything in the right
288 # way -- the other toolset in user-config.jam will be ignored.
289 + lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
290 cat << EOF >> user-config.jam
291 using gcc : cross : ${stdenv.cc.targetPrefix}c++
292 : <archiver>$AR
293 <ranlib>$RANLIB
294 ;
295
296 using clang : cross : ${stdenv.cc.targetPrefix}c++
297 : <archiver>$AR
298 <ranlib>$RANLIB
299 ;
300 EOF
301 ''
302 # b2 needs to be explicitly told how to find Python when cross-compiling
303 + lib.optionalString enablePython ''
304 cat << EOF >> user-config.jam
305 using python : : ${python.pythonOnBuildForHost.interpreter}
306 : ${python}/include/python${python.pythonVersion}
307 : ${python}/lib
308 ;
309 EOF
310 '';
311
312 # Fix compilation to 32-bit ARM with clang in downstream packages
313 # https://github.com/ned14/outcome/pull/308
314 # https://github.com/boostorg/json/pull/1064
315 postPatch = lib.optionalString (version == "1.87.0") ''
316 substituteInPlace \
317 boost/outcome/outcome_gdb.h \
318 boost/outcome/experimental/status-code/status_code.hpp \
319 boost/json/detail/gdb_printers.hpp \
320 boost/unordered/unordered_printers.hpp \
321 boost/interprocess/interprocess_printers.hpp \
322 libs/json/pretty_printers/generate-gdb-header.py \
323 --replace-fail ",@progbits,1" ",%progbits,1"
324 '';
325
326 env = {
327 NIX_CFLAGS_LINK = lib.optionalString stdenv.hostPlatform.isDarwin "-headerpad_max_install_names";
328 # copyPkgconfigItems will substitute these in the pkg-config file
329 includedir = "${placeholder "dev"}/include";
330 libdir = "${placeholder "out"}/lib";
331 };
332
333 pkgconfigItems = [
334 (makePkgconfigItem {
335 name = "boost";
336 inherit version;
337 # Exclude other variables not needed by meson
338 variables = {
339 includedir = "@includedir@";
340 libdir = "@libdir@";
341 };
342 })
343 ];
344
345 enableParallelBuilding = true;
346
347 nativeBuildInputs = [
348 which
349 boost-build
350 copyPkgconfigItems
351 sanitiseHeaderPathsHook
352 ]
353 ++ lib.optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames;
354 buildInputs = [
355 zlib
356 bzip2
357 libiconv
358 ]
359 ++ lib.optional (lib.versionAtLeast version "1.69") zstd
360 ++ [ xz ]
361 ++ lib.optional enableIcu icu
362 ++ lib.optionals enablePython [
363 libxcrypt
364 python
365 ]
366 ++ lib.optional enableNumpy python.pkgs.numpy;
367
368 configureScript = "./bootstrap.sh";
369 configurePlatforms = [ ];
370 dontDisableStatic = true;
371 dontAddStaticConfigureFlags = true;
372 configureFlags = [
373 "--includedir=$(dev)/include"
374 "--libdir=$(out)/lib"
375 "--with-bjam=b2" # prevent bootstrapping b2 in configurePhase
376 ]
377 ++ lib.optional (toolset != null) "--with-toolset=${toolset}"
378 ++ [ (if enableIcu then "--with-icu=${icu.dev}" else "--without-icu") ];
379
380 buildPhase = ''
381 runHook preBuild
382 b2 ${b2Args}
383 runHook postBuild
384 '';
385
386 installPhase = ''
387 runHook preInstall
388
389 # boostbook is needed by some applications
390 mkdir -p $dev/share/boostbook
391 cp -a tools/boostbook/{xsl,dtd} $dev/share/boostbook/
392
393 # Let boost install everything else
394 b2 ${b2Args} install
395
396 runHook postInstall
397 '';
398
399 preFixup = ''
400 # Strip UTF‐8 BOMs for `sanitiseHeaderPathsHook`.
401 cd "$dev" && find include \( -name '*.hpp' -or -name '*.h' -or -name '*.ipp' \) \
402 -exec sed '1s/^\xef\xbb\xbf//' -i '{}' \;
403 '';
404
405 postFixup = lib.optionalString stdenv.hostPlatform.isMinGW ''
406 $RANLIB "$out/lib/"*.a
407 '';
408
409 outputs = [
410 "out"
411 "dev"
412 ];
413 setOutputFlags = false;
414}