-
-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
postgresql: replace pg_config with custom script
By replacing upstream's pg_config binary with a shell script, we: - gain the ability to run pg_config easily when cross-compiling, - can remove the fake pg_config in the default output, - can remove the pg_config wrapper script dealing with special cases. Some 20 years ago, pg_config *was* a shell script upstream, too. It was changed to a binary, when it was made "relocatable", so it would return paths depending on the location of the "postgres" binary. However, this is exactly the thing that just hurts us in nixpkgs - we don't want those paths to change, we want them to always point at the right outputs. By writing the script ourselves, this becomes a lot less painful. This approach means more lines of codes, but all of them are dead simple and we have a lot less complexity overall. Additionally, pg_config is now made a separate derivation, only exposed as "postgresql.pg_config". This has the nice side-effect, that all users of postgresql and libpq in nixpkgs must be very *explicit* about their dependency on pg_config. This gives a lot more visibility into the state of affairs regarding pkg-config support for libpq, which ultimately is the much better solution.
- Loading branch information
1 parent
bcfa2a0
commit c733b7b
Showing
8 changed files
with
170 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Everything that pg_config normally returns is put into pg_config.env, so | ||
# that we can read it from our own pg_config script later on. | ||
pg_config.env: $(top_builddir)/src/port/pg_config_paths.h | $(top_builddir)/src/include/pg_config.h | ||
echo "CC=\"$(CC)\"" >$@ | ||
echo "CPPFLAGS=\"$(STD_CPPFLAGS)\"" >>$@ | ||
echo "CFLAGS=\"$(CFLAGS)\"" >>$@ | ||
echo "CFLAGS_SL=\"$(CFLAGS_SL)\"" >>$@ | ||
echo "LDFLAGS=\"$(STD_LDFLAGS)\"" >>$@ | ||
echo "LDFLAGS_EX=\"$(LDFLAGS_EX)\"" >>$@ | ||
echo "LDFLAGS_SL=\"$(LDFLAGS_SL)\"" >>$@ | ||
echo "LIBS=\"$(LIBS)\"" >>$@ | ||
cat $(top_builddir)/src/port/pg_config_paths.h $(top_builddir)/src/include/pg_config.h \ | ||
| sed -nE 's/^#define ([^ ]+) ("?)(.*)\2$$/\1="\3"/p' >>$@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
lib, | ||
replaceVarsWith, | ||
runtimeShell, | ||
# PostgreSQL package | ||
finalPackage, | ||
}: | ||
|
||
replaceVarsWith { | ||
name = "pg_config"; | ||
src = ./pg_config.sh; | ||
dir = "bin"; | ||
isExecutable = true; | ||
replacements = { | ||
inherit runtimeShell; | ||
postgresql-dev = lib.getDev finalPackage; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,122 @@ | ||
#!@runtimeShell@ | ||
set -euo pipefail | ||
|
||
# The real pg_config needs to be in the same path as the "postgres" binary | ||
# to return proper paths. However, we want it in the -dev output to prevent | ||
# cyclic references and to prevent blowing up the runtime closure. Thus, we | ||
# have wrapped -dev/bin/pg_config to fake its argv0 to be in the default | ||
# output. Unfortunately, pg_config tries to be smart and tries to find itself - | ||
# which will then fail with: | ||
# pg_config: could not find own program executable | ||
# To counter this, we're creating *this* fake pg_config script and put it into | ||
# the default output. The real pg_config is happy. | ||
# Some extensions, e.g. timescaledb, use the reverse logic and look for pg_config | ||
# in the same path as the "postgres" binary to support multi-version-installs. | ||
# Thus, they will end up calling this script during build, even though the real | ||
# pg_config would be available on PATH, provided by nativeBuildInputs. To help | ||
# this case, we're redirecting the call to pg_config to the one found in PATH, | ||
# iff we can be convinced that it belongs to our -dev output. | ||
|
||
# Avoid infinite recursion | ||
if [[ ! -v PG_CONFIG_CALLED ]]; then | ||
# compares "path of *this* script" with "path, which pg_config on PATH believes it is in" | ||
if [[ "$(readlink -f -- "$0")" == "$(PG_CONFIG_CALLED=1 pg_config --bindir)/pg_config" ]]; then | ||
# The pg_config in PATH returns the same bindir that we're actually called from. | ||
# This means that the pg_config in PATH is the one from "our" -dev output. | ||
# This happens when the -dev output has been put in native build | ||
# inputs and allows us to call the real pg_config without referencing | ||
# the -dev output itself. | ||
exec pg_config "$@" | ||
fi | ||
# This replacement script for the pg_config binary is based on the original pg_config | ||
# shell script, which was removed from PostgreSQL's codebase in 2004: | ||
# https://github.com/postgres/postgres/commit/cc07f8cfe73f56fce1ddda4ea25d7b0b6c4f0ae9 | ||
# | ||
# The main reason for removal was the ability to relocate an existing installation, which | ||
# is exactly the one feature that we are trying to work around in nixpkgs. | ||
# Going back to a shell script is much better for cross compiling. | ||
# | ||
# This file is a combination of the following two files: | ||
# https://github.com/postgres/postgres/blob/7510ac6203bc8e3c56eae95466feaeebfc1b4f31/src/bin/pg_config/pg_config.sh | ||
# https://github.com/postgres/postgres/blob/master/src/bin/pg_config/pg_config.c | ||
|
||
source @postgresql-dev@/nix-support/pg_config.env | ||
|
||
help=" | ||
pg_config provides information about the installed version of PostgreSQL. | ||
Usage: | ||
pg_config [OPTION]... | ||
Options: | ||
--bindir show location of user executables | ||
--docdir show location of documentation files | ||
--htmldir show location of HTML documentation files | ||
--includedir show location of C header files of the client | ||
interfaces | ||
--pkgincludedir show location of other C header files | ||
--includedir-server show location of C header files for the server | ||
--libdir show location of object code libraries | ||
--pkglibdir show location of dynamically loadable modules | ||
--localedir show location of locale support files | ||
--mandir show location of manual pages | ||
--sharedir show location of architecture-independent support files | ||
--sysconfdir show location of system-wide configuration files | ||
--pgxs show location of extension makefile | ||
--configure show options given to \"configure\" script when | ||
PostgreSQL was built | ||
--cc show CC value used when PostgreSQL was built | ||
--cppflags show CPPFLAGS value used when PostgreSQL was built | ||
--cflags show CFLAGS value used when PostgreSQL was built | ||
--cflags_sl show CFLAGS_SL value used when PostgreSQL was built | ||
--ldflags show LDFLAGS value used when PostgreSQL was built | ||
--ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built | ||
--ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built | ||
--libs show LIBS value used when PostgreSQL was built | ||
--version show the PostgreSQL version | ||
-?, --help show this help, then exit | ||
With no arguments, all known items are shown. | ||
Report bugs to <${PACKAGE_BUGREPORT}>. | ||
${PACKAGE_NAME} home page: <${PACKAGE_URL}>" | ||
|
||
show=() | ||
|
||
for opt; do | ||
case "$opt" in | ||
--bindir) show+=("$PGBINDIR") ;; | ||
--docdir) show+=("$DOCDIR") ;; | ||
--htmldir) show+=("$HTMLDIR") ;; | ||
--includedir) show+=("$INCLUDEDIR") ;; | ||
--pkgincludedir) show+=("$PKGINCLUDEDIR") ;; | ||
--includedir-server) show+=("$INCLUDEDIRSERVER") ;; | ||
--libdir) show+=("$LIBDIR") ;; | ||
--pkglibdir) show+=("$PKGLIBDIR") ;; | ||
--localedir) show+=("$LOCALEDIR") ;; | ||
--mandir) show+=("$MANDIR") ;; | ||
--sharedir) show+=("$PGSHAREDIR") ;; | ||
--sysconfdir) show+=("$SYSCONFDIR") ;; | ||
--pgxs) show+=("@postgresql-dev@/lib/pgxs/src/makefiles/pgxs.mk") ;; | ||
--configure) show+=("$CONFIGURE_ARGS") ;; | ||
--cc) show+=("$CC") ;; | ||
--cppflags) show+=("$CPPFLAGS") ;; | ||
--cflags) show+=("$CFLAGS") ;; | ||
--cflags_sl) show+=("$CFLAGS_SL") ;; | ||
--ldflags) show+=("$LDFLAGS") ;; | ||
--ldflags_ex) show+=("$LDFLAGS_EX") ;; | ||
--ldflags_sl) show+=("$LDFLAGS_SL") ;; | ||
--libs) show+=("$LIBS") ;; | ||
--version) show+=("PostgreSQL $PG_VERSION") ;; | ||
--help|-\?) echo "$help" | ||
exit 0 ;; | ||
*) >&2 echo "pg_config: invalid argument: $opt" | ||
>&2 echo "Try \"pg_config --help\" for more information." | ||
exit 1 ;; | ||
esac | ||
done | ||
|
||
if [ ${#show[@]} -gt 0 ]; then | ||
printf '%s\n' "${show[@]}" | ||
exit 0 | ||
fi | ||
|
||
# This will happen in one of these cases: | ||
# - *this* script is the first on PATH | ||
# - np pg_config on PATH | ||
# - some other pg_config on PATH, not from our -dev output | ||
echo The real pg_config can be found in the -dev output. | ||
exit 1 | ||
# no arguments -> print everything | ||
cat <<EOF | ||
BINDIR = $PGBINDIR | ||
DOCDIR = $DOCDIR | ||
HTMLDIR = $HTMLDIR | ||
INCLUDEDIR = $INCLUDEDIR | ||
PKGINCLUDEDIR = $PKGINCLUDEDIR | ||
INCLUDEDIR-SERVER = $INCLUDEDIRSERVER | ||
LIBDIR = $LIBDIR | ||
PKGLIBDIR = $PKGLIBDIR | ||
LOCALEDIR = $LOCALEDIR | ||
MANDIR = $MANDIR | ||
SHAREDIR = $PGSHAREDIR | ||
SYSCONFDIR = $SYSCONFDIR | ||
PGXS = @postgresql-dev@/lib/postgresql/pgxs/src/makefiles/pgxs.mk | ||
CONFIGURE = $CONFIGURE_ARGS | ||
CC = $CC | ||
CPPFLAGS = $CPPFLAGS | ||
CFLAGS = $CFLAGS | ||
CFLAGS_SL = $CFLAGS_SL | ||
LDFLAGS = $LDFLAGS | ||
LDFLAGS_EX = $LDFLAGS_EX | ||
LDFLAGS_SL = $LDFLAGS_SL | ||
LIBS = $LIBS | ||
VERSION = PostgreSQL $PG_VERSION | ||
EOF |