Files
postgrest/nix/static.nix
T
Wolfgang Walther caf0a70171 nix: Clarify pkg-config usage in static.nix a bit
This will make it easier to make the switch from pkgsCross.libpq to pkgsStatic.libpq,
once that is possible to build upstream - if ever.
2024-02-24 12:08:40 +01:00

96 lines
3.6 KiB
Nix

{ compiler
, name
, pkgs
, src
}:
let
# This builds a static PostgREST exectuable based on pkgsStatic.
# pkgsStatic is based on musl, so is a kind of cross-compilation.
# We still make this explicit here via pkgsCross, because we need
# to get postgresql/libpq for musl, too.
pkgsCross = pkgs.pkgsCross.musl64;
inherit (pkgsCross) pkgsStatic;
inherit (pkgsStatic.haskell) lib;
packagesStatic =
pkgsStatic.haskell.packages."${compiler}".override (old: {
ghc = pkgsStatic.pkgsBuildHost.haskell.compiler."${compiler}".override {
# Using the bundled libffi generally works better for cross-compiling
libffi = null;
# Building sphinx fails on some platforms
enableDocs = false;
# Cross compiling with native bignum works better than with gmp
enableNativeBignum = true;
};
overrides = pkgs.lib.composeExtensions old.overrides (final: prev: {
postgresql-libpq = (prev.postgresql-libpq.override {
# postgresql doesn't build in the fully static overlay - but the default
# derivation is built with static libraries anyway.
postgresql = pkgsCross.libpq;
}).overrideAttrs (finalAttrs: prevAttrs: {
# Using use-pkg-config flag, because pg_config won't work when cross-compiling
configureFlags = prevAttrs.configureFlags ++ [
"-fuse-pkg-config"
"--with-pkg-config=${pkgsStatic.pkgsBuildHost.pkg-config}/bin/${pkgsStatic.targetPlatform.config}-pkg-config"
];
# This needs to match where libpq is coming from above.
nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ pkgsCross.pkgsBuildHost.pkg-config ];
buildInputs = prevAttrs.buildInputs ++ [
(pkgsStatic.libkrb5.overrideAttrs (finalAttrs: prevAttrs: {
configureFlags = prevAttrs.configureFlags ++ [
"--sysconfdir=/etc"
# disable keyutils dependency, to avoid linking errors
"--without-keyutils"
];
postInstall = prevAttrs.postInstall + ''
${pkgsStatic.pkgsBuildHost.removeReferencesTo}/bin/remove-references-to -t $out $out/lib/*.a
'';
}))
];
});
});
});
makeExecutableStatic = drv: pkgs.lib.pipe drv [
(lib.compose.appendConfigureFlags [ "--enable-executable-static" ])
lib.compose.justStaticExecutables
# To successfully compile a redistributable, fully static executable we need to:
# 1. make executable really statically linked.
# 2. avoid any references to /nix/store to prevent blowing up the closure size.
# 3. be able to run the executable.
# When checking for references, we ignore the following:
# - eeee... are removed references which don't actually exist
# - openssl-etc references are purposely designed to be very small
(lib.compose.overrideCabal (drv: {
postFixup = drv.postFixup + ''
exe="$out/bin/postgrest"
if ! (file "$exe" | grep 'statically linked') then
echo "not a static executable, ldd output:"
ldd "$exe"
exit 1
fi
echo "Checking for references to /nix/store..."
(${pkgsStatic.binutils}/bin/strings "$exe" \
| grep -v /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee \
| grep -v -etc/etc/ssl \
| grep /nix/store || exit 0 && exit 1)
echo "No references to /nix/store found"
"$exe" --help
'';
}))
];
in
{
inherit packagesStatic;
postgrestStatic = makeExecutableStatic (packagesStatic.callCabal2nix name src { });
}