1{
2 # utils
3 stdenv,
4 fetchFromGitHub,
5 lib,
6
7 # runtime dependencies
8 openssl,
9 tzdata,
10 zlib,
11
12 # build dependencies
13 bison,
14 flex,
15 makeWrapper,
16 perl,
17 pkg-config,
18
19 # passthru / meta
20 postgresql,
21 buildPackages,
22
23 # GSSAPI
24 gssSupport ? with stdenv.hostPlatform; !isWindows && !isStatic,
25 libkrb5,
26
27 # NLS
28 nlsSupport ? false,
29 gettext,
30}:
31
32stdenv.mkDerivation (finalAttrs: {
33 pname = "libpq";
34 version = "17.6";
35
36 src = fetchFromGitHub {
37 owner = "postgres";
38 repo = "postgres";
39 # rev, not tag, on purpose: see generic.nix.
40 rev = "refs/tags/REL_17_6";
41 hash = "sha256-/7C+bjmiJ0/CvoAc8vzTC50vP7OsrM6o0w+lmmHvKvU=";
42 };
43
44 __structuredAttrs = true;
45
46 hardeningEnable = lib.optionals (!stdenv.cc.isClang) [ "pie" ];
47
48 outputs = [
49 "out"
50 "dev"
51 ];
52 outputChecks.out = {
53 disallowedReferences = [ "dev" ];
54 disallowedRequisites = [
55 stdenv.cc
56 ]
57 ++ (map lib.getDev (builtins.filter (drv: drv ? "dev") finalAttrs.buildInputs));
58 };
59
60 buildInputs = [
61 zlib
62 openssl
63 ]
64 ++ lib.optionals gssSupport [ libkrb5 ]
65 ++ lib.optionals nlsSupport [ gettext ];
66
67 nativeBuildInputs = [
68 bison
69 flex
70 makeWrapper
71 perl
72 pkg-config
73 ];
74
75 # causes random build failures
76 enableParallelBuilding = false;
77
78 separateDebugInfo = true;
79
80 buildFlags = [
81 "submake-libpgport"
82 "submake-libpq"
83 ];
84
85 # libpgcommon.a and libpgport.a contain all paths normally returned by pg_config and are
86 # linked into all shared libraries. However, almost no binaries actually use those paths.
87 # The following flags will remove unused sections from all shared libraries - including
88 # those paths. This avoids a lot of circular dependency problems with different outputs,
89 # and allows splitting them cleanly.
90 env.CFLAGS =
91 "-fdata-sections -ffunction-sections"
92 + (if stdenv.cc.isClang then " -flto" else " -fmerge-constants -Wl,--gc-sections");
93
94 # This flag was introduced upstream in:
95 # https://github.com/postgres/postgres/commit/b6c7cfac88c47a9194d76f3d074129da3c46545a
96 # It causes errors when linking against libpq.a in pkgsStatic:
97 # undefined reference to `pg_encoding_to_char'
98 # Unsetting the flag fixes it. The upstream reasoning to introduce it is about the risk
99 # to have initdb load a libpq.so from a different major version and how to avoid that.
100 # This doesn't apply to us with Nix.
101 env.NIX_CFLAGS_COMPILE = "-UUSE_PRIVATE_ENCODING_FUNCS";
102
103 configureFlags = [
104 "--enable-debug"
105 "--sysconfdir=/etc"
106 "--with-openssl"
107 "--with-system-tzdata=${tzdata}/share/zoneinfo"
108 "--without-icu"
109 "--without-perl"
110 "--without-readline"
111 ]
112 ++ lib.optionals gssSupport [ "--with-gssapi" ]
113 ++ lib.optionals nlsSupport [ "--enable-nls" ];
114
115 patches = lib.optionals stdenv.hostPlatform.isLinux [
116 ./patches/socketdir-in-run-13+.patch
117 ];
118
119 postPatch = ''
120 cat ${./pg_config.env.mk} >> src/common/Makefile
121 ''
122 # Explicitly disable building the shared libs, because that would fail with pkgsStatic.
123 + lib.optionalString stdenv.hostPlatform.isStatic ''
124 substituteInPlace src/interfaces/libpq/Makefile \
125 --replace-fail "all: all-lib libpq-refs-stamp" "all: all-lib"
126 substituteInPlace src/Makefile.shlib \
127 --replace-fail "all-lib: all-shared-lib" "all-lib: all-static-lib" \
128 --replace-fail "install-lib: install-lib-shared" "install-lib: install-lib-static"
129 '';
130
131 installPhase = ''
132 runHook preInstall
133
134 make -C src/common install pg_config.env
135 make -C src/include install
136 make -C src/interfaces/libpq install
137 make -C src/port install
138
139 substituteInPlace src/common/pg_config.env \
140 --replace-fail "$out" "@out@"
141
142 install -D src/common/pg_config.env "$dev/nix-support/pg_config.env"
143 moveToOutput "lib/*.a" "$dev"
144
145 rm -rfv $out/share
146 rm -rfv $dev/lib/*_shlib.a
147
148 runHook postInstall
149 '';
150
151 # PostgreSQL always builds both shared and static libs, so we delete those we don't want.
152 postInstall = if stdenv.hostPlatform.isStatic then "touch $out/empty" else "rm -rfv $dev/lib/*.a";
153
154 doCheck = false;
155
156 passthru.pg_config = buildPackages.callPackage ./pg_config.nix {
157 inherit (finalAttrs) finalPackage;
158 outputs = {
159 out = lib.getOutput "out" finalAttrs.finalPackage;
160 };
161 };
162
163 meta = {
164 inherit (postgresql.meta)
165 homepage
166 license
167 teams
168 platforms
169 ;
170 description = "C application programmer's interface to PostgreSQL";
171 changelog = "https://www.postgresql.org/docs/release/${finalAttrs.version}/";
172 pkgConfigModules = [ "libpq" ];
173 };
174})