mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-01-15 17:34:04 +00:00
68254e438c
This enables update scripts via buildPostgresqlExtension. Extensions must actively opt-out, if they don't support either the default configuration or the unstable configuration. To make the update script work, some extensions had to be changed to pull their code from GitHub instead. Those with PostgreSQL-style version tags (REL_X_Y) had to be changed to make src.rev the source of truth.
148 lines
6.2 KiB
Nix
148 lines
6.2 KiB
Nix
# PostgreSQL's build system for extensions (PGXS) makes the following assumptions:
|
|
# - All extensions will be installed in the same prefix as PostgreSQL itself.
|
|
# - pg_config is able to return the correct paths for bindir/libdir/datadir etc.
|
|
#
|
|
# Both of those assumptions break with nix. Since each extension is a separate
|
|
# derivation, we need to put all its files into a different folder. At the same
|
|
# time, pg_config only points to the PostgreSQL derivation's paths.
|
|
#
|
|
# When building extensions, the paths provided by pg_config are used for two
|
|
# purposes:
|
|
# - To find postgres libs and headers and reference those paths via -L and -I flags.
|
|
# - To determine the correct install directory.
|
|
#
|
|
# The PGXS Makefiles also support an environment variable DESTDIR, which is added as
|
|
# a prefix to all install locations. This is primarily used for temporary installs
|
|
# while running the test suite. Since pg_config returns absolute paths to /nix/store
|
|
# for us, using DESTDIR will result in install locations of the form:
|
|
# $DESTIDR/nix/store/<postgresql-output>/...
|
|
#
|
|
# In multiple iterations, the following approaches have been tried to work around all
|
|
# of this:
|
|
# 1. For a long time, all extensions in nixpkgs just overwrote the installPhase
|
|
# and moved the respective files to the correct location manually. This approach
|
|
# is not maintainable, because whenever upstream adds a new file, we'd have to
|
|
# make sure the file is correctly installed as well. Additionally, it makes adding
|
|
# a new extension harder than it should be.
|
|
#
|
|
# 2. A wrapper around pg_config could just replace the returned paths with paths to
|
|
# $out of currently building derivation, i.e. the extension. This works for install-
|
|
# ation, but breaks for any of the libs and headers the extension needs from postgres
|
|
# itself.
|
|
#
|
|
# 3. A variation of 2., but make the pg_config wrapper only return the changed paths
|
|
# during the installPahse. During configure and build, it would return the regular
|
|
# paths to the PostgreSQL derivation. This works better, but not for every case.
|
|
# Some extensions try to be smarter and search for the "postgres" binary to deduce
|
|
# the necessary paths from that. Those would still need special handling.
|
|
#
|
|
# 4. Use the fact that DESTDIR is prepended to every installation directory - and only
|
|
# there, to run a replacement of all Makefiles in postgres' lib/pgxs/ folder and
|
|
# all Makefiles in the extension's source. "$DESTDIR/$bindir" can be replaced with
|
|
# "$out/bin" etc. - thus mapping the installPhase directly into the right output.
|
|
# This works beautifully - for the majority of cases. But it doesn't work for
|
|
# some extensions that use CMake. And it doesn't work for some extensions that use
|
|
# custom variables instead of the default "bindir" and friends.
|
|
#
|
|
# 5. Just set DESTDIR to the extensions's output and then clean up afterward. This will
|
|
# result in paths like this:
|
|
# /nix/store/<extension-output>/nix/store/<postgresql-output>/...
|
|
# Directly after the installPhase, we'll move the files in the right folder.
|
|
# This seems to work consistently across all extensions we have in nixpkgs right now.
|
|
# Of course, it would break down for any extension that doesn't support DESTDIR -
|
|
# but that just means PGXS is not used either, so that's OK.
|
|
#
|
|
# This last approach is the one we're taking in this file. To make sure the removal of the
|
|
# nested nix/store happens immediately after the installPhase, before any other postInstall
|
|
# hooks run, this needs to be run in an override of `mkDerivation` and not in a setup hook.
|
|
|
|
{
|
|
lib,
|
|
stdenv,
|
|
postgresql,
|
|
nix-update-script,
|
|
}:
|
|
|
|
args:
|
|
|
|
let
|
|
buildPostgresqlExtension =
|
|
finalAttrs:
|
|
{
|
|
enableUpdateScript ? true,
|
|
...
|
|
}@prevAttrs:
|
|
{
|
|
passthru =
|
|
prevAttrs.passthru or { }
|
|
// lib.optionalAttrs enableUpdateScript {
|
|
updateScript =
|
|
prevAttrs.passthru.updateScript or (nix-update-script (
|
|
lib.optionalAttrs (lib.hasInfix "unstable" prevAttrs.version) {
|
|
extraArgs = [ "--version=branch" ];
|
|
}
|
|
));
|
|
};
|
|
|
|
buildInputs = [ postgresql ] ++ prevAttrs.buildInputs or [ ];
|
|
|
|
installFlags = [
|
|
"DESTDIR=${placeholder "out"}"
|
|
] ++ prevAttrs.installFlags or [ ];
|
|
|
|
postInstall =
|
|
''
|
|
# DESTDIR + pg_config install the files into
|
|
# /nix/store/<extension>/nix/store/<postgresql>/...
|
|
# We'll now remove the /nix/store/<postgresql> part:
|
|
if [[ -d "$out${postgresql}" ]]; then
|
|
cp -alt "$out" "$out${postgresql}"/*
|
|
rm -r "$out${postgresql}"
|
|
fi
|
|
|
|
if [[ -d "$out${postgresql.dev}" ]]; then
|
|
mkdir -p "''${dev:-$out}"
|
|
cp -alt "''${dev:-$out}" "$out${postgresql.dev}"/*
|
|
rm -r "$out${postgresql.dev}"
|
|
fi
|
|
|
|
if [[ -d "$out${postgresql.lib}" ]]; then
|
|
mkdir -p "''${lib:-$out}"
|
|
cp -alt "''${lib:-$out}" "$out${postgresql.lib}"/*
|
|
rm -r "$out${postgresql.lib}"
|
|
fi
|
|
|
|
if [[ -d "$out${postgresql.doc}" ]]; then
|
|
mkdir -p "''${doc:-$out}"
|
|
cp -alt "''${doc:-$out}" "$out${postgresql.doc}"/*
|
|
rm -r "$out${postgresql.doc}"
|
|
fi
|
|
|
|
if [[ -d "$out${postgresql.man}" ]]; then
|
|
mkdir -p "''${man:-$out}"
|
|
cp -alt "''${man:-$out}" "$out${postgresql.man}"/*
|
|
rm -r "$out${postgresql.man}"
|
|
fi
|
|
|
|
# In some cases (postgis) parts of the install script
|
|
# actually work "OK", before we add DESTDIR, so some
|
|
# files end up in
|
|
# /nix/store/<extension>/nix/store/<extension>/...
|
|
if [[ -d "$out$out" ]]; then
|
|
cp -alt "$out" "$out$out"/*
|
|
rm -r "$out$out"
|
|
fi
|
|
|
|
if [[ -d "$out/nix/store" ]]; then
|
|
if ! rmdir "$out/nix/store" "$out/nix"; then
|
|
find "$out/nix"
|
|
nixErrorLog 'Found left-overs in $out/nix/store, make sure to move them into $out properly.'
|
|
exit 1
|
|
fi
|
|
fi
|
|
''
|
|
+ prevAttrs.postInstall or "";
|
|
};
|
|
in
|
|
stdenv.mkDerivation (lib.extends buildPostgresqlExtension (lib.toFunction args))
|