nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ lib, stdenv, icu, expat, zlib, bzip2, python ? null, fixDarwinDylibNames, libiconv
2, boost-build
3, fetchpatch
4, which
5, toolset ? /**/ if stdenv.cc.isClang then "clang"
6 else if stdenv.cc.isGNU then "gcc"
7 else null
8, enableRelease ? true
9, enableDebug ? false
10, enableSingleThreaded ? false
11, enableMultiThreaded ? true
12, enableShared ? !(with stdenv.hostPlatform; isStatic || libc == "msvcrt") # problems for now
13, enableStatic ? !enableShared
14, enablePython ? false
15, enableNumpy ? false
16, taggedLayout ? ((enableRelease && enableDebug) || (enableSingleThreaded && enableMultiThreaded) || (enableShared && enableStatic))
17, patches ? []
18, boostBuildPatches ? []
19, useMpi ? false
20, mpi
21, extraB2Args ? []
22
23# Attributes inherit from specific versions
24, version, src
25, ...
26}:
27
28# We must build at least one type of libraries
29assert enableShared || enableStatic;
30
31# Python isn't supported when cross-compiling
32assert enablePython -> stdenv.hostPlatform == stdenv.buildPlatform;
33assert enableNumpy -> enablePython;
34
35# Boost <1.69 can't be built on linux with clang >8, because pth was removed
36assert with lib; (stdenv.isLinux && toolset == "clang" && versionAtLeast stdenv.cc.version "8.0.0") -> versionAtLeast version "1.69";
37
38with lib;
39let
40
41 variant = concatStringsSep ","
42 (optional enableRelease "release" ++
43 optional enableDebug "debug");
44
45 threading = concatStringsSep ","
46 (optional enableSingleThreaded "single" ++
47 optional enableMultiThreaded "multi");
48
49 link = concatStringsSep ","
50 (optional enableShared "shared" ++
51 optional enableStatic "static");
52
53 runtime-link = if enableShared then "shared" else "static";
54
55 # To avoid library name collisions
56 layout = if taggedLayout then "tagged" else "system";
57
58 # Versions of b2 before 1.65 have job limits; specifically:
59 # - Versions before 1.58 support up to 64 jobs[0]
60 # - Versions before 1.65 support up to 256 jobs[1]
61 #
62 # [0]: https://github.com/boostorg/build/commit/0ef40cb86728f1cd804830fef89a6d39153ff632
63 # [1]: https://github.com/boostorg/build/commit/316e26ca718afc65d6170029284521392524e4f8
64 jobs =
65 if versionOlder version "1.58" then
66 "$(($NIX_BUILD_CORES<=64 ? $NIX_BUILD_CORES : 64))"
67 else if versionOlder version "1.65" then
68 "$(($NIX_BUILD_CORES<=256 ? $NIX_BUILD_CORES : 256))"
69 else
70 "$NIX_BUILD_CORES";
71
72 needUserConfig = stdenv.hostPlatform != stdenv.buildPlatform || useMpi || (stdenv.isDarwin && enableShared);
73
74 b2Args = concatStringsSep " " ([
75 "--includedir=$dev/include"
76 "--libdir=$out/lib"
77 "-j${jobs}"
78 "--layout=${layout}"
79 "variant=${variant}"
80 "threading=${threading}"
81 "link=${link}"
82 "-sEXPAT_INCLUDE=${expat.dev}/include"
83 "-sEXPAT_LIBPATH=${expat.out}/lib"
84
85 # TODO: make this unconditional
86 ] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
87 "address-model=${toString stdenv.hostPlatform.parsed.cpu.bits}"
88 "architecture=${if stdenv.hostPlatform.isMips64
89 then if versionOlder version "1.78" then "mips1" else "mips"
90 else toString stdenv.hostPlatform.parsed.cpu.family}"
91 "binary-format=${toString stdenv.hostPlatform.parsed.kernel.execFormat.name}"
92 "target-os=${toString stdenv.hostPlatform.parsed.kernel.name}"
93
94 # adapted from table in boost manual
95 # https://www.boost.org/doc/libs/1_66_0/libs/context/doc/html/context/architectures.html
96 "abi=${if stdenv.hostPlatform.parsed.cpu.family == "arm" then "aapcs"
97 else if stdenv.hostPlatform.isWindows then "ms"
98 else if stdenv.hostPlatform.isMips32 then "o32"
99 else if stdenv.hostPlatform.isMips64n64 then "n64"
100 else "sysv"}"
101 ] ++ optional (link != "static") "runtime-link=${runtime-link}"
102 ++ optional (variant == "release") "debug-symbols=off"
103 ++ optional (toolset != null) "toolset=${toolset}"
104 ++ optional (!enablePython) "--without-python"
105 ++ optional needUserConfig "--user-config=user-config.jam"
106 ++ optionals (stdenv.hostPlatform.libc == "msvcrt") [
107 "threadapi=win32"
108 ] ++ extraB2Args
109 );
110
111in
112
113stdenv.mkDerivation {
114 pname = "boost";
115
116 inherit src version;
117
118 patchFlags = [];
119
120 patches = patches
121 ++ optional stdenv.isDarwin (
122 if version == "1.55.0"
123 then ./darwin-1.55-no-system-python.patch
124 else ./darwin-no-system-python.patch)
125 # Fix boost-context segmentation faults on ppc64 due to ABI violation
126 ++ optional (versionAtLeast version "1.61" &&
127 versionOlder version "1.71") (fetchpatch {
128 url = "https://github.com/boostorg/context/commit/2354eca9b776a6739112833f64754108cc0d1dc5.patch";
129 sha256 = "067m4bjpmcanqvg28djax9a10avmdwhlpfx6gn73kbqqq70dnz29";
130 stripLen = 1;
131 extraPrefix = "libs/context/";
132 })
133 # Fix compiler warning with GCC >= 8; TODO: patch may apply to older versions
134 ++ optional (versionAtLeast version "1.65" && versionOlder version "1.67")
135 (fetchpatch {
136 url = "https://github.com/boostorg/mpl/commit/f48fd09d021db9a28bd7b8452c175897e1af4485.patch";
137 sha256 = "15d2a636hhsb1xdyp44x25dyqfcaws997vnp9kl1mhzvxjzz7hb0";
138 stripLen = 1;
139 })
140 ++ optional (versionAtLeast version "1.65" && versionOlder version "1.70") (fetchpatch {
141 # support for Mips64n64 appeared in boost-context 1.70; this patch won't apply to pre-1.65 cleanly
142 url = "https://github.com/boostorg/context/commit/e3f744a1862164062d579d1972272d67bdaa9c39.patch";
143 sha256 = "sha256-qjQy1b4jDsIRrI+UYtcguhvChrMbGWO0UlEzEJHYzRI=";
144 stripLen = 1;
145 extraPrefix = "libs/context/";
146 })
147 ++ optional (versionAtLeast version "1.70" && versionOlder version "1.73") ./cmake-paths.patch
148 ++ optional (versionAtLeast version "1.73") ./cmake-paths-173.patch
149 ++ optional (version == "1.77.0") (fetchpatch {
150 url = "https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch";
151 relative = "include";
152 sha256 = "sha256-KlmIbixcds6GyKYt1fx5BxDIrU7msrgDdYo9Va/KJR4=";
153 });
154
155 meta = {
156 homepage = "http://boost.org/";
157 description = "Collection of C++ libraries";
158 license = licenses.boost;
159 platforms = platforms.unix ++ platforms.windows;
160 badPlatforms = optional (versionOlder version "1.59") "aarch64-linux"
161 ++ optional ((versionOlder version "1.57") || version == "1.58") "x86_64-darwin"
162 ++ optionals (versionOlder version "1.73") lib.platforms.riscv;
163 maintainers = with maintainers; [ hjones2199 ];
164
165 broken =
166 # boost-context lacks support for the N32 ABI on mips64. The build
167 # will succeed, but packages depending on boost-context will fail with
168 # a very cryptic error message.
169 stdenv.hostPlatform.isMips64n32 ||
170 # the patch above does not apply cleanly to pre-1.65 boost
171 (stdenv.hostPlatform.isMips64n64 && (versionOlder version "1.65"));
172 };
173
174 passthru = {
175 inherit boostBuildPatches;
176 };
177
178 preConfigure = optionalString useMpi ''
179 cat << EOF >> user-config.jam
180 using mpi : ${mpi}/bin/mpiCC ;
181 EOF
182 ''
183 # On darwin we need to add the `$out/lib` to the libraries' rpath explicitly,
184 # otherwise the dynamic linker is unable to resolve the reference to @rpath
185 # when the boost libraries want to load each other at runtime.
186 + optionalString (stdenv.isDarwin && enableShared) ''
187 cat << EOF >> user-config.jam
188 using clang-darwin : : ${stdenv.cc.targetPrefix}c++
189 : <linkflags>"-rpath $out/lib/"
190 ;
191 EOF
192 ''
193 # b2 has trouble finding the correct compiler and tools for cross compilation
194 # since it apparently ignores $CC, $AR etc. Thus we need to set everything
195 # in user-config.jam. To keep things simple we just set everything in an
196 # uniform way for clang and gcc (which works thanks to our cc-wrapper).
197 # We pass toolset later which will make b2 invoke everything in the right
198 # way -- the other toolset in user-config.jam will be ignored.
199 + optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
200 cat << EOF >> user-config.jam
201 using gcc : cross : ${stdenv.cc.targetPrefix}c++
202 : <archiver>$AR
203 <ranlib>$RANLIB
204 ;
205
206 using clang : cross : ${stdenv.cc.targetPrefix}c++
207 : <archiver>$AR
208 <ranlib>$RANLIB
209 ;
210 EOF
211 '';
212
213 NIX_CFLAGS_LINK = lib.optionalString stdenv.isDarwin
214 "-headerpad_max_install_names";
215
216 enableParallelBuilding = true;
217
218 nativeBuildInputs = [ which boost-build ]
219 ++ optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames;
220 buildInputs = [ expat zlib bzip2 libiconv ]
221 ++ optional (stdenv.hostPlatform == stdenv.buildPlatform) icu
222 ++ optional enablePython python
223 ++ optional enableNumpy python.pkgs.numpy;
224
225 configureScript = "./bootstrap.sh";
226 configurePlatforms = [];
227 dontDisableStatic = true;
228 dontAddStaticConfigureFlags = true;
229 configureFlags = [
230 "--includedir=$(dev)/include"
231 "--libdir=$(out)/lib"
232 "--with-bjam=b2" # prevent bootstrapping b2 in configurePhase
233 ] ++ optional enablePython "--with-python=${python.interpreter}"
234 ++ optional (toolset != null) "--with-toolset=${toolset}"
235 ++ [ (if stdenv.hostPlatform == stdenv.buildPlatform then "--with-icu=${icu.dev}" else "--without-icu") ];
236
237 buildPhase = ''
238 runHook preBuild
239 b2 ${b2Args}
240 runHook postBuild
241 '';
242
243 installPhase = ''
244 runHook preInstall
245
246 # boostbook is needed by some applications
247 mkdir -p $dev/share/boostbook
248 cp -a tools/boostbook/{xsl,dtd} $dev/share/boostbook/
249
250 # Let boost install everything else
251 b2 ${b2Args} install
252
253 runHook postInstall
254 '';
255
256 postFixup = ''
257 # Make boost header paths relative so that they are not runtime dependencies
258 cd "$dev" && find include \( -name '*.hpp' -or -name '*.h' -or -name '*.ipp' \) \
259 -exec sed '1s/^\xef\xbb\xbf//;1i#line 1 "{}"' -i '{}' \;
260 '' + optionalString (stdenv.hostPlatform.libc == "msvcrt") ''
261 $RANLIB "$out/lib/"*.a
262 '';
263
264 outputs = [ "out" "dev" ];
265 setOutputFlags = false;
266}