at 24.11-pre 309 lines 12 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 , linux-pam 9 10 # This is important to obtain a version of `libpq` that does not depend on systemd. 11 , systemdSupport ? lib.meta.availableOn stdenv.hostPlatform systemd && !stdenv.hostPlatform.isStatic 12 , enableSystemd ? null 13 , gssSupport ? with stdenv.hostPlatform; !isWindows && !isStatic 14 15 # for postgresql.pkgs 16 , self, newScope, buildEnv 17 18 # source specification 19 , version, hash, muslPatches ? {} 20 21 # for tests 22 , testers, nixosTests 23 24 # JIT 25 , jitSupport 26 , nukeReferences, patchelf, llvmPackages 27 28 # PL/Python 29 , pythonSupport ? false 30 , python3 31 32 # detection of crypt fails when using llvm stdenv, so we add it manually 33 # for <13 (where it got removed: https://github.com/postgres/postgres/commit/c45643d618e35ec2fe91438df15abd4f3c0d85ca) 34 , libxcrypt 35 } @args: 36 let 37 atLeast = lib.versionAtLeast version; 38 olderThan = lib.versionOlder version; 39 lz4Enabled = atLeast "14"; 40 zstdEnabled = atLeast "15"; 41 42 systemdSupport' = if enableSystemd == null then systemdSupport else (lib.warn "postgresql: argument enableSystemd is deprecated, please use systemdSupport instead." enableSystemd); 43 44 pname = "postgresql"; 45 46 stdenv' = if jitSupport then llvmPackages.stdenv else stdenv; 47 in stdenv'.mkDerivation (finalAttrs: { 48 inherit version; 49 pname = pname + lib.optionalString jitSupport "-jit"; 50 51 src = fetchurl { 52 url = "mirror://postgresql/source/v${version}/${pname}-${version}.tar.bz2"; 53 inherit hash; 54 }; 55 56 hardeningEnable = lib.optionals (!stdenv'.cc.isClang) [ "pie" ]; 57 58 outputs = [ "out" "lib" "doc" "man" ]; 59 setOutputFlags = false; # $out retains configureFlags :-/ 60 61 buildInputs = [ 62 zlib 63 readline 64 openssl 65 libxml2 66 icu 67 ] 68 ++ lib.optionals (olderThan "13") [ libxcrypt ] 69 ++ lib.optionals jitSupport [ llvmPackages.llvm ] 70 ++ lib.optionals lz4Enabled [ lz4 ] 71 ++ lib.optionals zstdEnabled [ zstd ] 72 ++ lib.optionals systemdSupport' [ systemd ] 73 ++ lib.optionals pythonSupport [ python3 ] 74 ++ lib.optionals gssSupport [ libkrb5 ] 75 ++ lib.optionals stdenv'.isLinux [ linux-pam ] 76 ++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ]; 77 78 nativeBuildInputs = [ 79 makeWrapper 80 pkg-config 81 ] 82 ++ lib.optionals jitSupport [ llvmPackages.llvm.dev nukeReferences patchelf ]; 83 84 enableParallelBuilding = true; 85 86 separateDebugInfo = true; 87 88 buildFlags = [ "world" ]; 89 90 # Makes cross-compiling work when xml2-config can't be executed on the host. 91 # Fixed upstream in https://github.com/postgres/postgres/commit/0bc8cebdb889368abdf224aeac8bc197fe4c9ae6 92 env.NIX_CFLAGS_COMPILE = lib.optionalString (olderThan "13") "-I${libxml2.dev}/include/libxml2"; 93 94 configureFlags = [ 95 "--with-openssl" 96 "--with-libxml" 97 "--with-icu" 98 "--sysconfdir=/etc" 99 "--libdir=$(lib)/lib" 100 "--with-system-tzdata=${tzdata}/share/zoneinfo" 101 "--enable-debug" 102 (lib.optionalString systemdSupport' "--with-systemd") 103 (if stdenv'.isDarwin then "--with-uuid=e2fs" else "--with-ossp-uuid") 104 ] ++ lib.optionals lz4Enabled [ "--with-lz4" ] 105 ++ lib.optionals zstdEnabled [ "--with-zstd" ] 106 ++ lib.optionals gssSupport [ "--with-gssapi" ] 107 ++ lib.optionals pythonSupport [ "--with-python" ] 108 ++ lib.optionals jitSupport [ "--with-llvm" ] 109 ++ lib.optionals stdenv'.isLinux [ "--with-pam" ]; 110 111 patches = [ 112 (if atLeast "16" then ./patches/relative-to-symlinks-16+.patch else ./patches/relative-to-symlinks.patch) 113 ./patches/less-is-more.patch 114 ./patches/paths-for-split-outputs.patch 115 ./patches/specify_pkglibdir_at_runtime.patch 116 ./patches/paths-with-postgresql-suffix.patch 117 118 (substituteAll { 119 src = ./patches/locale-binary-path.patch; 120 locale = "${if stdenv.isDarwin then darwin.adv_cmds else lib.getBin stdenv.cc.libc}/bin/locale"; 121 }) 122 123 ] ++ lib.optionals stdenv'.hostPlatform.isMusl ( 124 # Using fetchurl instead of fetchpatch on purpose: https://github.com/NixOS/nixpkgs/issues/240141 125 map fetchurl (lib.attrValues muslPatches) 126 ) ++ lib.optionals stdenv'.isLinux [ 127 (if atLeast "13" then ./patches/socketdir-in-run-13+.patch else ./patches/socketdir-in-run.patch) 128 ]; 129 130 installTargets = [ "install-world" ]; 131 132 postPatch = '' 133 # Hardcode the path to pgxs so pg_config returns the path in $out 134 substituteInPlace "src/common/config_info.c" --subst-var out 135 '' + lib.optionalString jitSupport '' 136 # Force lookup of jit stuff in $out instead of $lib 137 substituteInPlace src/backend/jit/jit.c --replace pkglib_path \"$out/lib\" 138 substituteInPlace src/backend/jit/llvm/llvmjit.c --replace pkglib_path \"$out/lib\" 139 substituteInPlace src/backend/jit/llvm/llvmjit_inline.cpp --replace pkglib_path \"$out/lib\" 140 ''; 141 142 postInstall = 143 '' 144 moveToOutput "lib/pgxs" "$out" # looks strange, but not deleting it 145 moveToOutput "lib/libpgcommon*.a" "$out" 146 moveToOutput "lib/libpgport*.a" "$out" 147 moveToOutput "lib/libecpg*" "$out" 148 149 # Prevent a retained dependency on gcc-wrapper. 150 substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/ld ld 151 152 if [ -z "''${dontDisableStatic:-}" ]; then 153 # Remove static libraries in case dynamic are available. 154 for i in $out/lib/*.a $lib/lib/*.a; do 155 name="$(basename "$i")" 156 ext="${stdenv'.hostPlatform.extensions.sharedLibrary}" 157 if [ -e "$lib/lib/''${name%.a}$ext" ] || [ -e "''${i%.a}$ext" ]; then 158 rm "$i" 159 fi 160 done 161 fi 162 '' + lib.optionalString jitSupport '' 163 # Move the bitcode and libllvmjit.so library out of $lib; otherwise, every client that 164 # depends on libpq.so will also have libLLVM.so in its closure too, bloating it 165 moveToOutput "lib/bitcode" "$out" 166 moveToOutput "lib/llvmjit*" "$out" 167 168 # In the case of JIT support, prevent a retained dependency on clang-wrapper 169 substituteInPlace "$out/lib/pgxs/src/Makefile.global" --replace ${stdenv'.cc}/bin/clang clang 170 nuke-refs $out/lib/llvmjit_types.bc $(find $out/lib/bitcode -type f) 171 172 # Stop out depending on the default output of llvm 173 substituteInPlace $out/lib/pgxs/src/Makefile.global \ 174 --replace ${llvmPackages.llvm.out}/bin "" \ 175 --replace '$(LLVM_BINPATH)/' "" 176 177 # Stop out depending on the -dev output of llvm 178 substituteInPlace $out/lib/pgxs/src/Makefile.global \ 179 --replace ${llvmPackages.llvm.dev}/bin/llvm-config llvm-config \ 180 --replace -I${llvmPackages.llvm.dev}/include "" 181 182 ${lib.optionalString (!stdenv'.isDarwin) '' 183 # Stop lib depending on the -dev output of llvm 184 rpath=$(patchelf --print-rpath $out/lib/llvmjit.so) 185 nuke-refs -e $out $out/lib/llvmjit.so 186 # Restore the correct rpath 187 patchelf $out/lib/llvmjit.so --set-rpath "$rpath" 188 ''} 189 ''; 190 191 postFixup = lib.optionalString (!stdenv'.isDarwin && stdenv'.hostPlatform.libc == "glibc") 192 '' 193 # initdb needs access to "locale" command from glibc. 194 wrapProgram $out/bin/initdb --prefix PATH ":" ${glibc.bin}/bin 195 ''; 196 197 doCheck = !stdenv'.isDarwin; 198 # autodetection doesn't seem to able to find this, but it's there. 199 checkTarget = "check"; 200 201 disallowedReferences = [ stdenv'.cc ]; 202 203 passthru = let 204 this = self.callPackage generic args; 205 jitToggle = this.override { 206 jitSupport = !jitSupport; 207 }; 208 in 209 { 210 psqlSchema = lib.versions.major version; 211 212 withJIT = if jitSupport then this else jitToggle; 213 withoutJIT = if jitSupport then jitToggle else this; 214 215 dlSuffix = if olderThan "16" then ".so" else stdenv.hostPlatform.extensions.sharedLibrary; 216 217 pkgs = let 218 scope = { 219 inherit jitSupport; 220 inherit (llvmPackages) llvm; 221 postgresql = this; 222 stdenv = stdenv'; 223 }; 224 newSelf = self // scope; 225 newSuper = { callPackage = newScope (scope // this.pkgs); }; 226 in import ./ext newSelf newSuper; 227 228 withPackages = postgresqlWithPackages { 229 inherit makeWrapper buildEnv; 230 postgresql = this; 231 } 232 this.pkgs; 233 234 tests = { 235 postgresql-wal-receiver = import ../../../../nixos/tests/postgresql-wal-receiver.nix { 236 inherit (stdenv) system; 237 pkgs = self; 238 package = this; 239 }; 240 pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; 241 } // lib.optionalAttrs jitSupport { 242 postgresql-jit = import ../../../../nixos/tests/postgresql-jit.nix { 243 inherit (stdenv) system; 244 pkgs = self; 245 package = this; 246 }; 247 }; 248 }; 249 250 meta = with lib; { 251 homepage = "https://www.postgresql.org"; 252 description = "A powerful, open source object-relational database system"; 253 license = licenses.postgresql; 254 changelog = "https://www.postgresql.org/docs/release/${finalAttrs.version}/"; 255 maintainers = with maintainers; [ thoughtpolice danbst globin ivan ma27 ]; 256 pkgConfigModules = [ "libecpg" "libecpg_compat" "libpgtypes" "libpq" ]; 257 platforms = platforms.unix; 258 259 # JIT support doesn't work with cross-compilation. It is attempted to build LLVM-bytecode 260 # (`%.bc` is the corresponding `make(1)`-rule) for each sub-directory in `backend/` for 261 # the JIT apparently, but with a $(CLANG) that can produce binaries for the build, not the 262 # host-platform. 263 # 264 # I managed to get a cross-build with JIT support working with 265 # `depsBuildBuild = [ llvmPackages.clang ] ++ buildInputs`, but considering that the 266 # resulting LLVM IR isn't platform-independent this doesn't give you much. 267 # In fact, I tried to test the result in a VM-test, but as soon as JIT was used to optimize 268 # a query, postgres would coredump with `Illegal instruction`. 269 broken = (jitSupport && stdenv.hostPlatform != stdenv.buildPlatform) 270 # Allmost all tests fail FATAL errors for v12 and v13 271 || (jitSupport && stdenv.hostPlatform.isMusl && olderThan "14"); 272 }; 273 }); 274 275 postgresqlWithPackages = { postgresql, makeWrapper, buildEnv }: pkgs: f: buildEnv { 276 name = "postgresql-and-plugins-${postgresql.version}"; 277 paths = f pkgs ++ [ 278 postgresql 279 postgresql.lib 280 postgresql.man # in case user installs this into environment 281 ]; 282 nativeBuildInputs = [ makeWrapper ]; 283 284 285 # We include /bin to ensure the $out/bin directory is created, which is 286 # needed because we'll be removing the files from that directory in postBuild 287 # below. See #22653 288 pathsToLink = ["/" "/bin"]; 289 290 # Note: the duplication of executables is about 4MB size. 291 # So a nicer solution was patching postgresql to allow setting the 292 # libdir explicitly. 293 postBuild = '' 294 mkdir -p $out/bin 295 rm $out/bin/{pg_config,postgres,pg_ctl} 296 cp --target-directory=$out/bin ${postgresql}/bin/{postgres,pg_config,pg_ctl} 297 wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib 298 ''; 299 300 passthru.version = postgresql.version; 301 passthru.psqlSchema = postgresql.psqlSchema; 302 }; 303 304in 305# passed by <major>.nix 306versionArgs: 307# passed by default.nix 308{ self, ... } @defaultArgs: 309self.callPackage generic (defaultArgs // versionArgs)