From 0ceb158a9c610a017a1cf5298b58d469cf0d7646 Mon Sep 17 00:00:00 2001
From: Greg Burd <greg@burd.me>
Date: Mon, 24 Aug 2026 12:53:12 -0400
Subject: [PATCH v1] 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 and add a file that goes stale in
the tree. The flake instead tracks whatever nixpkgs the developer already
runs; anyone needing reproducibility can generate a lock locally.
---
 flake.nix | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 261 insertions(+)
 create mode 100644 flake.nix

diff --git a/flake.nix b/flake.nix
new file mode 100644
index 00000000000..ab376df4a76
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,261 @@
+{
+  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`: full toolchain for configure/make, meson, docs,
+      # TAP tests, and all three PLs — regardless of which features a
+      # given build enables.
+      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
+            libxslt
+            meson
+            ninja
+            perl
+            python3
+            tcl
+          ];
+        };
+      });
+
+      formatter = forAllSystems (pkgs: pkgs.nixfmt);
+    };
+}
-- 
2.54.0

