at 23.11-beta 403 lines 16 kB view raw
1let 2 3 generic = 4 # dependencies 5 { stdenv, lib, fetchurl, makeWrapper, fetchpatch 6 , glibc, zlib, readline, openssl, icu, lz4, zstd, systemd, libossp_uuid 7 , pkg-config, libxml2, tzdata, libkrb5, substituteAll, darwin 8 9 # This is important to obtain a version of `libpq` that does not depend on systemd. 10 , enableSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd && !stdenv.hostPlatform.isStatic 11 , gssSupport ? with stdenv.hostPlatform; !isWindows && !isStatic 12 13 # for postgresql.pkgs 14 , this, self, newScope, buildEnv 15 16 # source specification 17 , version, hash, psqlSchema 18 19 # for tests 20 , testers, nixosTests, thisAttr 21 22 # JIT 23 , jitSupport ? false 24 , nukeReferences, patchelf, llvmPackages 25 , makeRustPlatform, buildPgxExtension, cargo, rustc 26 27 # detection of crypt fails when using llvm stdenv, so we add it manually 28 # for <13 (where it got removed: https://github.com/postgres/postgres/commit/c45643d618e35ec2fe91438df15abd4f3c0d85ca) 29 , libxcrypt 30 }: 31 let 32 atLeast = lib.versionAtLeast version; 33 olderThan = lib.versionOlder version; 34 lz4Enabled = atLeast "14"; 35 zstdEnabled = atLeast "15"; 36 37 pname = "postgresql"; 38 39 stdenv' = if jitSupport then llvmPackages.stdenv else stdenv; 40 in stdenv'.mkDerivation (finalAttrs: { 41 inherit pname version; 42 43 src = fetchurl { 44 url = "mirror://postgresql/source/v${version}/${pname}-${version}.tar.bz2"; 45 inherit hash; 46 }; 47 48 hardeningEnable = lib.optionals (!stdenv'.cc.isClang) [ "pie" ]; 49 50 outputs = [ "out" "lib" "doc" "man" ]; 51 setOutputFlags = false; # $out retains configureFlags :-/ 52 53 buildInputs = [ 54 zlib 55 readline 56 openssl 57 libxml2 58 icu 59 ] 60 ++ lib.optionals (olderThan "13") [ libxcrypt ] 61 ++ lib.optionals jitSupport [ llvmPackages.llvm ] 62 ++ lib.optionals lz4Enabled [ lz4 ] 63 ++ lib.optionals zstdEnabled [ zstd ] 64 ++ lib.optionals enableSystemd [ systemd ] 65 ++ lib.optionals gssSupport [ libkrb5 ] 66 ++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ]; 67 68 nativeBuildInputs = [ 69 makeWrapper 70 pkg-config 71 ] 72 ++ lib.optionals jitSupport [ llvmPackages.llvm.dev nukeReferences patchelf ]; 73 74 enableParallelBuilding = !stdenv'.isDarwin; 75 76 separateDebugInfo = true; 77 78 buildFlags = [ "world" ]; 79 80 env.NIX_CFLAGS_COMPILE = "-I${libxml2.dev}/include/libxml2"; 81 82 # Otherwise it retains a reference to compiler and fails; see #44767. TODO: better. 83 preConfigure = "CC=${stdenv'.cc.targetPrefix}cc"; 84 85 configureFlags = [ 86 "--with-openssl" 87 "--with-libxml" 88 "--with-icu" 89 "--sysconfdir=/etc" 90 "--libdir=$(lib)/lib" 91 "--with-system-tzdata=${tzdata}/share/zoneinfo" 92 "--enable-debug" 93 (lib.optionalString enableSystemd "--with-systemd") 94 (if stdenv'.isDarwin then "--with-uuid=e2fs" else "--with-ossp-uuid") 95 ] ++ lib.optionals lz4Enabled [ "--with-lz4" ] 96 ++ lib.optionals zstdEnabled [ "--with-zstd" ] 97 ++ lib.optionals gssSupport [ "--with-gssapi" ] 98 ++ lib.optionals stdenv'.hostPlatform.isRiscV [ "--disable-spinlocks" ] 99 ++ lib.optionals jitSupport [ "--with-llvm" ]; 100 101 patches = [ 102 (if atLeast "16" then ./patches/disable-normalize_exec_path.patch 103 else ./patches/disable-resolve_symlinks.patch) 104 ./patches/less-is-more.patch 105 ./patches/hardcode-pgxs-path.patch 106 ./patches/specify_pkglibdir_at_runtime.patch 107 ./patches/findstring.patch 108 109 (substituteAll { 110 src = ./locale-binary-path.patch; 111 locale = "${if stdenv.isDarwin then darwin.adv_cmds else lib.getBin stdenv.cc.libc}/bin/locale"; 112 }) 113 114 ] ++ lib.optionals stdenv'.hostPlatform.isMusl ( 115 let 116 self = { 117 "12" = { 118 icu-collations-hack = fetchurl { 119 url = "https://git.alpinelinux.org/aports/plain/testing/postgresql12/icu-collations-hack.patch?id=d5227c91adda59d4e7f55f13468f0314e8869174"; 120 hash = "sha256-wuwjvGHArkRNwFo40g3p43W32OrJohretlt6iSRlJKg="; 121 }; 122 }; 123 "13" = { 124 inherit (self."14") icu-collations-hack; 125 disable-test-collate-icu-utf8 = fetchurl { 126 url = "https://git.alpinelinux.org/aports/plain/main/postgresql13/disable-test-collate.icu.utf8.patch?id=69faa146ec9fff3b981511068f17f9e629d4688b"; 127 hash = "sha256-jS/qxezaiaKhkWeMCXwpz1SDJwUWn9tzN0uKaZ3Ph2Y="; 128 }; 129 }; 130 "14" = { 131 icu-collations-hack = fetchurl { 132 url = "https://git.alpinelinux.org/aports/plain/main/postgresql14/icu-collations-hack.patch?id=56999e6d0265ceff5c5239f85fdd33e146f06cb7"; 133 hash = "sha256-wuwjvGHArkRNwFo40g3p43W32OrJohretlt6iSRlJKg="; 134 }; 135 disable-test-collate-icu-utf8 = fetchurl { 136 url = "https://git.alpinelinux.org/aports/plain/main/postgresql14/disable-test-collate.icu.utf8.patch?id=56999e6d0265ceff5c5239f85fdd33e146f06cb7"; 137 hash = "sha256-jXe23AxnFjEl+TZQm4R7rStk2Leo08ctxMNmu1xr5zM="; 138 }; 139 }; 140 "15" = { 141 icu-collations-hack = fetchurl { 142 url = "https://git.alpinelinux.org/aports/plain/main/postgresql15/icu-collations-hack.patch?id=f424e934e6d076c4ae065ce45e734aa283eecb9c"; 143 hash = "sha256-HgtmhF4OJYU9macGJbTB9PjQi/yW7c3Akm3U0niWs8I="; 144 }; 145 }; 146 "16" = { 147 icu-collations-hack = fetchurl { 148 url = "https://git.alpinelinux.org/aports/plain/main/postgresql16/icu-collations-hack.patch?id=08a24be262339fd093e641860680944c3590238e"; 149 hash = "sha256-+urQdVIlADLdDPeT68XYv5rljhbK8M/7mPZn/cF+FT0="; 150 }; 151 }; 152 }; 153 154 patchesForVersion = self.${lib.versions.major version} or (throw "no musl patches for postgresql ${version}"); 155 in 156 lib.attrValues patchesForVersion 157 ) ++ lib.optionals stdenv'.isLinux [ 158 (if atLeast "13" then ./patches/socketdir-in-run-13.patch else ./patches/socketdir-in-run.patch) 159 ]; 160 161 installTargets = [ "install-world" ]; 162 163 LC_ALL = "C"; 164 165 postPatch = '' 166 # Hardcode the path to pgxs so pg_config returns the path in $out 167 substituteInPlace "src/common/config_info.c" --replace HARDCODED_PGXS_PATH "$out/lib" 168 '' + lib.optionalString jitSupport '' 169 # Force lookup of jit stuff in $out instead of $lib 170 substituteInPlace src/backend/jit/jit.c --replace pkglib_path \"$out/lib\" 171 substituteInPlace src/backend/jit/llvm/llvmjit.c --replace pkglib_path \"$out/lib\" 172 substituteInPlace src/backend/jit/llvm/llvmjit_inline.cpp --replace pkglib_path \"$out/lib\" 173 ''; 174 175 postInstall = 176 '' 177 moveToOutput "lib/pgxs" "$out" # looks strange, but not deleting it 178 moveToOutput "lib/libpgcommon*.a" "$out" 179 moveToOutput "lib/libpgport*.a" "$out" 180 moveToOutput "lib/libecpg*" "$out" 181 182 # Prevent a retained dependency on gcc-wrapper. 183 substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/ld ld 184 185 if [ -z "''${dontDisableStatic:-}" ]; then 186 # Remove static libraries in case dynamic are available. 187 for i in $out/lib/*.a $lib/lib/*.a; do 188 name="$(basename "$i")" 189 ext="${stdenv'.hostPlatform.extensions.sharedLibrary}" 190 if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then 191 rm "$i" 192 fi 193 done 194 fi 195 '' + lib.optionalString jitSupport '' 196 # Move the bitcode and libllvmjit.so library out of $lib; otherwise, every client that 197 # depends on libpq.so will also have libLLVM.so in its closure too, bloating it 198 moveToOutput "lib/bitcode" "$out" 199 moveToOutput "lib/llvmjit*" "$out" 200 201 # In the case of JIT support, prevent a retained dependency on clang-wrapper 202 substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${self.llvmPackages.stdenv.cc}/bin/clang clang 203 nuke-refs $out/lib/llvmjit_types.bc $(find $out/lib/bitcode -type f) 204 205 # Stop out depending on the default output of llvm 206 substituteInPlace $out/lib/pgxs/src/Makefile.global \ 207 --replace ${self.llvmPackages.llvm.out}/bin "" \ 208 --replace '$(LLVM_BINPATH)/' "" 209 210 # Stop out depending on the -dev output of llvm 211 substituteInPlace $out/lib/pgxs/src/Makefile.global \ 212 --replace ${self.llvmPackages.llvm.dev}/bin/llvm-config llvm-config \ 213 --replace -I${self.llvmPackages.llvm.dev}/include "" 214 215 ${lib.optionalString (!stdenv'.isDarwin) '' 216 # Stop lib depending on the -dev output of llvm 217 rpath=$(patchelf --print-rpath $out/lib/llvmjit.so) 218 nuke-refs -e $out $out/lib/llvmjit.so 219 # Restore the correct rpath 220 patchelf $out/lib/llvmjit.so --set-rpath "$rpath" 221 ''} 222 ''; 223 224 postFixup = lib.optionalString (!stdenv'.isDarwin && stdenv'.hostPlatform.libc == "glibc") 225 '' 226 # initdb needs access to "locale" command from glibc. 227 wrapProgram $out/bin/initdb --prefix PATH ":" ${glibc.bin}/bin 228 ''; 229 230 doCheck = !stdenv'.isDarwin; 231 # autodetection doesn't seem to able to find this, but it's there. 232 checkTarget = "check"; 233 234 preCheck = 235 # On musl, comment skip the following tests, because they break due to 236 # ! ERROR: could not load library "/build/postgresql-11.5/tmp_install/nix/store/...-postgresql-11.5-lib/lib/libpqwalreceiver.so": Error loading shared library libpq.so.5: No such file or directory (needed by /build/postgresql-11.5/tmp_install/nix/store/...-postgresql-11.5-lib/lib/libpqwalreceiver.so) 237 # See also here: 238 # https://git.alpinelinux.org/aports/tree/main/postgresql/disable-broken-tests.patch?id=6d7d32c12e073a57a9e5946e55f4c1fbb68bd442 239 if stdenv'.hostPlatform.isMusl then '' 240 substituteInPlace src/test/regress/parallel_schedule \ 241 --replace "subscription" "" \ 242 --replace "object_address" "" 243 '' else null; 244 245 doInstallCheck = false; # needs a running daemon? 246 247 disallowedReferences = [ stdenv'.cc ]; 248 249 passthru = let 250 jitToggle = this.override { 251 jitSupport = !jitSupport; 252 this = jitToggle; 253 }; 254 in 255 { 256 inherit readline psqlSchema jitSupport; 257 258 withJIT = if jitSupport then this else jitToggle; 259 withoutJIT = if jitSupport then jitToggle else this; 260 261 dlSuffix = if olderThan "16" then ".so" else stdenv.hostPlatform.extensions.sharedLibrary; 262 263 pkgs = let 264 scope = { 265 postgresql = this; 266 stdenv = stdenv'; 267 buildPgxExtension = buildPgxExtension.override { 268 stdenv = stdenv'; 269 rustPlatform = makeRustPlatform { 270 stdenv = stdenv'; 271 inherit rustc cargo; 272 }; 273 }; 274 }; 275 newSelf = self // scope; 276 newSuper = { callPackage = newScope (scope // this.pkgs); }; 277 in import ./packages.nix newSelf newSuper; 278 279 withPackages = postgresqlWithPackages { 280 inherit makeWrapper buildEnv; 281 postgresql = this; 282 } 283 this.pkgs; 284 285 tests = { 286 postgresql = nixosTests.postgresql-wal-receiver.${thisAttr}; 287 pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; 288 } // lib.optionalAttrs jitSupport { 289 postgresql-jit = nixosTests.postgresql-jit.${thisAttr}; 290 }; 291 } // lib.optionalAttrs jitSupport { 292 inherit (llvmPackages) llvm; 293 }; 294 295 meta = with lib; { 296 homepage = "https://www.postgresql.org"; 297 description = "A powerful, open source object-relational database system"; 298 license = licenses.postgresql; 299 changelog = "https://www.postgresql.org/docs/release/${finalAttrs.version}/"; 300 maintainers = with maintainers; [ thoughtpolice danbst globin marsam ivan ma27 ]; 301 pkgConfigModules = [ "libecpg" "libecpg_compat" "libpgtypes" "libpq" ]; 302 platforms = platforms.unix; 303 304 # JIT support doesn't work with cross-compilation. It is attempted to build LLVM-bytecode 305 # (`%.bc` is the corresponding `make(1)`-rule) for each sub-directory in `backend/` for 306 # the JIT apparently, but with a $(CLANG) that can produce binaries for the build, not the 307 # host-platform. 308 # 309 # I managed to get a cross-build with JIT support working with 310 # `depsBuildBuild = [ llvmPackages.clang ] ++ buildInputs`, but considering that the 311 # resulting LLVM IR isn't platform-independent this doesn't give you much. 312 # In fact, I tried to test the result in a VM-test, but as soon as JIT was used to optimize 313 # a query, postgres would coredump with `Illegal instruction`. 314 broken = jitSupport && (stdenv.hostPlatform != stdenv.buildPlatform); 315 }; 316 }); 317 318 postgresqlWithPackages = { postgresql, makeWrapper, buildEnv }: pkgs: f: buildEnv { 319 name = "postgresql-and-plugins-${postgresql.version}"; 320 paths = f pkgs ++ [ 321 postgresql 322 postgresql.lib 323 postgresql.man # in case user installs this into environment 324 ]; 325 nativeBuildInputs = [ makeWrapper ]; 326 327 328 # We include /bin to ensure the $out/bin directory is created, which is 329 # needed because we'll be removing the files from that directory in postBuild 330 # below. See #22653 331 pathsToLink = ["/" "/bin"]; 332 333 # Note: the duplication of executables is about 4MB size. 334 # So a nicer solution was patching postgresql to allow setting the 335 # libdir explicitly. 336 postBuild = '' 337 mkdir -p $out/bin 338 rm $out/bin/{pg_config,postgres,pg_ctl} 339 cp --target-directory=$out/bin ${postgresql}/bin/{postgres,pg_config,pg_ctl} 340 wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib 341 ''; 342 343 passthru.version = postgresql.version; 344 passthru.psqlSchema = postgresql.psqlSchema; 345 }; 346 347 mkPackages = self: { 348 postgresql_12 = self.callPackage generic { 349 version = "12.17"; 350 psqlSchema = "12"; 351 hash = "sha256-k+jhsjmB1fA8bFdj93soGEwc5NtxlPpGbi7bZdnBxfY="; 352 this = self.postgresql_12; 353 thisAttr = "postgresql_12"; 354 inherit self; 355 }; 356 357 postgresql_13 = self.callPackage generic { 358 version = "13.13"; 359 psqlSchema = "13"; 360 hash = "sha256-ivacJZkEeirSRlZ9aOxBMa7xFpVNjD5GnpeJCAs3pHQ="; 361 this = self.postgresql_13; 362 thisAttr = "postgresql_13"; 363 inherit self; 364 }; 365 366 postgresql_14 = self.callPackage generic { 367 version = "14.10"; 368 psqlSchema = "14"; 369 hash = "sha256-yZQxxI6dRwsNCrlG6yFBo80ZEwwvtNxLMoSnd07Mg5k="; 370 this = self.postgresql_14; 371 thisAttr = "postgresql_14"; 372 inherit self; 373 }; 374 375 postgresql_15 = self.callPackage generic { 376 version = "15.5"; 377 psqlSchema = "15"; 378 hash = "sha256-j1OqldeOuOglNupGtoGHeTtCu6O09lqjQvVAsjybEKY="; 379 this = self.postgresql_15; 380 thisAttr = "postgresql_15"; 381 inherit self; 382 }; 383 384 postgresql_16 = self.callPackage generic { 385 version = "16.1"; 386 psqlSchema = "16"; 387 hash = "sha256-zjxNhdGbASH+DT+O8fpgH3GYnob4pm99w61UbdVWT+w="; 388 this = self.postgresql_16; 389 thisAttr = "postgresql_16"; 390 inherit self; 391 }; 392 }; 393 394in self: 395 let packages = mkPackages self; in 396 packages 397 // self.lib.mapAttrs' 398 (attrName: postgres: self.lib.nameValuePair "${attrName}_jit" (postgres.override rec { 399 jitSupport = true; 400 thisAttr = "${attrName}_jit"; 401 this = self.${thisAttr}; 402 })) 403 packages