diff --git a/pkgs/servers/sql/postgresql/14.nix b/pkgs/servers/sql/postgresql/14.nix index 184d0a7b3b73..04c9628ceb66 100644 --- a/pkgs/servers/sql/postgresql/14.nix +++ b/pkgs/servers/sql/postgresql/14.nix @@ -1,4 +1,4 @@ -import ./generic.nix { +{ version = "14.23"; rev = "refs/tags/REL_14_23"; hash = "sha256-fjoboaUhrHFDqusmIXzSS5ZnIpSRHO9+qcqvkchl2dM="; diff --git a/pkgs/servers/sql/postgresql/15.nix b/pkgs/servers/sql/postgresql/15.nix index 633131478a21..084b353c00ec 100644 --- a/pkgs/servers/sql/postgresql/15.nix +++ b/pkgs/servers/sql/postgresql/15.nix @@ -1,4 +1,4 @@ -import ./generic.nix { +{ version = "15.18"; rev = "refs/tags/REL_15_18"; hash = "sha256-tw1zzgLXx7Jr4bi8rMKRmTJzOSQFGvrP2nHr9FcVrjs="; diff --git a/pkgs/servers/sql/postgresql/16.nix b/pkgs/servers/sql/postgresql/16.nix index 22027d48d97c..83fa3acab5d1 100644 --- a/pkgs/servers/sql/postgresql/16.nix +++ b/pkgs/servers/sql/postgresql/16.nix @@ -1,4 +1,4 @@ -import ./generic.nix { +{ version = "16.14"; rev = "refs/tags/REL_16_14"; hash = "sha256-g2+OdB2dGIKBSFJ24Z3Yy7oRAFywNMSVDdWfnsaeJJQ="; diff --git a/pkgs/servers/sql/postgresql/17.nix b/pkgs/servers/sql/postgresql/17.nix index c5298a23de81..0f5eb20d649c 100644 --- a/pkgs/servers/sql/postgresql/17.nix +++ b/pkgs/servers/sql/postgresql/17.nix @@ -1,4 +1,4 @@ -import ./generic.nix { +{ version = "17.10"; rev = "refs/tags/REL_17_10"; hash = "sha256-3ZAqlT3R8ywhNH13oqz2VUbSwpOJ2JaICbxZ29awaMw="; diff --git a/pkgs/servers/sql/postgresql/18.nix b/pkgs/servers/sql/postgresql/18.nix index 4d70b2474f27..1bccfcc412a0 100644 --- a/pkgs/servers/sql/postgresql/18.nix +++ b/pkgs/servers/sql/postgresql/18.nix @@ -1,4 +1,4 @@ -import ./generic.nix { +{ version = "18.4"; rev = "refs/tags/REL_18_4"; hash = "sha256-Ac/Dqcj8vjcW3my5vsnKaMiQqTq/HPtUzckJ3SMyrfA="; diff --git a/pkgs/servers/sql/postgresql/19.nix b/pkgs/servers/sql/postgresql/19.nix index 50862f58f4ab..9ee9780fbfa5 100644 --- a/pkgs/servers/sql/postgresql/19.nix +++ b/pkgs/servers/sql/postgresql/19.nix @@ -1,4 +1,4 @@ -import ./generic.nix { +{ version = "19beta1"; rev = "refs/tags/REL_19_BETA1"; hash = "sha256-thvbttX8wwGLf5tMJRHl86Xv8OgINzahoqB/AzAdtMI="; diff --git a/pkgs/servers/sql/postgresql/default.nix b/pkgs/servers/sql/postgresql/default.nix index 7fe28ef140fd..c8c57ec7ae76 100644 --- a/pkgs/servers/sql/postgresql/default.nix +++ b/pkgs/servers/sql/postgresql/default.nix @@ -23,7 +23,7 @@ let version: path: let attrName = if jitSupport then "${version}_jit" else version; - postgresql = import path { inherit self; }; + postgresql = self.callPackage ./generic.nix (import path // { inherit self; }); attrValue = if jitSupport then postgresql.withJIT else postgresql; in self.lib.nameValuePair attrName attrValue diff --git a/pkgs/servers/sql/postgresql/generic.nix b/pkgs/servers/sql/postgresql/generic.nix index c4e17fa1ec11..8332f4d4e2de 100644 --- a/pkgs/servers/sql/postgresql/generic.nix +++ b/pkgs/servers/sql/postgresql/generic.nix @@ -1,608 +1,598 @@ +{ + # utils + stdenv, + fetchFromGitHub, + fetchurl, + lib, + replaceVars, + + # source specification + hash, + muslPatches ? { }, + rev, + version, + + # runtime dependencies + darwin, + freebsd, + glibc, + libuuid, + libxml2, + lz4, + openssl, + readline, + tzdata, + zlib, + zstd, + + # build dependencies + bison, + docbook-xsl-nons, + docbook_xml_dtd_45, + flex, + libxslt, + makeBinaryWrapper, + pkg-config, + removeReferencesTo, + + # passthru + buildPackages, + newScope, + nixosTests, + self, + testers, + + # Block size + # Changing the block size will break on-disk database compatibility. See: + # https://www.postgresql.org/docs/current/install-make.html#CONFIGURE-OPTION-WITH-BLOCKSIZE + withBlocksize ? null, + withWalBlocksize ? null, + + # bonjour + bonjourSupport ? false, + + # Curl + curlSupport ? lib.versionAtLeast version "18" && lib.meta.availableOn stdenv.hostPlatform curl, + curl, + + # GSSAPI + gssSupport ? with stdenv.hostPlatform; !isWindows, + libkrb5, + + # icu + icuSupport ? true, + icu, + + # JIT + jitSupport ? stdenv.hostPlatform.canExecute stdenv.buildPlatform, + llvmPackages, + nukeReferences, + overrideCC, + + # LDAP + ldapSupport ? false, + openldap, + + # NLS + nlsSupport ? false, + gettext, + + # NUMA + numaSupport ? lib.versionAtLeast version "18" && lib.meta.availableOn stdenv.hostPlatform numactl, + numactl, + + # PAM + pamSupport ? lib.meta.availableOn stdenv.hostPlatform linux-pam, + linux-pam, + + # PL/Perl + perlSupport ? + lib.meta.availableOn stdenv.hostPlatform perl + # configure tries to call the perl executable for the version + && stdenv.buildPlatform.canExecute stdenv.hostPlatform, + perl, + + # PL/Python + pythonSupport ? + lib.meta.availableOn stdenv.hostPlatform python3 + # configure tries to call the python executable + && stdenv.buildPlatform.canExecute stdenv.hostPlatform, + python3, + + # PL/Tcl + tclSupport ? + lib.meta.availableOn stdenv.hostPlatform tcl + # configure fails with: + # configure: error: file 'tclConfig.sh' is required for Tcl + && stdenv.buildPlatform.canExecute stdenv.hostPlatform, + tcl, + + # SELinux + selinuxSupport ? false, + libselinux, + + # Systemd + systemdSupport ? lib.meta.availableOn stdenv.hostPlatform systemdLibs, + systemdLibs, + + # Uring + uringSupport ? lib.versionAtLeast version "18" && lib.meta.availableOn stdenv.hostPlatform liburing, + liburing, +}@args: let + atLeast = lib.versionAtLeast version; + olderThan = lib.versionOlder version; + lz4Enabled = atLeast "14"; + zstdEnabled = atLeast "15"; - generic = - # utils - { - stdenv, - fetchFromGitHub, - fetchurl, - lib, - replaceVars, + dlSuffix = if olderThan "16" then ".so" else stdenv.hostPlatform.extensions.sharedLibrary; - # source specification - hash, - muslPatches ? { }, - rev, - version, + stdenv' = + if !stdenv.cc.isClang then + overrideCC llvmPackages.stdenv ( + llvmPackages.stdenv.cc.override { + # LLVM bintools are not used by default, but are needed to make -flto work below. + bintools = buildPackages."llvmPackages_${lib.versions.major llvmPackages.release_version}".bintools; + } + ) + else + stdenv; +in +stdenv'.mkDerivation (finalAttrs: { + inherit version; + pname = "postgresql"; - # runtime dependencies - darwin, - freebsd, - glibc, - libuuid, - libxml2, - lz4, - openssl, - readline, - tzdata, - zlib, - zstd, + src = fetchFromGitHub { + owner = "postgres"; + repo = "postgres"; + # rev, not tag, on purpose: allows updating when new versions + # are "stamped" a few days before release (tag). + inherit hash rev; + }; - # build dependencies - bison, - docbook-xsl-nons, - docbook_xml_dtd_45, - flex, - libxslt, - makeBinaryWrapper, - pkg-config, - removeReferencesTo, + __structuredAttrs = true; - # passthru - buildPackages, - newScope, - nixosTests, - self, - testers, + outputs = [ + "out" + "dev" + "doc" + "lib" + "man" + ] + ++ lib.optionals jitSupport [ "jit" ] + ++ lib.optionals perlSupport [ "plperl" ] + ++ lib.optionals pythonSupport [ "plpython3" ] + ++ lib.optionals tclSupport [ "pltcl" ]; - # Block size - # Changing the block size will break on-disk database compatibility. See: - # https://www.postgresql.org/docs/current/install-make.html#CONFIGURE-OPTION-WITH-BLOCKSIZE - withBlocksize ? null, - withWalBlocksize ? null, + outputChecks = { + out = { + disallowedReferences = [ + "dev" + "doc" + "man" + ] + ++ lib.optionals jitSupport [ "jit" ]; + disallowedRequisites = [ + stdenv'.cc + llvmPackages.llvm.out + llvmPackages.llvm.lib + ] + ++ (map lib.getDev (builtins.filter (drv: drv ? "dev") finalAttrs.buildInputs)); + }; - # bonjour - bonjourSupport ? false, - - # Curl - curlSupport ? lib.versionAtLeast version "18" && lib.meta.availableOn stdenv.hostPlatform curl, - curl, - - # GSSAPI - gssSupport ? with stdenv.hostPlatform; !isWindows, - libkrb5, - - # icu - icuSupport ? true, - icu, - - # JIT - jitSupport ? stdenv.hostPlatform.canExecute stdenv.buildPlatform, - llvmPackages, - nukeReferences, - overrideCC, - - # LDAP - ldapSupport ? false, - openldap, - - # NLS - nlsSupport ? false, - gettext, - - # NUMA - numaSupport ? lib.versionAtLeast version "18" && lib.meta.availableOn stdenv.hostPlatform numactl, - numactl, - - # PAM - pamSupport ? lib.meta.availableOn stdenv.hostPlatform linux-pam, - linux-pam, - - # PL/Perl - perlSupport ? - lib.meta.availableOn stdenv.hostPlatform perl - # configure tries to call the perl executable for the version - && stdenv.buildPlatform.canExecute stdenv.hostPlatform, - perl, - - # PL/Python - pythonSupport ? - lib.meta.availableOn stdenv.hostPlatform python3 - # configure tries to call the python executable - && stdenv.buildPlatform.canExecute stdenv.hostPlatform, - python3, - - # PL/Tcl - tclSupport ? - lib.meta.availableOn stdenv.hostPlatform tcl - # configure fails with: - # configure: error: file 'tclConfig.sh' is required for Tcl - && stdenv.buildPlatform.canExecute stdenv.hostPlatform, - tcl, - - # SELinux - selinuxSupport ? false, - libselinux, - - # Systemd - systemdSupport ? lib.meta.availableOn stdenv.hostPlatform systemdLibs, - systemdLibs, - - # Uring - uringSupport ? lib.versionAtLeast version "18" && lib.meta.availableOn stdenv.hostPlatform liburing, - liburing, - }@args: - let - atLeast = lib.versionAtLeast version; - olderThan = lib.versionOlder version; - lz4Enabled = atLeast "14"; - zstdEnabled = atLeast "15"; - - dlSuffix = if olderThan "16" then ".so" else stdenv.hostPlatform.extensions.sharedLibrary; - - stdenv' = - if !stdenv.cc.isClang then - overrideCC llvmPackages.stdenv ( - llvmPackages.stdenv.cc.override { - # LLVM bintools are not used by default, but are needed to make -flto work below. - bintools = buildPackages."llvmPackages_${lib.versions.major llvmPackages.release_version}".bintools; - } - ) - else - stdenv; - in - stdenv'.mkDerivation (finalAttrs: { - inherit version; - pname = "postgresql"; - - src = fetchFromGitHub { - owner = "postgres"; - repo = "postgres"; - # rev, not tag, on purpose: allows updating when new versions - # are "stamped" a few days before release (tag). - inherit hash rev; - }; - - __structuredAttrs = true; - - outputs = [ + lib = { + disallowedReferences = [ "out" "dev" "doc" - "lib" "man" ] - ++ lib.optionals jitSupport [ "jit" ] - ++ lib.optionals perlSupport [ "plperl" ] - ++ lib.optionals pythonSupport [ "plpython3" ] - ++ lib.optionals tclSupport [ "pltcl" ]; - - outputChecks = { - out = { - disallowedReferences = [ - "dev" - "doc" - "man" - ] - ++ lib.optionals jitSupport [ "jit" ]; - disallowedRequisites = [ - stdenv'.cc - llvmPackages.llvm.out - llvmPackages.llvm.lib - ] - ++ (map lib.getDev (builtins.filter (drv: drv ? "dev") finalAttrs.buildInputs)); - }; - - lib = { - disallowedReferences = [ - "out" - "dev" - "doc" - "man" - ] - ++ lib.optionals jitSupport [ "jit" ]; - disallowedRequisites = [ - stdenv'.cc - llvmPackages.llvm.out - llvmPackages.llvm.lib - ] - ++ (map lib.getDev (builtins.filter (drv: drv ? "dev") finalAttrs.buildInputs)); - }; - - doc = { - disallowedReferences = [ - "out" - "dev" - "man" - ] - ++ lib.optionals jitSupport [ "jit" ]; - }; - - man = { - disallowedReferences = [ - "out" - "dev" - "doc" - ] - ++ lib.optionals jitSupport [ "jit" ]; - }; - } - // lib.optionalAttrs jitSupport { - jit = { - disallowedReferences = [ - "dev" - "doc" - "man" - ]; - disallowedRequisites = [ - stdenv'.cc - llvmPackages.llvm.out - ] - ++ (map lib.getDev (builtins.filter (drv: drv ? "dev") finalAttrs.buildInputs)); - }; - }; - - strictDeps = true; - - buildInputs = [ - zlib - readline - openssl - libxml2 - libuuid + ++ lib.optionals jitSupport [ "jit" ]; + disallowedRequisites = [ + stdenv'.cc + llvmPackages.llvm.out + llvmPackages.llvm.lib ] - ++ lib.optionals icuSupport [ icu ] - ++ lib.optionals jitSupport [ llvmPackages.llvm ] - ++ lib.optionals lz4Enabled [ lz4 ] - ++ lib.optionals zstdEnabled [ zstd ] - ++ lib.optionals systemdSupport [ systemdLibs ] - ++ lib.optionals uringSupport [ liburing ] - ++ lib.optionals curlSupport [ curl ] - ++ lib.optionals numaSupport [ numactl ] - ++ lib.optionals gssSupport [ libkrb5 ] - ++ lib.optionals pamSupport [ linux-pam ] - ++ lib.optionals perlSupport [ perl ] - ++ lib.optionals ldapSupport [ openldap ] - ++ lib.optionals selinuxSupport [ libselinux ] - ++ lib.optionals nlsSupport [ gettext ]; + ++ (map lib.getDev (builtins.filter (drv: drv ? "dev") finalAttrs.buildInputs)); + }; - nativeBuildInputs = [ - bison - docbook-xsl-nons - docbook_xml_dtd_45 - flex - libxml2 - libxslt - makeBinaryWrapper - perl - pkg-config - removeReferencesTo + doc = { + disallowedReferences = [ + "out" + "dev" + "man" ] - ++ lib.optionals jitSupport [ - llvmPackages.llvm.dev - nukeReferences + ++ lib.optionals jitSupport [ "jit" ]; + }; + + man = { + disallowedReferences = [ + "out" + "dev" + "doc" + ] + ++ lib.optionals jitSupport [ "jit" ]; + }; + } + // lib.optionalAttrs jitSupport { + jit = { + disallowedReferences = [ + "dev" + "doc" + "man" ]; + disallowedRequisites = [ + stdenv'.cc + llvmPackages.llvm.out + ] + ++ (map lib.getDev (builtins.filter (drv: drv ? "dev") finalAttrs.buildInputs)); + }; + }; - enableParallelBuilding = true; + strictDeps = true; - separateDebugInfo = true; + buildInputs = [ + zlib + readline + openssl + libxml2 + libuuid + ] + ++ lib.optionals icuSupport [ icu ] + ++ lib.optionals jitSupport [ llvmPackages.llvm ] + ++ lib.optionals lz4Enabled [ lz4 ] + ++ lib.optionals zstdEnabled [ zstd ] + ++ lib.optionals systemdSupport [ systemdLibs ] + ++ lib.optionals uringSupport [ liburing ] + ++ lib.optionals curlSupport [ curl ] + ++ lib.optionals numaSupport [ numactl ] + ++ lib.optionals gssSupport [ libkrb5 ] + ++ lib.optionals pamSupport [ linux-pam ] + ++ lib.optionals perlSupport [ perl ] + ++ lib.optionals ldapSupport [ openldap ] + ++ lib.optionals selinuxSupport [ libselinux ] + ++ lib.optionals nlsSupport [ gettext ]; - buildFlags = [ "world" ]; + nativeBuildInputs = [ + bison + docbook-xsl-nons + docbook_xml_dtd_45 + flex + libxml2 + libxslt + makeBinaryWrapper + perl + pkg-config + removeReferencesTo + ] + ++ lib.optionals jitSupport [ + llvmPackages.llvm.dev + nukeReferences + ]; - env = { - # libpgcommon.a and libpgport.a contain all paths returned by pg_config and are linked - # into all binaries. However, almost no binaries actually use those paths. The following - # flags will remove unused sections from all shared libraries and binaries - including - # those paths. This avoids a lot of circular dependency problems with different outputs, - # and allows splitting them cleanly. - CFLAGS = "-fdata-sections -ffunction-sections -flto"; + enableParallelBuilding = true; - # This flag was introduced upstream in: - # https://github.com/postgres/postgres/commit/b6c7cfac88c47a9194d76f3d074129da3c46545a - # It causes errors when linking against libpq.a in pkgsStatic: - # undefined reference to `pg_encoding_to_char' - # Unsetting the flag fixes it. The upstream reasoning to introduce it is about the risk - # to have initdb load a libpq.so from a different major version and how to avoid that. - # This doesn't apply to us with Nix. - NIX_CFLAGS_COMPILE = "-UUSE_PRIVATE_ENCODING_FUNCS"; - } - // lib.optionalAttrs perlSupport { PERL = lib.getExe perl; } - // lib.optionalAttrs pythonSupport { PYTHON = lib.getExe python3; } - // lib.optionalAttrs tclSupport { TCLSH = "${lib.getBin tcl}/bin/tclsh"; }; + separateDebugInfo = true; - configureFlags = - let - inherit (lib) withFeature; - in + buildFlags = [ "world" ]; + + env = { + # libpgcommon.a and libpgport.a contain all paths returned by pg_config and are linked + # into all binaries. However, almost no binaries actually use those paths. The following + # flags will remove unused sections from all shared libraries and binaries - including + # those paths. This avoids a lot of circular dependency problems with different outputs, + # and allows splitting them cleanly. + CFLAGS = "-fdata-sections -ffunction-sections -flto"; + + # This flag was introduced upstream in: + # https://github.com/postgres/postgres/commit/b6c7cfac88c47a9194d76f3d074129da3c46545a + # It causes errors when linking against libpq.a in pkgsStatic: + # undefined reference to `pg_encoding_to_char' + # Unsetting the flag fixes it. The upstream reasoning to introduce it is about the risk + # to have initdb load a libpq.so from a different major version and how to avoid that. + # This doesn't apply to us with Nix. + NIX_CFLAGS_COMPILE = "-UUSE_PRIVATE_ENCODING_FUNCS"; + } + // lib.optionalAttrs perlSupport { PERL = lib.getExe perl; } + // lib.optionalAttrs pythonSupport { PYTHON = lib.getExe python3; } + // lib.optionalAttrs tclSupport { TCLSH = "${lib.getBin tcl}/bin/tclsh"; }; + + configureFlags = + let + inherit (lib) withFeature; + in + [ + "--with-openssl" + "--with-libxml" + (withFeature icuSupport "icu") + "--sysconfdir=/etc" + "--with-system-tzdata=${tzdata}/share/zoneinfo" + "--enable-debug" + (lib.optionalString systemdSupport "--with-systemd") + (if stdenv.hostPlatform.isFreeBSD then "--with-uuid=bsd" else "--with-uuid=e2fs") + (withFeature perlSupport "perl") + ] + ++ lib.optionals (withBlocksize != null) [ "--with-blocksize=${toString withBlocksize}" ] + ++ lib.optionals (withWalBlocksize != null) [ "--with-wal-blocksize=${toString withWalBlocksize}" ] + ++ lib.optionals lz4Enabled [ "--with-lz4" ] + ++ lib.optionals zstdEnabled [ "--with-zstd" ] + ++ lib.optionals uringSupport [ "--with-liburing" ] + ++ lib.optionals curlSupport [ "--with-libcurl" ] + ++ lib.optionals numaSupport [ "--with-libnuma" ] + ++ lib.optionals gssSupport [ "--with-gssapi" ] + ++ lib.optionals pythonSupport [ "--with-python" ] + ++ lib.optionals jitSupport [ "--with-llvm" ] + ++ lib.optionals pamSupport [ "--with-pam" ] + # This can be removed once v17 is removed. v18+ ships with it. + ++ lib.optionals (stdenv'.hostPlatform.isDarwin && atLeast "16" && olderThan "18") [ + "LDFLAGS_EX_BE=-Wl,-export_dynamic" + ] + # some version of this flag is required in all cross configurations + # since it cannot be automatically detected + ++ + lib.optionals + ( + (!stdenv'.hostPlatform.isDarwin) + && (!(stdenv'.buildPlatform.canExecute stdenv.hostPlatform)) + && atLeast "16" + ) [ - "--with-openssl" - "--with-libxml" - (withFeature icuSupport "icu") - "--sysconfdir=/etc" - "--with-system-tzdata=${tzdata}/share/zoneinfo" - "--enable-debug" - (lib.optionalString systemdSupport "--with-systemd") - (if stdenv.hostPlatform.isFreeBSD then "--with-uuid=bsd" else "--with-uuid=e2fs") - (withFeature perlSupport "perl") + "LDFLAGS_EX_BE=-Wl,--export-dynamic" ] - ++ lib.optionals (withBlocksize != null) [ "--with-blocksize=${toString withBlocksize}" ] - ++ lib.optionals (withWalBlocksize != null) [ "--with-wal-blocksize=${toString withWalBlocksize}" ] - ++ lib.optionals lz4Enabled [ "--with-lz4" ] - ++ lib.optionals zstdEnabled [ "--with-zstd" ] - ++ lib.optionals uringSupport [ "--with-liburing" ] - ++ lib.optionals curlSupport [ "--with-libcurl" ] - ++ lib.optionals numaSupport [ "--with-libnuma" ] - ++ lib.optionals gssSupport [ "--with-gssapi" ] - ++ lib.optionals pythonSupport [ "--with-python" ] - ++ lib.optionals jitSupport [ "--with-llvm" ] - ++ lib.optionals pamSupport [ "--with-pam" ] - # This can be removed once v17 is removed. v18+ ships with it. - ++ lib.optionals (stdenv'.hostPlatform.isDarwin && atLeast "16" && olderThan "18") [ - "LDFLAGS_EX_BE=-Wl,-export_dynamic" - ] - # some version of this flag is required in all cross configurations - # since it cannot be automatically detected - ++ - lib.optionals - ( - (!stdenv'.hostPlatform.isDarwin) - && (!(stdenv'.buildPlatform.canExecute stdenv.hostPlatform)) - && atLeast "16" - ) - [ - "LDFLAGS_EX_BE=-Wl,--export-dynamic" - ] - ++ lib.optionals ldapSupport [ "--with-ldap" ] - ++ lib.optionals tclSupport [ "--with-tcl" ] - ++ lib.optionals selinuxSupport [ "--with-selinux" ] - ++ lib.optionals nlsSupport [ "--enable-nls" ] - ++ lib.optionals bonjourSupport [ "--with-bonjour" ] - # Configure needs a little help to find `nm` when cross-compiling. - ++ lib.optionals (atLeast "19") [ "NM=${stdenv'.cc}/bin/${stdenv'.cc.targetPrefix}nm" ]; + ++ lib.optionals ldapSupport [ "--with-ldap" ] + ++ lib.optionals tclSupport [ "--with-tcl" ] + ++ lib.optionals selinuxSupport [ "--with-selinux" ] + ++ lib.optionals nlsSupport [ "--enable-nls" ] + ++ lib.optionals bonjourSupport [ "--with-bonjour" ] + # Configure needs a little help to find `nm` when cross-compiling. + ++ lib.optionals (atLeast "19") [ "NM=${stdenv'.cc}/bin/${stdenv'.cc.targetPrefix}nm" ]; - patches = [ - ( - if atLeast "16" then - ./patches/relative-to-symlinks-16+.patch - else - ./patches/relative-to-symlinks.patch - ) - ( - if atLeast "15" then - ./patches/empty-pg-config-view-15+.patch - else - ./patches/empty-pg-config-view.patch - ) - ./patches/less-is-more.patch - ./patches/paths-for-split-outputs.patch - ./patches/paths-with-postgresql-suffix.patch + patches = [ + ( + if atLeast "16" then + ./patches/relative-to-symlinks-16+.patch + else + ./patches/relative-to-symlinks.patch + ) + ( + if atLeast "15" then + ./patches/empty-pg-config-view-15+.patch + else + ./patches/empty-pg-config-view.patch + ) + ./patches/less-is-more.patch + ./patches/paths-for-split-outputs.patch + ./patches/paths-with-postgresql-suffix.patch - (replaceVars ./patches/locale-binary-path.patch { - locale = "${ - if stdenv.hostPlatform.isDarwin then - darwin.adv_cmds - else if stdenv.hostPlatform.isFreeBSD then - freebsd.locale - else - lib.getBin stdenv.cc.libc - }/bin/locale"; - }) - ] - ++ lib.optionals stdenv'.hostPlatform.isMusl ( - # Using fetchurl instead of fetchpatch on purpose: https://github.com/NixOS/nixpkgs/issues/240141 - map fetchurl (lib.attrValues muslPatches) - ) - ++ lib.optionals stdenv'.hostPlatform.isLinux [ - ./patches/socketdir-in-run-13+.patch - ] - ++ lib.optionals (stdenv'.hostPlatform.isDarwin && olderThan "16") [ - ./patches/export-dynamic-darwin-15-.patch - ]; + (replaceVars ./patches/locale-binary-path.patch { + locale = "${ + if stdenv.hostPlatform.isDarwin then + darwin.adv_cmds + else if stdenv.hostPlatform.isFreeBSD then + freebsd.locale + else + lib.getBin stdenv.cc.libc + }/bin/locale"; + }) + ] + ++ lib.optionals stdenv'.hostPlatform.isMusl ( + # Using fetchurl instead of fetchpatch on purpose: https://github.com/NixOS/nixpkgs/issues/240141 + map fetchurl (lib.attrValues muslPatches) + ) + ++ lib.optionals stdenv'.hostPlatform.isLinux [ + ./patches/socketdir-in-run-13+.patch + ] + ++ lib.optionals (stdenv'.hostPlatform.isDarwin && olderThan "16") [ + ./patches/export-dynamic-darwin-15-.patch + ]; - installTargets = [ "install-world" ]; + installTargets = [ "install-world" ]; - postPatch = '' - substituteInPlace "src/Makefile.global.in" --subst-var out - substituteInPlace "src/common/config_info.c" --subst-var dev - cat ${./pg_config.env.mk} >> src/common/Makefile - '' - # This test always fails on hardware with >1 NUMA node: the sysfs - # dirs providing information about the topology are hidden in the sandbox, - # so postgres assumes there's only a single node `0`. However, - # the test checks on which NUMA nodes the allocated pages are which is >1 - # on such hardware. This in turn triggers a safeguard in the view - # which breaks the test. - # Manual tests confirm that the testcase behaves properly outside of the - # Nix sandbox. - + lib.optionalString (atLeast "18") '' - substituteInPlace src/test/regress/parallel_schedule \ - --replace-fail numa "" - ''; + postPatch = '' + substituteInPlace "src/Makefile.global.in" --subst-var out + substituteInPlace "src/common/config_info.c" --subst-var dev + cat ${./pg_config.env.mk} >> src/common/Makefile + '' + # This test always fails on hardware with >1 NUMA node: the sysfs + # dirs providing information about the topology are hidden in the sandbox, + # so postgres assumes there's only a single node `0`. However, + # the test checks on which NUMA nodes the allocated pages are which is >1 + # on such hardware. This in turn triggers a safeguard in the view + # which breaks the test. + # Manual tests confirm that the testcase behaves properly outside of the + # Nix sandbox. + + lib.optionalString (atLeast "18") '' + substituteInPlace src/test/regress/parallel_schedule \ + --replace-fail numa "" + ''; - postInstall = '' - moveToOutput "bin/ecpg" "$dev" - moveToOutput "lib/pgxs" "$dev" - '' - + lib.optionalString (stdenv'.buildPlatform.canExecute stdenv'.hostPlatform) '' - mkdir -p "$dev/nix-support" - "$out/bin/pg_config" > "$dev/nix-support/pg_config.expected" - '' - + '' - rm "$out/bin/pg_config" - make -C src/common pg_config.env - substituteInPlace src/common/pg_config.env \ - --replace-fail "$out" "@out@" \ - --replace-fail "$man" "@man@" - install -D src/common/pg_config.env "$dev/nix-support/pg_config.env" + postInstall = '' + moveToOutput "bin/ecpg" "$dev" + moveToOutput "lib/pgxs" "$dev" + '' + + lib.optionalString (stdenv'.buildPlatform.canExecute stdenv'.hostPlatform) '' + mkdir -p "$dev/nix-support" + "$out/bin/pg_config" > "$dev/nix-support/pg_config.expected" + '' + + '' + rm "$out/bin/pg_config" + make -C src/common pg_config.env + substituteInPlace src/common/pg_config.env \ + --replace-fail "$out" "@out@" \ + --replace-fail "$man" "@man@" + install -D src/common/pg_config.env "$dev/nix-support/pg_config.env" - # postgres exposes external symbols get_pkginclude_path and similar. Those - # can't be stripped away by --gc-sections/LTO, because they could theoretically - # be used by dynamically loaded modules / extensions. To avoid circular dependencies, - # references to -dev, -doc and -man are removed here. References to -lib must be kept, - # because there is a realistic use-case for extensions to locate the /lib directory to - # load other shared modules. - remove-references-to -t "$dev" -t "$doc" -t "$man" "$out/bin/postgres" + # postgres exposes external symbols get_pkginclude_path and similar. Those + # can't be stripped away by --gc-sections/LTO, because they could theoretically + # be used by dynamically loaded modules / extensions. To avoid circular dependencies, + # references to -dev, -doc and -man are removed here. References to -lib must be kept, + # because there is a realistic use-case for extensions to locate the /lib directory to + # load other shared modules. + remove-references-to -t "$dev" -t "$doc" -t "$man" "$out/bin/postgres" - if [ -z "''${dontDisableStatic:-}" ]; then - # Remove static libraries in case dynamic are available. - for i in $lib/lib/*.a; do - name="$(basename "$i")" - ext="${stdenv'.hostPlatform.extensions.sharedLibrary}" - if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then - rm "$i" - fi - done + if [ -z "''${dontDisableStatic:-}" ]; then + # Remove static libraries in case dynamic are available. + for i in $lib/lib/*.a; do + name="$(basename "$i")" + ext="${stdenv'.hostPlatform.extensions.sharedLibrary}" + if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then + rm "$i" fi + done + fi - # The remaining static libraries are libpgcommon.a, libpgport.a and related. - # Those are only used when building e.g. extensions, so go to $dev. - moveToOutput "lib/*.a" "$dev" - '' - + lib.optionalString jitSupport '' - # In the case of JIT support, prevent useless dependencies on header files - find "$out/lib" -iname '*.bc' -type f -exec nuke-refs '{}' + + # The remaining static libraries are libpgcommon.a, libpgport.a and related. + # Those are only used when building e.g. extensions, so go to $dev. + moveToOutput "lib/*.a" "$dev" + '' + + lib.optionalString jitSupport '' + # In the case of JIT support, prevent useless dependencies on header files + find "$out/lib" -iname '*.bc' -type f -exec nuke-refs '{}' + - # Stop lib depending on the -dev output of llvm - remove-references-to -t ${llvmPackages.llvm.dev} "$out/lib/llvmjit${dlSuffix}" + # Stop lib depending on the -dev output of llvm + remove-references-to -t ${llvmPackages.llvm.dev} "$out/lib/llvmjit${dlSuffix}" - moveToOutput "lib/bitcode" "$jit" - moveToOutput "lib/llvmjit*" "$jit" - '' - + lib.optionalString stdenv'.hostPlatform.isDarwin '' - # The darwin specific Makefile for PGXS contains a reference to the postgres - # binary. Some extensions (here: postgis), which are able to set bindir correctly - # to their own output for installation, will then fail to find "postgres" during linking. - substituteInPlace "$dev/lib/pgxs/src/Makefile.port" \ - --replace-fail '-bundle_loader $(bindir)/postgres' "-bundle_loader $out/bin/postgres" - '' - + lib.optionalString perlSupport '' - moveToOutput "lib/*plperl*" "$plperl" - moveToOutput "share/postgresql/extension/*plperl*" "$plperl" - '' - + lib.optionalString pythonSupport '' - moveToOutput "lib/*plpython3*" "$plpython3" - moveToOutput "share/postgresql/extension/*plpython3*" "$plpython3" - '' - + lib.optionalString tclSupport '' - moveToOutput "lib/*pltcl*" "$pltcl" - moveToOutput "share/postgresql/extension/*pltcl*" "$pltcl" - ''; + moveToOutput "lib/bitcode" "$jit" + moveToOutput "lib/llvmjit*" "$jit" + '' + + lib.optionalString stdenv'.hostPlatform.isDarwin '' + # The darwin specific Makefile for PGXS contains a reference to the postgres + # binary. Some extensions (here: postgis), which are able to set bindir correctly + # to their own output for installation, will then fail to find "postgres" during linking. + substituteInPlace "$dev/lib/pgxs/src/Makefile.port" \ + --replace-fail '-bundle_loader $(bindir)/postgres' "-bundle_loader $out/bin/postgres" + '' + + lib.optionalString perlSupport '' + moveToOutput "lib/*plperl*" "$plperl" + moveToOutput "share/postgresql/extension/*plperl*" "$plperl" + '' + + lib.optionalString pythonSupport '' + moveToOutput "lib/*plpython3*" "$plpython3" + moveToOutput "share/postgresql/extension/*plpython3*" "$plpython3" + '' + + lib.optionalString tclSupport '' + moveToOutput "lib/*pltcl*" "$pltcl" + moveToOutput "share/postgresql/extension/*pltcl*" "$pltcl" + ''; - postFixup = lib.optionalString stdenv'.hostPlatform.isGnu '' - # initdb needs access to "locale" command from glibc. - wrapProgram $out/bin/initdb --prefix PATH ":" ${glibc.bin}/bin - ''; + postFixup = lib.optionalString stdenv'.hostPlatform.isGnu '' + # initdb needs access to "locale" command from glibc. + wrapProgram $out/bin/initdb --prefix PATH ":" ${glibc.bin}/bin + ''; - # Running tests as "install check" to work around SIP issue on macOS: - # https://www.postgresql.org/message-id/flat/4D8E1BC5-BBCF-4B19-8226-359201EA8305%40gmail.com - # Also see /doc/stdenv/platform-notes.chapter.md - doCheck = false; - doInstallCheck = - # Tests currently can't be run on darwin, because of a Nix bug: - # https://github.com/NixOS/nix/issues/12548 - # https://git.lix.systems/lix-project/lix/issues/691 - # The error appears as this in the initdb logs: - # FATAL: could not create shared memory segment: Cannot allocate memory - # Don't let yourself be fooled when trying to remove this condition: Running - # the tests works fine most of the time. But once the tests (or any package using - # postgresqlTestHook) fails on the same machine for a few times, enough IPC objects - # will be stuck around, and any future builds with the tests enabled *will* fail. - !(stdenv'.hostPlatform.isDarwin) - && - # Regression tests currently fail in pkgsMusl because of a difference in EXPLAIN output. - !(stdenv'.hostPlatform.isMusl) - && - # Modifying block sizes is expected to break regression tests. - # https://www.postgresql.org/message-id/E1TJOeZ-000717-Lg%40wrigleys.postgresql.org - (withBlocksize == null && withWalBlocksize == null); - installCheckTarget = "check-world"; + # Running tests as "install check" to work around SIP issue on macOS: + # https://www.postgresql.org/message-id/flat/4D8E1BC5-BBCF-4B19-8226-359201EA8305%40gmail.com + # Also see /doc/stdenv/platform-notes.chapter.md + doCheck = false; + doInstallCheck = + # Tests currently can't be run on darwin, because of a Nix bug: + # https://github.com/NixOS/nix/issues/12548 + # https://git.lix.systems/lix-project/lix/issues/691 + # The error appears as this in the initdb logs: + # FATAL: could not create shared memory segment: Cannot allocate memory + # Don't let yourself be fooled when trying to remove this condition: Running + # the tests works fine most of the time. But once the tests (or any package using + # postgresqlTestHook) fails on the same machine for a few times, enough IPC objects + # will be stuck around, and any future builds with the tests enabled *will* fail. + !(stdenv'.hostPlatform.isDarwin) + && + # Regression tests currently fail in pkgsMusl because of a difference in EXPLAIN output. + !(stdenv'.hostPlatform.isMusl) + && + # Modifying block sizes is expected to break regression tests. + # https://www.postgresql.org/message-id/E1TJOeZ-000717-Lg%40wrigleys.postgresql.org + (withBlocksize == null && withWalBlocksize == null); + installCheckTarget = "check-world"; - passthru = { - inherit dlSuffix; + passthru = { + inherit dlSuffix; - psqlSchema = lib.versions.major version; + psqlSchema = lib.versions.major version; - withJIT = - if jitSupport then - finalAttrs.finalPackage.withPackages (_: [ finalAttrs.finalPackage.jit ]) - else - null; - withoutJIT = finalAttrs.finalPackage.withPackages (_: [ ]); + withJIT = + if jitSupport then + finalAttrs.finalPackage.withPackages (_: [ finalAttrs.finalPackage.jit ]) + else + null; + withoutJIT = finalAttrs.finalPackage.withPackages (_: [ ]); - pkgs = - let - scope = { - inherit - jitSupport - pythonSupport - perlSupport - tclSupport - ; - inherit (llvmPackages) llvm; - postgresql = finalAttrs.finalPackage; - stdenv = stdenv'; - postgresqlTestExtension = newSuper.callPackage ./postgresqlTestExtension.nix { }; - postgresqlBuildExtension = newSuper.callPackage ./postgresqlBuildExtension.nix { }; - }; - newSelf = self // scope; - newSuper = { - callPackage = newScope (scope // finalAttrs.finalPackage.pkgs); - }; - in - import ./ext.nix newSelf newSuper; - - withPackages = self.callPackage ./wrapper.nix { postgresql = finalAttrs.finalPackage; }; - - pg_config = buildPackages.callPackage ./pg_config.nix { - inherit (finalAttrs) finalPackage; - outputs = { - out = lib.getOutput "out" finalAttrs.finalPackage; - man = lib.getOutput "man" finalAttrs.finalPackage; - }; + pkgs = + let + scope = { + inherit + jitSupport + pythonSupport + perlSupport + tclSupport + ; + inherit (llvmPackages) llvm; + postgresql = finalAttrs.finalPackage; + stdenv = stdenv'; + postgresqlTestExtension = newSuper.callPackage ./postgresqlTestExtension.nix { }; + postgresqlBuildExtension = newSuper.callPackage ./postgresqlBuildExtension.nix { }; }; - - tests = { - postgresql = nixosTests.postgresql.postgresql.passthru.override finalAttrs.finalPackage; - postgresql-replication = nixosTests.postgresql.postgresql-replication.passthru.override finalAttrs.finalPackage; - postgresql-tls-client-cert = nixosTests.postgresql.postgresql-tls-client-cert.passthru.override finalAttrs.finalPackage; - postgresql-wal-receiver = nixosTests.postgresql.postgresql-wal-receiver.passthru.override finalAttrs.finalPackage; - pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; - } - // lib.optionalAttrs jitSupport { - postgresql-jit = nixosTests.postgresql.postgresql-jit.passthru.override finalAttrs.finalPackage; + newSelf = self // scope; + newSuper = { + callPackage = newScope (scope // finalAttrs.finalPackage.pkgs); }; + in + import ./ext.nix newSelf newSuper; + + withPackages = self.callPackage ./wrapper.nix { postgresql = finalAttrs.finalPackage; }; + + pg_config = buildPackages.callPackage ./pg_config.nix { + inherit (finalAttrs) finalPackage; + outputs = { + out = lib.getOutput "out" finalAttrs.finalPackage; + man = lib.getOutput "man" finalAttrs.finalPackage; }; + }; - meta = { - homepage = "https://www.postgresql.org"; - description = "Powerful, open source object-relational database system"; - license = lib.licenses.postgresql; - changelog = "https://www.postgresql.org/docs/release/${finalAttrs.version}/"; - teams = [ lib.teams.postgres ]; - pkgConfigModules = [ - "libecpg" - "libecpg_compat" - "libpgtypes" - "libpq" - ]; - platforms = lib.platforms.unix; + tests = { + postgresql = nixosTests.postgresql.postgresql.passthru.override finalAttrs.finalPackage; + postgresql-replication = nixosTests.postgresql.postgresql-replication.passthru.override finalAttrs.finalPackage; + postgresql-tls-client-cert = nixosTests.postgresql.postgresql-tls-client-cert.passthru.override finalAttrs.finalPackage; + postgresql-wal-receiver = nixosTests.postgresql.postgresql-wal-receiver.passthru.override finalAttrs.finalPackage; + pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; + } + // lib.optionalAttrs jitSupport { + postgresql-jit = nixosTests.postgresql.postgresql-jit.passthru.override finalAttrs.finalPackage; + }; + }; - broken = - # JIT support doesn't work with cross-compilation. It is attempted to build LLVM-bytecode - # (`%.bc` is the corresponding `make(1)`-rule) for each sub-directory in `backend/` for - # the JIT apparently, but with a $(CLANG) that can produce binaries for the build, not the - # host-platform. - # - # I managed to get a cross-build with JIT support working with - # `depsBuildBuild = [ llvmPackages.clang ] ++ buildInputs`, but considering that the - # resulting LLVM IR isn't platform-independent this doesn't give you much. - # In fact, I tried to test the result in a VM-test, but as soon as JIT was used to optimize - # a query, postgres would coredump with `Illegal instruction`. - # - # Note: This is "host canExecute build" on purpose, since this is about the LLVM that is called - # to do JIT at **runtime**. - (jitSupport && !stdenv.hostPlatform.canExecute stdenv.buildPlatform) - # While PostgreSQL claims to support static builds, it does not do so in a way that - # would work properly and consistently in pkgsStatic. The server heavily depends on - # the ability to load shared modules at runtime, but dlopen() is stubbed out in static - # musl builds. The important part is, that the separate libpq package builds in pkgsStatic. - || stdenv.hostPlatform.isStatic; - }; - }); + meta = { + homepage = "https://www.postgresql.org"; + description = "Powerful, open source object-relational database system"; + license = lib.licenses.postgresql; + changelog = "https://www.postgresql.org/docs/release/${finalAttrs.version}/"; + teams = [ lib.teams.postgres ]; + pkgConfigModules = [ + "libecpg" + "libecpg_compat" + "libpgtypes" + "libpq" + ]; + platforms = lib.platforms.unix; -in -# passed by .nix -versionArgs: -# passed by default.nix -{ self, ... }@defaultArgs: -self.callPackage generic (defaultArgs // versionArgs) + broken = + # JIT support doesn't work with cross-compilation. It is attempted to build LLVM-bytecode + # (`%.bc` is the corresponding `make(1)`-rule) for each sub-directory in `backend/` for + # the JIT apparently, but with a $(CLANG) that can produce binaries for the build, not the + # host-platform. + # + # I managed to get a cross-build with JIT support working with + # `depsBuildBuild = [ llvmPackages.clang ] ++ buildInputs`, but considering that the + # resulting LLVM IR isn't platform-independent this doesn't give you much. + # In fact, I tried to test the result in a VM-test, but as soon as JIT was used to optimize + # a query, postgres would coredump with `Illegal instruction`. + # + # Note: This is "host canExecute build" on purpose, since this is about the LLVM that is called + # to do JIT at **runtime**. + (jitSupport && !stdenv.hostPlatform.canExecute stdenv.buildPlatform) + # While PostgreSQL claims to support static builds, it does not do so in a way that + # would work properly and consistently in pkgsStatic. The server heavily depends on + # the ability to load shared modules at runtime, but dlopen() is stubbed out in static + # musl builds. The important part is, that the separate libpq package builds in pkgsStatic. + || stdenv.hostPlatform.isStatic; + }; +})