diff --git a/debhelper/Debian/Debhelper/Buildsystem/pgxs.pm b/debhelper/Debian/Debhelper/Buildsystem/pgxs.pm new file mode 100644 index 0000000000000000000000000000000000000000..f1270ea63e47bdce3f71b05efa2190d05abf3366 --- /dev/null +++ b/debhelper/Debian/Debhelper/Buildsystem/pgxs.pm @@ -0,0 +1,58 @@ +# A debhelper build system class for building PostgreSQL extension modules using PGXS +# +# Per PostgreSQL major version, a `build-$version` subdirectory is created. +# +# Copyright: © 2020 Christoph Berg +# License: GPL-2+ + +package Debian::Debhelper::Buildsystem::pgxs; + +use strict; +use warnings; +use parent qw(Debian::Debhelper::Buildsystem); +use Cwd; +use Debian::Debhelper::Dh_Lib; +use Debian::Debhelper::pgxs; + +sub DESCRIPTION { + "PGXS (PostgreSQL extensions), building in subdirectory per PostgreSQL version" +} + +sub check_auto_buildable { + my $this=shift; + unless (-e $this->get_sourcepath("debian/pgversions")) { + error("debian/pgversions is required to build with PGXS"); + } + return (-e $this->get_sourcepath("Makefile")) ? 1 : 0; +} + +sub new { + my $class=shift; + my $this=$class->SUPER::new(@_); + $this->enforce_in_source_building(); + return $this; +} + +sub build { + my $this=shift; + $this->doit_in_sourcedir(qw(pg_buildext build build-%v)); +} + +sub install { + my $this=shift; + my $pattern = package_pattern(); + $this->doit_in_sourcedir(qw(pg_buildext install build-%v), $pattern); +} + +sub test { + my $this=shift; + verbose_print("Postponing tests to install stage"); +} + +sub clean { + my $this=shift; + my $pattern = package_pattern(); + $this->doit_in_sourcedir(qw(pg_buildext clean build-%v), $pattern); +} + +1; diff --git a/debhelper/Debian/Debhelper/Buildsystem/pgxs_loop.pm b/debhelper/Debian/Debhelper/Buildsystem/pgxs_loop.pm new file mode 100644 index 0000000000000000000000000000000000000000..716bcbfd2aba56e3ecf2931fcd8285193a1888ee --- /dev/null +++ b/debhelper/Debian/Debhelper/Buildsystem/pgxs_loop.pm @@ -0,0 +1,33 @@ +# A debhelper build system class for building PostgreSQL extension modules using PGXS +# +# For packages not supporting building in subdirectories, the pgxs_loop variant builds +# for each PostgreSQL major version in turn in the top-level directory. +# +# Copyright: © 2020 Christoph Berg +# License: GPL-2+ + +package Debian::Debhelper::Buildsystem::pgxs_loop; + +use strict; +use warnings; +use parent qw(Debian::Debhelper::Buildsystem::pgxs); +use Cwd; +use Debian::Debhelper::Dh_Lib; +use Debian::Debhelper::pgxs; + +sub DESCRIPTION { + "PGXS (PostgreSQL extensions), building for each PostgreSQL version in top level directory" +} + +sub build { + my $this=shift; + verbose_print("Postponing build to install stage; if this package supports out-of-tree builds, replace --buildsystem=pgxs_loop by --buildsystem=pgxs to build in the build stage"); +} + +sub install { + my $this=shift; + my $pattern = package_pattern(); + $this->doit_in_sourcedir(qw(pg_buildext loop), $pattern); +} + +1; diff --git a/debhelper/Debian/Debhelper/Sequence/pgxs.pm b/debhelper/Debian/Debhelper/Sequence/pgxs.pm new file mode 100644 index 0000000000000000000000000000000000000000..e6a56f1e1228ca574c81cd6b73efce6630f64a42 --- /dev/null +++ b/debhelper/Debian/Debhelper/Sequence/pgxs.pm @@ -0,0 +1,20 @@ +#!/usr/bin/perl + +use warnings; +use strict; +use Debian::Debhelper::Dh_Lib; + +# check if debian/control needs updating from debian/control.in +insert_after("dh_clean", "pg_buildext"); +add_command_options("pg_buildext", "checkcontrol"); + +# use PGXS for clean, build, and install +add_command_options("dh_auto_clean", "--buildsystem=pgxs"); +add_command_options("dh_auto_build", "--buildsystem=pgxs"); +add_command_options("dh_auto_install", "--buildsystem=pgxs"); + +# move tests from dh_auto_test to dh_pgxs_test +remove_command("dh_auto_test"); +insert_after("dh_auto_install", "dh_pgxs_test"); + +1; diff --git a/debhelper/Debian/Debhelper/Sequence/pgxs_loop.pm b/debhelper/Debian/Debhelper/Sequence/pgxs_loop.pm new file mode 100644 index 0000000000000000000000000000000000000000..f1c5a1bf0fc5a176c9e325b7a6e6452fd2492dce --- /dev/null +++ b/debhelper/Debian/Debhelper/Sequence/pgxs_loop.pm @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +use warnings; +use strict; +use Debian::Debhelper::Dh_Lib; + +# check if debian/control needs updating from debian/control.in +insert_after("dh_clean", "pg_buildext"); +add_command_options("pg_buildext", "checkcontrol"); + +# use PGXS for clean, build, and install +add_command_options("dh_auto_clean", "--buildsystem=pgxs_loop"); +add_command_options("dh_auto_build", "--buildsystem=pgxs_loop"); +add_command_options("dh_auto_install", "--buildsystem=pgxs_loop"); + +# move tests from dh_auto_test to dh_pgxs_test +remove_command("dh_auto_test"); +insert_after("dh_auto_install", "dh_pgxs_test"); +add_command_options("dh_pgxs_test", "loop"); + +1; diff --git a/debhelper/Debian/Debhelper/pgxs.pm b/debhelper/Debian/Debhelper/pgxs.pm new file mode 100644 index 0000000000000000000000000000000000000000..e3d86b2561198af6198ef6b4ac09769badc745c2 --- /dev/null +++ b/debhelper/Debian/Debhelper/pgxs.pm @@ -0,0 +1,38 @@ +# A debhelper build system class for building PostgreSQL extension modules using PGXS +# +# Copyright: © 2020 Christoph Berg +# License: GPL-2+ + +package Debian::Debhelper::pgxs; + +use strict; +use warnings; +use Exporter 'import'; +our @EXPORT = qw(package_pattern); + +=head1 package_pattern() + +From C<debian/control.in>, look for the package name containing the +B<PGVERSION> placeholder, and return it in the format suitable for passing to +B<pg_buildext>, i.e. with B<PGVERSION> replaced by B<%v>. + +For B<Package: postgresql-PGVERSION-unit> it will return B<postgresql-%v-unit>. + +Errors out if more than one package with the B<PGVERSION> placeholder is found. + +=cut + +sub package_pattern () { + open F, "debian/control.in" or die "debian/control.in: $!"; + my $pattern; + while (<F>) { + if (/^Package: (.*)PGVERSION(.*)/) { + die "More than one Package with PGVERSION placeholder found in debian/control.in, cannot build with dh --buildsystem=pgxs. Use pg_buildext manually." if ($pattern); + $pattern = "$1%v$2"; + } + } + close F; + return $pattern; +} + +1; diff --git a/debhelper/dh_pgxs_test b/debhelper/dh_pgxs_test new file mode 100755 index 0000000000000000000000000000000000000000..c12bacdfcc6980b65eadb14ad4ae29d23e8fb0cb --- /dev/null +++ b/debhelper/dh_pgxs_test @@ -0,0 +1,11 @@ +#!/usr/bin/perl + +use warnings; +use strict; +use Debian::Debhelper::Dh_Lib; +use Debian::Debhelper::pgxs; + +my $target = (@ARGV and $ARGV[0] eq 'loop') ? "." : "build-%v"; +my $pattern = package_pattern(); + +print_and_doit(qw(pg_buildext installcheck .), $target, $pattern); diff --git a/debian/changelog b/debian/changelog index 744d810a6cf98474623572960ff0a48f2eabc82d..5fd329f0f07a215866631754e2517b55c6212f8b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,11 @@ postgresql-common (217) UNRELEASED; urgency=medium * t/060_obsolete_confparams.t: Generate full config files dynamically. * dh_make_pgxs: Use current debhelper version instead of the oldest one, support setting homepage, general template copy-editing. + * Implement extension building as `dh $@ --with pgxs` and pgxs_loop, backed + by `--buildsystem=pgxs` and pgxs_loop. We also run `make installcheck` at + extension build time now via dh_pgxs_test and our PostgreSQL + extension_destdir patch. Previously extensions could only be tested at + runtime via autopkgtest. * Drop the PG major prefix from postgresql-all version number so extensions can declare sensible versioned dependencies on it. * Updated it debconf translation by Luca Monducci, thanks! (Closes: #969220) diff --git a/debian/copyright b/debian/copyright index ffab18e969dfbfd1032498e2ab150621dbe2d225..e307173e26682c565ee5187bd4fa5f763294e460 100644 --- a/debian/copyright +++ b/debian/copyright @@ -5,7 +5,7 @@ Files: * Copyright: 2005-2014 Martin Pitt <mpitt@debian.org> 2009 Cyril Bouthors <cyril@bouthors.org> 2010 Dimitri Fontaine <dfontaine@hi-media.com> - 2011-2014 Christoph Berg <myon@debian.org> + 2011-2020 Christoph Berg <myon@debian.org> 2013 Peter Eisentraut <petere@debian.org> License: GPL-2+ This program is free software; you can redistribute it and/or modify diff --git a/debian/postgresql-server-dev-all.install b/debian/postgresql-server-dev-all.install index ba66193c287455d43ff53d76b33d88721d0b3c8c..546bd2ef3158388f2d4425a9749148074d9a6556 100644 --- a/debian/postgresql-server-dev-all.install +++ b/debian/postgresql-server-dev-all.install @@ -1,4 +1,6 @@ gitlab usr/share/postgresql-common pgxs_debian_control.mk /usr/share/postgresql-common/ +debhelper/Debian /usr/share/perl5 +debhelper/dh_pgxs_test /usr/bin dh_make_pgxs/dh_make_pgxs /usr/bin dh_make_pgxs/debian /usr/share/postgresql-common/dh_make_pgxs diff --git a/dh_make_pgxs/debian/rules b/dh_make_pgxs/debian/rules index 7b28bd80f0c7dcf54092326b3138f041aa210426..563f0e9a29701939a56f836b145cf3df0b775c55 100755 --- a/dh_make_pgxs/debian/rules +++ b/dh_make_pgxs/debian/rules @@ -1,21 +1,32 @@ #!/usr/bin/make -f -include /usr/share/postgresql-common/pgxs_debian_control.mk - -override_dh_auto_build: - +pg_buildext build build-%v - -override_dh_auto_test: - # nothing to do here, see debian/tests/* instead - -override_dh_auto_install: - +pg_buildext install build-%v postgresql-%v-@EXTNAME@ +%: + dh $@ --buildsystem=pgxs override_dh_installdocs: dh_installdocs --all README.* -override_dh_auto_clean: - +pg_buildext clean build-%v +# if the package does not support building from subdirectories, use +# `--buildsystem=pgxs_loop` above. -%: - dh $@ +# classic `pg_buildext` interface: + +#include /usr/share/postgresql-common/pgxs_debian_control.mk +# +#override_dh_auto_build: +# +pg_buildext build build-%v +# +#override_dh_auto_test: +# # nothing to do here, see debian/tests/* instead +# +#override_dh_auto_install: +# +pg_buildext install build-%v postgresql-%v-@EXTNAME@ +# +#override_dh_installdocs: +# dh_installdocs --all README.* +# +#override_dh_auto_clean: +# +pg_buildext clean build-%v +# +#%: +# dh $@ diff --git a/pg_buildext b/pg_buildext index d01161ebeabee9da2689a579dd624a10517ff64a..ac7aa371ec66193e4b962793a860a7e87f0f859c 100755 --- a/pg_buildext +++ b/pg_buildext @@ -4,7 +4,7 @@ # versions # # (C) 2010 Dimitri Fontaine <dfontaine@hi-media.com> -# (C) 2011-2019 Christoph Berg <myon@debian.org> +# (C) 2011-2020 Christoph Berg <myon@debian.org> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -36,10 +36,12 @@ done # shift away args shift $(($OPTIND - 1)) +# positional arguments: action [srcdir] [target [opt]] [ "${1:-}" ] || die "no action given" action="$1" if [ -d "${2:-}" ] && [ "${3:-}" ]; then # optional: $2 is source directory srcdir="${2:-}" + [ "$srcdir" = "." ] && srcdir="$PWD" shift else srcdir="$PWD" @@ -90,15 +92,12 @@ install() { clean() { prepare_env $1 - - # if a Makefile was created by configure, use it, else the top level Makefile - [ -f $vtarget/Makefile ] || makefile="-f $srcdir/Makefile" - [ -d $vtarget ] && make -C $vtarget clean ${makefile:-} PG_CONFIG="$pgc" VPATH="$srcdir" USE_PGXS=1 $MAKEVARS - rm -rf $vtarget + if [ "$vtarget" ]; then + rm -rf $vtarget + fi } loop() { - echo "### $1 ###" prepare_env $1 package=$(echo $target | sed -e "s:%v:$1:g") @@ -108,7 +107,6 @@ loop() { make -C "$srcdir" PG_CONFIG="$pgc" USE_PGXS=1 $MAKEVARS echo "# $1: make install" make -C "$srcdir" install DESTDIR="$PWD/debian/$package" PG_CONFIG="$pgc" USE_PGXS=1 $MAKEVARS - echo "### done $1 ###" } installcheck() { @@ -122,10 +120,16 @@ installcheck() { export NONROOT=1 fi - if [ "$target" ]; then # if target is given, use it, else stay in the top source dir + # if a package pattern is given, tell pg_virtualenv where the installed files are + if [ "$opt" ]; then + pkg=$(echo "$opt" | sed -e "s:%v:$1:g") + PKGARGS="-o extension_destdir=$PWD/debian/$pkg -o dynamic_library_path=$PWD/debian/$pkg/usr/lib/postgresql/$1/lib:/usr/lib/postgresql/$1/lib" + fi + + if [ "$target" ] && [ "$target" != "." ]; then # if target is given, use it, else stay in the top source dir # if a Makefile was created by configure, use it, else the top level Makefile [ -f $vtarget/Makefile ] || makefile="-f $srcdir/Makefile" - if ! pg_virtualenv $VENVARGS -v $1 \ + if ! pg_virtualenv ${PKGARGS:-} $VENVARGS -v $1 \ make -C $vtarget ${makefile:-} installcheck \ PG_CONFIG="$pgc" VPATH="$srcdir" USE_PGXS=1 $MAKEVARS; then if [ -r $vtarget/regression.diffs ]; then @@ -135,7 +139,7 @@ installcheck() { exit 1 fi else - if ! pg_virtualenv $VENVARGS -v $1 \ + if ! pg_virtualenv ${PKGARGS:-} $VENVARGS -v $1 \ make installcheck PG_CONFIG="$pgc" USE_PGXS=1 $MAKEVARS; then if [ -r regression.diffs ]; then echo "**** regression.diffs ****" @@ -143,6 +147,8 @@ installcheck() { fi exit 1 fi + # since we are in the top-level directory, clean up behind us + make clean PG_CONFIG="$pgc" USE_PGXS=1 $MAKEVARS fi } @@ -188,7 +194,7 @@ gencontrol() { if [ -f debian/tests/control.in ]; then tmptestscontrol=$(mktemp debian/tests/control.XXXXXX) fi - trap "rm -f $tmpcontrol ${tmptestscontrol:-}" 0 2 3 15 + trap "rm -f $tmpcontrol ${tmptestscontrol:-}" EXIT export PGVERSIONS="$(versions)" [ "$PGVERSIONS" ] || die "No current PostgreSQL versions are supported by this package" @@ -241,8 +247,9 @@ case $action in configure-*|build-*|install-*|clean-*|installcheck-*) a=${action%%-*} v=${action##$a-} - echo "### $a $v ###" + echo "### PostgreSQL $v $a ###" $a $v + echo "### End $v $a ###" exit ;; @@ -273,21 +280,39 @@ case $action in exit ;; + clean) + if [ "$target" ]; then + pattern=$(echo "$target" | sed -e "s:%v:*:g") + echo rm -rf $pattern/ + rm -rf $pattern/ + fi + if [ "$opt" ]; then + pattern=$(echo "$opt" | sed -e "s:%v:*:g") + echo rm -rf debian/$pattern/ debian/$pattern.substvars + rm -rf debian/$pattern/ debian/$pattern.substvars + fi + make clean + exit + ;; + installed-versions) installed_versions exit ;; installcheck) - if [ -f debian/control.in ]; then + # prefer testing installed versions over supported versions as the set + # of versions might have changed (unless a package-pattern is provided) + if [ -f debian/control.in ] && [ -z "$opt" ]; then versions=$(installed_versions) else versions=$(versions) fi [ "$versions" ] || exit 1 for v in $versions; do - echo "### $action $v ###" + echo "### PostgreSQL $v $action ###" $action $v + echo "### End $v $action ###" done exit ;; @@ -304,8 +329,9 @@ do configure|build|install|clean|loop) [ "$target" ] || die "syntax: pg_buildext $action <target> [<srcdir>] [<opt>]" - echo "### $action $v ###" + echo "### PostgreSQL $v $action ###" $action $v + echo "### End $v $action ###" ;; *) diff --git a/pg_buildext.pod b/pg_buildext.pod index 27f1826cf817c60cdf099386088d8ae980367fcd..577e0ad94230250ce1901566d52de448e17838a4 100644 --- a/pg_buildext.pod +++ b/pg_buildext.pod @@ -15,6 +15,10 @@ C<debian/pgversions> (versions supported by the package) and in C</usr/share/postgresql-common/supported-versions> (versions supported in this release). +Many PostgreSQL extension packages require no special handling at build time +and can use B<dh $@ --with pgxs> or B<dh $@ --with pgxs_loop> to +automatically execute the steps outlined below. + =head1 USAGE Packages using B<pg_buildext> should be prepared to build binaries for @@ -115,9 +119,9 @@ The third parameter specifies the package name to use. Most packages use B<postgresql-%v-pkgname>. Make will be called with DESTDIR="$(CURDIR)/debian/I<package>". -=item B<clean> [I<src-dir>] I<build-dir> +=item B<clean> [I<src-dir>] [I<build-dir>] [I<package-pattern>] -Clean the build directory. +Clean the build directories. =item B<loop> [I<src-dir>] I<package-pattern> @@ -127,14 +131,19 @@ should be used if the package does not support VPATH builds. As it also invokes B<make install>, it should be placed were installation happens in debian/rules, rather than where build would normally be called. -=item B<installcheck> [I<src-dir>] [I<build-dir>] +=item B<installcheck> [I<src-dir>] [I<build-dir>] [I<package-pattern>] Use B<pg_virtualenv make installcheck> to run the extension regression tests. This is meant to be run from C<debian/tests/control> using B<autopkgtest>. If I<build-dir> is omitted, the top source directory is used. +If I<package-pattern> is given, options are passed to B<pg_virtualenv> to set +up the temporary PostgreSQL instance to find extension files in +C<debian/package-directory/>. + Other than the other actions which run on the "supported" versions, if C<debian/control.in> exists, this one -runs on the "installed" versions as reported by B<installed-versions>. +runs on the "installed" versions as reported by B<installed-versions> (unless +I<package-pattern> is provided, which means we are called during a build). =back @@ -193,7 +202,28 @@ configure the list of supported versions on your system. #9.6 #11+ -=item B<debian/rules:> +=item B<debian/rules> using B<dh $@ --with pgxs>: + + #!/usr/bin/make -f + + override_dh_installdocs: + dh_installdocs --all README.* + + %: + dh $@ --with pgxs + +=item If the package does no support building from subdirectories, use B<dh $@ --with pgxs_loop>: + + #!/usr/bin/make -f + + %: + dh $@ --with pgxs_loop + +=item If the package does not use PGXS's "make installcheck" for testing: + + override_dh_pgxs_test: + +=item B<debian/rules> using B<pg_buildext> directly: #!/usr/bin/make -f @@ -276,6 +306,9 @@ introduced in postgresql-common (>= 171~). The action B<installed-versions> was introduced in postgresql-common (>= 208~). B<installcheck> was switched to use it in the same version. +B<dh $@ --with pgxs> and B<pgxs_loop>, and the corresponding B<--buildsystem> +were introduced in postgresql-server-dev-all (>= 217~). + =head1 SEE ALSO C</usr/share/postgresql-common/supported-versions>, autopkgtest(1),