From: Greg Burd <greg@burd.me>
To: Tom Lane <tgl@sss.pgh.pa.us>
To: Andrew Dunstan <andrew@dunslane.net>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Subject: Re: Add a Nix flake
Date: Wed, 26 Aug 2026 01:33:18 -0400
Message-ID: <b6156ff0-d924-4a54-b4ef-7857da2dbc6a@app.fastmail.com> (raw)
In-Reply-To: <618056.1787663948@sss.pgh.pa.us>
References: <a0979d2a-4670-44fe-864f-c0425edbd4f1@app.fastmail.com>
<58ed7628-7527-450d-8acc-b14a322e9375@dunslane.net>
<618056.1787663948@sss.pgh.pa.us>
On Tue Aug 25, 2026 at 6:37 AM CDT, Andrew Dunstan wrote:
> Well, "growing" could cover a multitude of possibilities. It could mean
> there was one and now there are two. [...] But if you want to say that
> there is a significant number of people actually contributing here who
> use it that would be all the better for some evidence.
Fair, and I shouldn't have leaned on an unquantified "growing." Let me
separate what I can back up from what I can't.
What I can point to concretely:
- There is already an active pgsql-hackers thread, "Building with meson on
NixOS/nixpkgs," [1] where the Meson build was adjusted specifically
because of problems Nix/NixOS packagers hit. So Nix is already shaping
build-related decisions here whether or not we carry a flake.
- Wolfgang Walther maintains the PostgreSQL packaging in nixpkgs and has
posted here on exactly these issues.
- Supabase's fork use Nix extensively. [2]
- I keep a flake setup that I re-apply/use to enable predictable efficient
development cross-platform.
- Tristan (upthread) keeps a private flake and a NixOS-based buildfarm
client.
What I can't do is hand you a survey. I don't have a count of contributors
who develop on Nix, and I'd rather admit that than dress up a guess. If the
bar for this is demonstrated contributor demand, that's a reasonable bar and
I'm happy to let the thread be the evidence, if it's just me and Tristan, so
be it; this can wait.
> Historically we've been fairly resistant to carrying things related to
> how people build or develop postgres.
Understood, and I don't want to relitigate that policy. The narrower claim
I'd make is that a flake is closer to the .editorconfig / .dir-locals.el end
of the spectrum (declare-the-environment) than to endorsing a build system,
it doesn't touch configure, Meson, or the Makefiles. But I take the point
that the door being narrow is deliberate.
On Tue Aug 25, 2026 at 8:19 AM CDT, Tom Lane wrote:
> I might hold my nose if the effects extended only to one more root-level
> file (although that's not great). But if we're talking about rather
> expansive .gitexclude patterns, I'm going to push back on the grounds of
> possible unforeseen side-effects on other peoples' work.
That's a fair objection and easy to remove: v3 (attached) is exactly one new
root-level file, flake.nix, and nothing else. I've dropped the .gitignore
changes entirely.
For what it's worth on side-effects: the patterns I'd proposed were
root-anchored (/flake.lock, /result, /result-*), the same shape as the
existing /tmp_install/ and /portlock/ lines, so they couldn't have matched a
result/ elsewhere in the tree. But that's beside the point now, they're gone.
The build artifacts belong in each developer's own $GIT_DIR/info/exclude,
which is precisely what the .gitignore header already recommends for "files
from local workflows"; `nix build -o` can also just name the symlink. No
committed-ignore changes needed.
So the question really does reduce to your "one more root-level file, though
that's not great." I won't pretend that's nothing. If the consensus is that
even one file is more build/dev tooling than the tree wants to carry, I'll
accept that outcome, but if it's going to live somewhere, one self-contained
file at the root is the smallest footprint I can offer.
best.
-greg
[1] https://pg.ddx.io/m/pgsql-hackers/5d6b6485-9eff-44a0-99ac-661fdeb72a21@technowledgy.de/T/
[2] https://github.com/supabase/postgres/blob/develop/flake.nixAttachments:
[text/x-patch] v3-0001-Add-a-Nix-flake-for-reproducible-builds-and-dev-s.patch (12.2K, ../b6156ff0-d924-4a54-b4ef-7857da2dbc6a@app.fastmail.com/2-v3-0001-Add-a-Nix-flake-for-reproducible-builds-and-dev-s.patch)
download | inline diff:
From 83273f384bbf7d98418578697c3406e1c0699f73 Mon Sep 17 00:00:00 2001
From: Greg Burd <greg@burd.me>
Date: Tue, 25 Aug 2026 15:34:06 -0400
Subject: [PATCH v3] Add a Nix flake for reproducible builds and dev shells
Provide a flake.nix at the repository root so contributors on Nix-based
systems (Linux, macOS, and increasingly BSD and illumos) get a single,
in-tree starting point instead of maintaining private, drifting copies.
It doesn't add a build system: `nix develop` drops you into a shell with
bison, flex, perl, the optional libraries, and the docs toolchain on PATH,
where `meson setup` (the default) or `./configure` just works; `nix build`
produces a server.
Every optional configure/Meson feature is a boolean toggle with
platform-appropriate defaults (io_uring, libnuma, systemd, PAM on Linux;
Bonjour on macOS), so it is a starting point, not a policy. Presets cover
debug, minimal, and autoconf builds.
No flake.lock is committed on purpose: pinning nixpkgs would freeze
contributors to one dependency snapshot. The flake instead tracks whatever
nixpkgs the developer already runs; anyone needing reproducibility can
generate a lock locally.
This touches only a single new root-level file. Build artifacts
(flake.lock, result symlinks) are left to each developer's local ignore
($GIT_DIR/info/exclude), as the .gitignore header already recommends for
files from local workflows; `nix build -o` can also name the symlink.
---
flake.nix | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 257 insertions(+)
create mode 100644 flake.nix
diff --git a/flake.nix b/flake.nixnew file mode 100644index 00000000000..7c113cdedc8--- /dev/null+++ b/flake.nix@@ -0,0 +1,257 @@+{+ description = "PostgreSQL, built from this source tree";++ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";++ outputs =+ { self, nixpkgs }:+ let+ systems = [+ "x86_64-linux"+ "aarch64-linux"+ "x86_64-darwin"+ "aarch64-darwin"+ ];+ forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});++ # A single builder covering every optional feature ./configure and+ # meson expose. Each feature is a boolean toggle wired to its+ # buildInput + flag; flip any of them via .override { ... }.+ # Platform-specific features default to their availability.+ postgresqlFor =+ pkgs:+ let+ inherit (pkgs) lib stdenv;+ onLinux = stdenv.hostPlatform.isLinux;+ onDarwin = stdenv.hostPlatform.isDarwin;+ in+ lib.makeOverridable (+ {+ # Build system: "meson" (ninja) or "autoconf" (configure/make).+ # Meson is the default; it is the project's eventual sole build system.+ buildSystem ? "meson",++ # Optional library features (buildInput + flag).+ icuSupport ? true,+ readlineSupport ? true,+ zlibSupport ? true,+ opensslSupport ? true,+ libxmlSupport ? true,+ libxsltSupport ? true,+ lz4Support ? true,+ zstdSupport ? true,+ uuidSupport ? true,+ curlSupport ? true,++ # Procedural languages.+ perlSupport ? true,+ pythonSupport ? true,+ tclSupport ? true,++ # Platform-gated features.+ systemdSupport ? onLinux,+ selinuxSupport ? false,+ liburingSupport ? onLinux,+ numaSupport ? onLinux,+ gssSupport ? true,+ ldapSupport ? false,+ pamSupport ? onLinux,+ bonjourSupport ? onDarwin,+ llvmSupport ? false,++ # Developer / build-shape toggles (no extra deps).+ cassert ? false,+ debugSymbols ? false,+ tapTests ? true,+ injectionPoints ? false,++ # Documentation build (SGML/DocBook toolchain).+ docs ? false,+ }:+ let+ useMeson = buildSystem == "meson";++ # feature -> { flag = configure arg; dep = buildInput or null; }+ featureFlag = cond: flag: lib.optional cond flag;+ featureDep = cond: dep: lib.optional cond dep;++ configureFeatures = lib.flatten [+ (featureFlag icuSupport "--with-icu")+ (featureFlag (!icuSupport) "--without-icu")+ (featureFlag (!readlineSupport) "--without-readline")+ (featureFlag (!zlibSupport) "--without-zlib")+ (featureFlag opensslSupport "--with-ssl=openssl")+ (featureFlag libxmlSupport "--with-libxml")+ (featureFlag libxsltSupport "--with-libxslt")+ (featureFlag lz4Support "--with-lz4")+ (featureFlag zstdSupport "--with-zstd")+ (featureFlag uuidSupport "--with-uuid=e2fs")+ (featureFlag curlSupport "--with-libcurl")+ (featureFlag perlSupport "--with-perl")+ (featureFlag pythonSupport "--with-python")+ (featureFlag tclSupport "--with-tcl")+ (featureFlag systemdSupport "--with-systemd")+ (featureFlag selinuxSupport "--with-selinux")+ (featureFlag liburingSupport "--with-liburing")+ (featureFlag numaSupport "--with-libnuma")+ (featureFlag gssSupport "--with-gssapi")+ (featureFlag ldapSupport "--with-ldap")+ (featureFlag pamSupport "--with-pam")+ (featureFlag bonjourSupport "--with-bonjour")+ (featureFlag llvmSupport "--with-llvm")+ (featureFlag cassert "--enable-cassert")+ (featureFlag debugSymbols "--enable-debug")+ (featureFlag tapTests "--enable-tap-tests")+ (featureFlag injectionPoints "--enable-injection-points")+ ];++ # meson uses -Dfeature=enabled/disabled instead of --with-*.+ mesonFeatures = lib.flatten [+ [ "-Dicu=${if icuSupport then "enabled" else "disabled"}" ]+ [ "-Dreadline=${if readlineSupport then "enabled" else "disabled"}" ]+ [ "-Dzlib=${if zlibSupport then "enabled" else "disabled"}" ]+ [ "-Dssl=${if opensslSupport then "openssl" else "none"}" ]+ [ "-Dlibxml=${if libxmlSupport then "enabled" else "disabled"}" ]+ [ "-Dlibxslt=${if libxsltSupport then "enabled" else "disabled"}" ]+ [ "-Dlz4=${if lz4Support then "enabled" else "disabled"}" ]+ [ "-Dzstd=${if zstdSupport then "enabled" else "disabled"}" ]+ [ "-Duuid=${if uuidSupport then "e2fs" else "none"}" ]+ [ "-Dlibcurl=${if curlSupport then "enabled" else "disabled"}" ]+ [ "-Dplperl=${if perlSupport then "enabled" else "disabled"}" ]+ [ "-Dplpython=${if pythonSupport then "enabled" else "disabled"}" ]+ [ "-Dpltcl=${if tclSupport then "enabled" else "disabled"}" ]+ [ "-Dsystemd=${if systemdSupport then "enabled" else "disabled"}" ]+ [ "-Dselinux=${if selinuxSupport then "enabled" else "disabled"}" ]+ [ "-Dliburing=${if liburingSupport then "enabled" else "disabled"}" ]+ [ "-Dlibnuma=${if numaSupport then "enabled" else "disabled"}" ]+ [ "-Dgssapi=${if gssSupport then "enabled" else "disabled"}" ]+ [ "-Dldap=${if ldapSupport then "enabled" else "disabled"}" ]+ [ "-Dpam=${if pamSupport then "enabled" else "disabled"}" ]+ [ "-Dbonjour=${if bonjourSupport then "enabled" else "disabled"}" ]+ [ "-Dllvm=${if llvmSupport then "enabled" else "disabled"}" ]+ [ "-Dcassert=${lib.boolToString cassert}" ]+ [ "-Dtap_tests=${if tapTests then "enabled" else "disabled"}" ]+ [ "-Dinjection_points=${lib.boolToString injectionPoints}" ]+ ];++ buildInputs = lib.flatten (with pkgs; [+ (featureDep icuSupport icu)+ (featureDep readlineSupport readline)+ (featureDep zlibSupport zlib)+ (featureDep opensslSupport openssl)+ (featureDep libxmlSupport libxml2)+ (featureDep libxsltSupport libxslt)+ (featureDep lz4Support lz4)+ (featureDep zstdSupport zstd)+ (featureDep uuidSupport libuuid)+ (featureDep curlSupport curl)+ (featureDep perlSupport perl)+ (featureDep pythonSupport python3)+ (featureDep tclSupport tcl)+ (featureDep systemdSupport systemdLibs)+ (featureDep selinuxSupport libselinux)+ (featureDep liburingSupport liburing)+ (featureDep numaSupport numactl)+ (featureDep gssSupport libkrb5)+ (featureDep ldapSupport openldap)+ (featureDep pamSupport linux-pam)+ (featureDep llvmSupport llvmPackages.llvm)+ ]);+ in+ stdenv.mkDerivation {+ pname = "postgresql";+ version = "20devel";+ src = self;++ strictDeps = true;++ nativeBuildInputs = lib.flatten (with pkgs; [+ bison+ flex+ perl+ pkg-config+ (featureDep useMeson meson)+ (featureDep useMeson ninja)+ (featureDep llvmSupport llvmPackages.llvm.dev)+ (featureDep docs docbook-xsl-nons)+ (featureDep docs docbook_xml_dtd_45)+ (featureDep docs libxslt)+ ]);++ inherit buildInputs;++ # ---- autoconf path ----+ configureFlags = lib.optionals (!useMeson) configureFeatures;++ # ---- meson path ----+ mesonBuildType = "release";+ mesonFlags = lib.optionals useMeson mesonFeatures;+ dontUseMesonConfigure = !useMeson;+ mesonAutoFeatures = "disabled";++ enableParallelBuilding = true;+ doCheck = tapTests;++ meta = with lib; {+ description = "Object-relational database management system, built from source";+ homepage = "https://www.postgresql.org/";+ license = licenses.postgresql;+ platforms = platforms.unix;+ mainProgram = "psql";+ };+ }+ )+ { };+ in+ {+ packages = forAllSystems (pkgs: rec {+ postgresql = postgresqlFor pkgs;+ # Common presets built on top of the fully-parameterized default.+ postgresql-autoconf = postgresql.override { buildSystem = "autoconf"; };+ postgresql-debug = postgresql.override {+ cassert = true;+ debugSymbols = true;+ injectionPoints = true;+ };+ postgresql-minimal = postgresql.override {+ icuSupport = false;+ readlineSupport = false;+ zlibSupport = false;+ opensslSupport = false;+ libxmlSupport = false;+ libxsltSupport = false;+ lz4Support = false;+ zstdSupport = false;+ uuidSupport = false;+ curlSupport = false;+ perlSupport = false;+ pythonSupport = false;+ tclSupport = false;+ systemdSupport = false;+ liburingSupport = false;+ numaSupport = false;+ gssSupport = false;+ pamSupport = false;+ };+ default = postgresql;+ });++ # `nix develop`: the postgresql package already brings in the full+ # build toolchain (meson, ninja, bison, flex, perl, python3, tcl, and+ # the optional libraries) via inputsFrom. We add only what a dev shell+ # wants on top: ccache, and the DocBook toolchain for building docs+ # (docs are off in the default package build).+ devShells = forAllSystems (pkgs: {+ default = pkgs.mkShell {+ inputsFrom = [ self.packages.${pkgs.stdenv.hostPlatform.system}.postgresql ];+ packages = with pkgs; [+ ccache+ docbook_xml_dtd_45+ docbook-xsl-nons+ ];+ };+ });++ formatter = forAllSystems (pkgs: pkgs.nixfmt);+ };+}--
2.54.0
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: greg@burd.me, tgl@sss.pgh.pa.us, andrew@dunslane.net, pgsql-hackers@lists.postgresql.org
Subject: Re: Add a Nix flake
In-Reply-To: <b6156ff0-d924-4a54-b4ef-7857da2dbc6a@app.fastmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox