268 lines
9.9 KiB
Nix
268 lines
9.9 KiB
Nix
|
{ lib, stdenv, icu, expat, zlib, bzip2, zstd, xz, python ? null, fixDarwinDylibNames, libiconv, libxcrypt
|
||
|
, boost-build
|
||
|
, fetchpatch
|
||
|
, which
|
||
|
, toolset ? /**/ if stdenv.cc.isClang then "clang"
|
||
|
else if stdenv.cc.isGNU then "gcc"
|
||
|
else null
|
||
|
, enableRelease ? true
|
||
|
, enableDebug ? false
|
||
|
, enableSingleThreaded ? false
|
||
|
, enableMultiThreaded ? true
|
||
|
, enableShared ? !(with stdenv.hostPlatform; isStatic || isMinGW) # problems for now
|
||
|
, enableStatic ? !enableShared
|
||
|
, enablePython ? false
|
||
|
, enableNumpy ? false
|
||
|
, enableIcu ? stdenv.hostPlatform == stdenv.buildPlatform
|
||
|
, taggedLayout ? ((enableRelease && enableDebug) || (enableSingleThreaded && enableMultiThreaded) || (enableShared && enableStatic))
|
||
|
, patches ? []
|
||
|
, boostBuildPatches ? []
|
||
|
, useMpi ? false
|
||
|
, mpi
|
||
|
, extraB2Args ? []
|
||
|
|
||
|
# Attributes inherit from specific versions
|
||
|
, version, src
|
||
|
, ...
|
||
|
}:
|
||
|
|
||
|
# We must build at least one type of libraries
|
||
|
assert enableShared || enableStatic;
|
||
|
|
||
|
assert enableNumpy -> enablePython;
|
||
|
|
||
|
let
|
||
|
|
||
|
variant = lib.concatStringsSep ","
|
||
|
(lib.optional enableRelease "release" ++
|
||
|
lib.optional enableDebug "debug");
|
||
|
|
||
|
threading = lib.concatStringsSep ","
|
||
|
(lib.optional enableSingleThreaded "single" ++
|
||
|
lib.optional enableMultiThreaded "multi");
|
||
|
|
||
|
link = lib.concatStringsSep ","
|
||
|
(lib.optional enableShared "shared" ++
|
||
|
lib.optional enableStatic "static");
|
||
|
|
||
|
runtime-link = if enableShared then "shared" else "static";
|
||
|
|
||
|
# To avoid library name collisions
|
||
|
layout = if taggedLayout then "tagged" else "system";
|
||
|
|
||
|
needUserConfig = stdenv.hostPlatform != stdenv.buildPlatform || useMpi || (stdenv.isDarwin && enableShared);
|
||
|
|
||
|
b2Args = lib.concatStringsSep " " ([
|
||
|
"--includedir=$dev/include"
|
||
|
"--libdir=$out/lib"
|
||
|
"-j$NIX_BUILD_CORES"
|
||
|
"--layout=${layout}"
|
||
|
"variant=${variant}"
|
||
|
"threading=${threading}"
|
||
|
"link=${link}"
|
||
|
"-sEXPAT_INCLUDE=${expat.dev}/include"
|
||
|
"-sEXPAT_LIBPATH=${expat.out}/lib"
|
||
|
|
||
|
# TODO: make this unconditional
|
||
|
] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform ||
|
||
|
# required on mips; see 61d9f201baeef4c4bb91ad8a8f5f89b747e0dfe4
|
||
|
(stdenv.hostPlatform.isMips && lib.versionAtLeast version "1.79")) [
|
||
|
"address-model=${toString stdenv.hostPlatform.parsed.cpu.bits}"
|
||
|
"architecture=${if stdenv.hostPlatform.isMips64
|
||
|
then if lib.versionOlder version "1.78" then "mips1" else "mips"
|
||
|
else if stdenv.hostPlatform.parsed.cpu.name == "s390x" then "s390x"
|
||
|
else toString stdenv.hostPlatform.parsed.cpu.family}"
|
||
|
# env in host triplet for Mach-O is "macho", but boost binary format for Mach-O is "mach-o"
|
||
|
"binary-format=${if stdenv.hostPlatform.isMacho then "mach-o"
|
||
|
else toString stdenv.hostPlatform.parsed.kernel.execFormat.name}"
|
||
|
"target-os=${toString stdenv.hostPlatform.parsed.kernel.name}"
|
||
|
|
||
|
# adapted from table in boost manual
|
||
|
# https://www.boost.org/doc/libs/1_66_0/libs/context/doc/html/context/architectures.html
|
||
|
"abi=${if stdenv.hostPlatform.parsed.cpu.family == "arm" then "aapcs"
|
||
|
else if stdenv.hostPlatform.isWindows then "ms"
|
||
|
else if stdenv.hostPlatform.isMips32 then "o32"
|
||
|
else if stdenv.hostPlatform.isMips64n64 then "n64"
|
||
|
else "sysv"}"
|
||
|
] ++ lib.optional (link != "static") "runtime-link=${runtime-link}"
|
||
|
++ lib.optional (variant == "release") "debug-symbols=off"
|
||
|
++ lib.optional (toolset != null) "toolset=${toolset}"
|
||
|
++ lib.optional (!enablePython) "--without-python"
|
||
|
++ lib.optional needUserConfig "--user-config=user-config.jam"
|
||
|
++ lib.optional (stdenv.buildPlatform.isDarwin && stdenv.hostPlatform.isLinux) "pch=off"
|
||
|
++ lib.optionals stdenv.hostPlatform.isMinGW [
|
||
|
"threadapi=win32"
|
||
|
] ++ extraB2Args
|
||
|
);
|
||
|
|
||
|
in
|
||
|
|
||
|
stdenv.mkDerivation {
|
||
|
pname = "boost";
|
||
|
|
||
|
inherit src version;
|
||
|
|
||
|
patchFlags = [];
|
||
|
|
||
|
patches = patches
|
||
|
++ lib.optional stdenv.isDarwin ./darwin-no-system-python.patch
|
||
|
++ [ ./cmake-paths-173.patch ]
|
||
|
++ lib.optional (version == "1.77.0") (fetchpatch {
|
||
|
url = "https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch";
|
||
|
relative = "include";
|
||
|
sha256 = "sha256-KlmIbixcds6GyKYt1fx5BxDIrU7msrgDdYo9Va/KJR4=";
|
||
|
})
|
||
|
# Fixes ABI detection
|
||
|
++ lib.optional (version == "1.83.0") (fetchpatch {
|
||
|
url = "https://github.com/boostorg/context/commit/6fa6d5c50d120e69b2d8a1c0d2256ee933e94b3b.patch";
|
||
|
stripLen = 1;
|
||
|
extraPrefix = "libs/context/";
|
||
|
sha256 = "sha256-bCfLL7bD1Rn4Ie/P3X+nIcgTkbXdCX6FW7B9lHsmVW8=";
|
||
|
})
|
||
|
# This fixes another issue regarding ill-formed constant expressions, which is a default error
|
||
|
# in clang 16 and will be a hard error in clang 17.
|
||
|
++ lib.optional (lib.versionOlder version "1.80") (fetchpatch {
|
||
|
url = "https://github.com/boostorg/log/commit/77f1e20bd69c2e7a9e25e6a9818ae6105f7d070c.patch";
|
||
|
relative = "include";
|
||
|
hash = "sha256-6qOiGJASm33XzwoxVZfKJd7sTlQ5yd+MMFQzegXm5RI=";
|
||
|
})
|
||
|
++ lib.optionals (lib.versionOlder version "1.81") [
|
||
|
# libc++ 15 dropped support for `std::unary_function` and `std::binary_function` in C++17+.
|
||
|
# C++17 is the default for clang 16, but clang 15 is also affected in that language mode.
|
||
|
# This patch is for Boost 1.80, but it also applies to earlier versions.
|
||
|
(fetchpatch {
|
||
|
url = "https://www.boost.org/patches/1_80_0/0005-config-libcpp15.patch";
|
||
|
hash = "sha256-ULFMzKphv70unvPZ3o4vSP/01/xbSM9a2TlIV67eXDQ=";
|
||
|
})
|
||
|
# This fixes another ill-formed contant expressions issue flagged by clang 16.
|
||
|
(fetchpatch {
|
||
|
url = "https://github.com/boostorg/numeric_conversion/commit/50a1eae942effb0a9b90724323ef8f2a67e7984a.patch";
|
||
|
relative = "include";
|
||
|
hash = "sha256-dq4SVgxkPJSC7Fvr59VGnXkM4Lb09kYDaBksCHo9C0s=";
|
||
|
})
|
||
|
# This fixes an issue in Python 3.11 about Py_TPFLAGS_HAVE_GC
|
||
|
(fetchpatch {
|
||
|
name = "python311-compatibility.patch";
|
||
|
url = "https://github.com/boostorg/python/commit/a218babc8daee904a83f550fb66e5cb3f1cb3013.patch";
|
||
|
hash = "sha256-IHxLtJBx0xSy7QEr8FbCPofsjcPuSYzgtPwDlx1JM+4=";
|
||
|
stripLen = 1;
|
||
|
extraPrefix = "libs/python/";
|
||
|
})
|
||
|
];
|
||
|
|
||
|
meta = with lib; {
|
||
|
homepage = "http://boost.org/";
|
||
|
description = "Collection of C++ libraries";
|
||
|
license = licenses.boost;
|
||
|
platforms = platforms.unix ++ platforms.windows;
|
||
|
# boost-context lacks support for the N32 ABI on mips64. The build
|
||
|
# will succeed, but packages depending on boost-context will fail with
|
||
|
# a very cryptic error message.
|
||
|
badPlatforms = [ lib.systems.inspect.patterns.isMips64n32 ];
|
||
|
maintainers = with maintainers; [ hjones2199 ];
|
||
|
};
|
||
|
|
||
|
# passthru = {
|
||
|
# inherit boostBuildPatches;
|
||
|
# };
|
||
|
|
||
|
preConfigure = lib.optionalString useMpi ''
|
||
|
cat << EOF >> user-config.jam
|
||
|
using mpi : ${lib.getDev mpi}/bin/mpiCC ;
|
||
|
EOF
|
||
|
''
|
||
|
# On darwin we need to add the `$out/lib` to the libraries' rpath explicitly,
|
||
|
# otherwise the dynamic linker is unable to resolve the reference to @rpath
|
||
|
# when the boost libraries want to load each other at runtime.
|
||
|
+ lib.optionalString (stdenv.isDarwin && enableShared) ''
|
||
|
cat << EOF >> user-config.jam
|
||
|
using clang-darwin : : ${stdenv.cc.targetPrefix}c++
|
||
|
: <linkflags>"-rpath $out/lib/"
|
||
|
;
|
||
|
EOF
|
||
|
''
|
||
|
# b2 has trouble finding the correct compiler and tools for cross compilation
|
||
|
# since it apparently ignores $CC, $AR etc. Thus we need to set everything
|
||
|
# in user-config.jam. To keep things simple we just set everything in an
|
||
|
# uniform way for clang and gcc (which works thanks to our cc-wrapper).
|
||
|
# We pass toolset later which will make b2 invoke everything in the right
|
||
|
# way -- the other toolset in user-config.jam will be ignored.
|
||
|
+ lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
|
||
|
cat << EOF >> user-config.jam
|
||
|
using gcc : cross : ${stdenv.cc.targetPrefix}c++
|
||
|
: <archiver>$AR
|
||
|
<ranlib>$RANLIB
|
||
|
;
|
||
|
|
||
|
using clang : cross : ${stdenv.cc.targetPrefix}c++
|
||
|
: <archiver>$AR
|
||
|
<ranlib>$RANLIB
|
||
|
;
|
||
|
EOF
|
||
|
''
|
||
|
# b2 needs to be explicitly told how to find Python when cross-compiling
|
||
|
+ lib.optionalString enablePython ''
|
||
|
cat << EOF >> user-config.jam
|
||
|
using python : : ${python.interpreter}
|
||
|
: ${python}/include/python${python.pythonVersion}
|
||
|
: ${python}/lib
|
||
|
;
|
||
|
EOF
|
||
|
'';
|
||
|
|
||
|
NIX_CFLAGS_LINK = lib.optionalString stdenv.isDarwin
|
||
|
"-headerpad_max_install_names";
|
||
|
|
||
|
enableParallelBuilding = true;
|
||
|
|
||
|
nativeBuildInputs = [ which boost-build ]
|
||
|
++ lib.optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames;
|
||
|
buildInputs = [ expat zlib bzip2 libiconv ]
|
||
|
++ lib.optional (lib.versionAtLeast version "1.69") zstd
|
||
|
++ [ xz ]
|
||
|
++ lib.optional enableIcu icu
|
||
|
++ lib.optionals enablePython [ libxcrypt python ]
|
||
|
++ lib.optional enableNumpy python.pkgs.numpy;
|
||
|
|
||
|
configureScript = "./bootstrap.sh";
|
||
|
configurePlatforms = [];
|
||
|
dontDisableStatic = true;
|
||
|
dontAddStaticConfigureFlags = true;
|
||
|
configureFlags = [
|
||
|
"--includedir=$(dev)/include"
|
||
|
"--libdir=$(out)/lib"
|
||
|
"--with-bjam=b2" # prevent bootstrapping b2 in configurePhase
|
||
|
] ++ lib.optional (toolset != null) "--with-toolset=${toolset}"
|
||
|
++ [ (if enableIcu then "--with-icu=${icu.dev}" else "--without-icu") ];
|
||
|
|
||
|
buildPhase = ''
|
||
|
runHook preBuild
|
||
|
b2 ${b2Args}
|
||
|
runHook postBuild
|
||
|
'';
|
||
|
|
||
|
installPhase = ''
|
||
|
runHook preInstall
|
||
|
|
||
|
# boostbook is needed by some applications
|
||
|
mkdir -p $dev/share/boostbook
|
||
|
cp -a tools/boostbook/{xsl,dtd} $dev/share/boostbook/
|
||
|
|
||
|
# Let boost install everything else
|
||
|
b2 ${b2Args} install
|
||
|
|
||
|
runHook postInstall
|
||
|
'';
|
||
|
|
||
|
postFixup = ''
|
||
|
# Make boost header paths relative so that they are not runtime dependencies
|
||
|
cd "$dev" && find include \( -name '*.hpp' -or -name '*.h' -or -name '*.ipp' \) \
|
||
|
-exec sed '1s/^\xef\xbb\xbf//;1i#line 1 "{}"' -i '{}' \;
|
||
|
'' + lib.optionalString stdenv.hostPlatform.isMinGW ''
|
||
|
$RANLIB "$out/lib/"*.a
|
||
|
'';
|
||
|
|
||
|
outputs = [ "out" "dev" ];
|
||
|
setOutputFlags = false;
|
||
|
}
|