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