nix: Build static postgrest executable via pkgsStatic

This replaces the build via static-haskell-nix and will hopefully make
it possible to cross compile in the future.
This commit is contained in:
Wolfgang Walther
2024-01-26 17:17:05 +01:00
committed by Wolfgang Walther
parent 3a639c7172
commit 259d97acee
10 changed files with 74 additions and 172 deletions
+4 -16
View File
@@ -36,7 +36,7 @@ let
allOverlays.build-toolbox
allOverlays.checked-shell-script
allOverlays.gitignore
(allOverlays.postgresql-default { inherit patches; })
allOverlays.postgresql-default
allOverlays.postgresql-legacy
allOverlays.postgresql-future
allOverlays.postgis
@@ -60,23 +60,11 @@ let
{ name = "postgresql-9.6"; postgresql = pkgs.postgresql_9_6.withPackages (p: [ p.postgis p.pg_safeupdate ]); }
];
patches =
pkgs.callPackage nix/patches { };
# Dynamic derivation for PostgREST
postgrest =
pkgs.haskell.packages."${compiler}".callCabal2nix name src { };
# Functionality that derives a fully static Haskell package based on
# nh2/static-haskell-nix
staticHaskellPackage =
import nix/static-haskell-package.nix { inherit nixpkgs system compiler patches allOverlays; };
# Static executable.
postgrestStatic =
lib.justStaticExecutables (lib.dontCheck (staticHaskellPackage name src).package);
packagesStatic = (staticHaskellPackage name src).survey;
staticHaskellPackage = import nix/static.nix { inherit compiler name pkgs src; };
# Options passed to cabal in dev tools and tests
devCabalOptions =
@@ -160,8 +148,8 @@ rec {
};
} // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux rec {
# Static executable.
inherit postgrestStatic;
inherit packagesStatic;
inherit (staticHaskellPackage) postgrestStatic;
inherit (staticHaskellPackage) packagesStatic;
# Docker images and loading script.
docker =
-9
View File
@@ -33,15 +33,6 @@ postgrest-nixpkgs-upgrade
```
## Update pinned version of `static-haskell-nix`
We pin [`static-haskell-nix`](https://github.com/nh2/static-haskell-nix) in
[`nix/static-haskell-package.nix`](static-haskell-package.nix). Upgrade the
pinned revision and the tarball hash if necessary. See
[`nix/nixpkgs-upgrade.nix`](nixpkgs-upgrade.nix) for how to get the correct
tarball hash, or just change the hash to an arbitrary value of correct length,
run `nix-build` and use the expected value from the resulting error message.
## Review overlays
Check whether the individual [overlays](overlays) are still required.
+2 -5
View File
@@ -1,8 +1,5 @@
{ patches }: self: super:
self: super:
# Overlay that sets the default version of PostgreSQL.
with patches;
{
postgresql = super.postgresql_15.overrideAttrs ({ patches ? [ ], ... }: {
patches = patches ++ [ postgresql-atexit ];
});
postgresql = super.postgresql_15;
}
-29
View File
@@ -1,29 +0,0 @@
{ runCommand }:
{
applyPatches =
name: src: patches:
runCommand
name
{ inherit src patches; }
''
set -eou pipefail
cp -r $src $out
chmod -R u+w $out
for patch in $patches; do
echo "Applying patch $patch"
patch -d "$out" -p1 < "$patch"
done
'';
static-haskell-nix-ncurses =
./static-haskell-nix-ncurses.patch;
static-haskell-nix-ghc-bignum =
./static-haskell-nix-ghc-bignum.patch;
static-haskell-nix-openssl =
./static-haskell-nix-openssl.patch;
postgresql-atexit =
./postgresql-atexit.patch;
}
-11
View File
@@ -1,11 +0,0 @@
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -118,7 +118,7 @@ backend_src = $(top_srcdir)/src/backend
libpq-refs-stamp: $(shlib)
ifneq ($(enable_coverage), yes)
ifeq (,$(filter aix solaris,$(PORTNAME)))
- @if nm -A -u $< 2>/dev/null | grep -v __cxa_atexit | grep exit; then \
+ @if nm -A -u $< 2>/dev/null | grep " exit"; then \
echo 'libpq must not be calling any function which invokes exit'; exit 1; \
fi
endif
@@ -1,12 +0,0 @@
diff --git a/survey/default.nix b/survey/default.nix
index 70afbbc..28cb0e9 100644
--- a/survey/default.nix
+++ b/survey/default.nix
@@ -81,6 +81,7 @@ let
# `.override` and the likes).
isProperHaskellPackage = val:
lib.isDerivation val && # must pass lib.isDerivation
+ val.pname != "ghc-bignum" &&
val ? env; # must have an .env key
# Function that tells us if a given Haskell package has an executable.
@@ -1,13 +0,0 @@
diff --git a/survey/default.nix b/survey/default.nix
index 46d8066..a47f214 100644
--- a/survey/default.nix
+++ b/survey/default.nix
@@ -1519,7 +1519,7 @@ let
[
"--enable-executable-static" # requires `useFixedCabal`
# `enableShared` seems to be required to avoid `recompile with -fPIC` errors on some packages.
- "--extra-lib-dirs=${final.ncurses.override { enableStatic = true; enableShared = true; }}/lib"
+ "--extra-lib-dirs=${final.ncurses.override { enableStatic = true; }}/lib"
]
# TODO Figure out why this and the below libffi are necessary.
# `working` and `workingStackageExecutables` don't seem to need that,
@@ -1,12 +0,0 @@
diff --git a/survey/default.nix b/survey/default.nix
index cf1bd31..9d34753 100644
--- a/survey/default.nix
+++ b/survey/default.nix
@@ -736,6 +736,7 @@ let
openblas = previous.openblas.override { enableStatic = true; };
openssl = previous.openssl.override { static = true; };
+ openssl_1_1 = previous.openssl_1_1.override { static = true; };
libsass = previous.libsass.overrideAttrs (old: { dontDisableStatic = true; });
-65
View File
@@ -1,65 +0,0 @@
# Derive a fully static Haskell package based on musl instead of glibc.
{ nixpkgs, system, compiler, patches, allOverlays }:
name: src:
let
# The nh2/static-haskell-nix project does all the hard work for us.
static-haskell-nix =
let
rev = "bd66b86b72cff4479e1c76d5916a853c38d09837";
in
builtins.fetchTarball {
url = "https://github.com/nh2/static-haskell-nix/archive/${rev}.tar.gz";
sha256 = "0rnsxaw7v27znsg9lgqk1i4007ydqrc8gfgimrmhf24lv6galbjh";
};
patched-static-haskell-nix =
patches.applyPatches "patched-static-haskell-nix"
static-haskell-nix
[
patches.static-haskell-nix-ncurses
patches.static-haskell-nix-ghc-bignum
patches.static-haskell-nix-openssl
];
extraOverrides =
final: prev:
rec {
# We need to add our package needs to the package set that we pass to
# static-haskell-nix. Using callCabal2nix on the haskellPackages that
# it returns would result in a dynamic build based on musl, and not the
# fully static build that we want.
"${name}" = prev.callCabal2nix name src { };
};
overlays =
[
allOverlays.postgresql-future
(allOverlays.postgresql-default { inherit patches; })
(allOverlays.haskell-packages { inherit compiler extraOverrides; })
# Disable failing tests for postgresql on musl that should have no impact
# on the libpq that we need (collate.icu.utf8 and foreign regression
# tests)
(self: super:
{ postgresql = super.postgresql.overrideAttrs (_: { doCheck = false; }); }
)
];
# Apply our overlay to nixpkgs.
normalPkgs =
import nixpkgs { inherit overlays system; };
defaultCabalPackageVersionComingWithGhc =
{
ghc948 = "Cabal_3_8_1_0";
}."${compiler}";
# The static-haskell-nix 'survey' derives a full static set of Haskell
# packages, applying fixes where necessary.
survey =
import "${patched-static-haskell-nix}/survey" { inherit normalPkgs compiler defaultCabalPackageVersionComingWithGhc; };
in
{
inherit survey;
package = survey.haskellPackages."${name}";
}
+68
View File
@@ -0,0 +1,68 @@
{ 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;
# postgresql doesn't build in the fully static overlay - but the default
# derivation is built with static libraries anyway.
libpq = (pkgsCross.postgresql.override {
# disable server-side only stuff to improve compilation times
enableSystemd = false;
jitSupport = false;
# disable gssapi support, because it leads to linking errors
gssSupport = false;
}).overrideAttrs (finalAttrs: prevAttrs: {
dontDisableStatic = true;
# Tests fail for initdb and other server-side code which we don't care about
doCheck = false;
});
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 = libpq;
}).overrideAttrs (finalAttrs: prevAttrs: {
# Using use-pkg-config flag, because pg_config won't work when cross-compiling
configureFlags = prevAttrs.configureFlags ++ [ "-fuse-pkg-config" ];
# Using pkg-config without pkgsCross, because "pkg-config" is hardcoded in
# postgresql-libpq's Setup.hs. Using pkgsStatic to make pkg-config return the
# static libs for libpq.
nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ pkgs.pkgsStatic.pkg-config ];
buildInputs = [
pkgsStatic.openssl
];
});
});
});
makeExecutableStatic = drv:
lib.justStaticExecutables
(lib.appendConfigureFlag drv "--enable-executable-static");
in
{
inherit packagesStatic;
postgrestStatic = makeExecutableStatic (packagesStatic.callCabal2nix name src { });
}