diff options
Diffstat (limited to 'doc/postgresql-debian-packaging.md')
-rw-r--r-- | doc/postgresql-debian-packaging.md | 741 |
1 files changed, 741 insertions, 0 deletions
diff --git a/doc/postgresql-debian-packaging.md b/doc/postgresql-debian-packaging.md new file mode 100644 index 0000000..4edd9ca --- /dev/null +++ b/doc/postgresql-debian-packaging.md @@ -0,0 +1,741 @@ +Packaging PostgreSQL Extensions for Debian +========================================== +January 2024, Christoph Berg <myon@debian.org> + +Debian ships many PostgreSQL applications and extensions as packages. I often +get asked by developers how they would get their programs packaged, and ended +up writing the same reply over and over. This is a write-up intended as a more +thorough answer. + +# Anatomy of Debian packages + +Debian knows two sorts of packages: "source" packages and "binary" packages. +The latter type is the `.deb` files that get installed using apt or dpkg. The +first type is what this article is mostly about. For both sorts of packages, +there is an unpacked form and a packed form. + +## Binary packages + +Packed binary packages are a single `.deb` file: + +``` +$ ls -al postgresql-16-unit_7.7-1_amd64.deb +-rw-r--r-- 1 myon myon 136740 Jan 12 14:13 postgresql-16-unit_7.7-1_amd64.deb + +$ dpkg-deb -I postgresql-16-unit_7.7-1_amd64.deb + new Debian package, version 2.0. + size 136740 bytes: control archive=1332 bytes. + 643 bytes, 15 lines control + 2046 bytes, 25 lines md5sums + Package: postgresql-16-unit + Source: postgresql-unit + Version: 7.7-1 + Architecture: amd64 + Maintainer: Christoph Berg <myon@debian.org> + Installed-Size: 500 + Depends: postgresql-16, postgresql-16-jit-llvm (>= 16), libc6 (>= 2.14) + Section: database + Priority: optional + Homepage: https://github.com/df7cb/postgresql-unit + Description: SI Units for PostgreSQL + postgresql-unit implements a PostgreSQL datatype for SI units, plus byte. The + base units can be combined to named and unnamed derived units using operators + defined in the PostgreSQL type system. SI prefixes are used for input and + output, and quantities can be converted to arbitrary scale. + +$ dpkg-deb -c postgresql-16-unit_7.7-1_amd64.deb +drwxr-xr-x root/root 0 2023-01-06 16:34 ./ +drwxr-xr-x root/root 0 2023-01-06 16:34 ./usr/ +drwxr-xr-x root/root 0 2023-01-06 16:34 ./usr/share/ +drwxr-xr-x root/root 0 2023-01-06 16:34 ./usr/share/doc/ +drwxr-xr-x root/root 0 2023-01-06 16:34 ./usr/share/doc/postgresql-16-unit/ +-rw-r--r-- root/root 267 2023-01-06 16:34 ./usr/share/doc/postgresql-16-unit/NEWS.Debian.gz +-rw-r--r-- root/root 7202 2023-01-06 16:34 ./usr/share/doc/postgresql-16-unit/README.md.gz +-rw-r--r-- root/root 977 2023-01-06 16:34 ./usr/share/doc/postgresql-16-unit/changelog.Debian.gz +-rw-r--r-- root/root 868 2023-01-06 16:34 ./usr/share/doc/postgresql-16-unit/copyright +drwxr-xr-x root/root 0 2023-01-06 16:34 ./usr/share/postgresql/ +drwxr-xr-x root/root 0 2023-01-06 16:34 ./usr/share/postgresql/16/ +drwxr-xr-x root/root 0 2023-01-06 16:34 ./usr/share/postgresql/16/extension/ +-rw-r--r-- root/root 19259 2023-01-06 16:34 ./usr/share/postgresql/16/extension/unit--7.sql +-rw-r--r-- root/root 244 2023-01-06 16:34 ./usr/share/postgresql/16/extension/unit.control +... +``` + +The unpacked binary package is of course the files being installed on the +system. + +## Source packages + +Unpacked source packages consist of the original upstream source code, with a `debian/` directory added. + +``` +postgresql-unit/ +├── debian/ +│ ├── changelog +│ ├── control +│ ├── control.in +│ ├── copyright +│ ├── gitlab-ci.yml +│ ├── NEWS +│ ├── pgversions +│ ├── rules* +│ ├── source/ +│ │ └── format +│ ├── tests/ +│ │ ├── control +│ │ └── installcheck* +│ ├── upstream/ +│ │ └── metadata +│ └── watch +├── Makefile +├── NEWS.md +├── README.md +├── unit--7.sql.in +├── unit.c +└── unit.control +``` + +Most packages are maintained in Git, which tracks this unpacked source package +form. (Either with or without the original upstream source, more on that +later.) + +Packed source packages are actually a set of files: + +``` +-rw-rw-r-- 1 myon myon 3848 Jan 12 14:31 postgresql-unit_7.7-1.debian.tar.xz +-rw-rw-r-- 1 myon myon 1100 Jan 12 14:31 postgresql-unit_7.7-1.dsc +-rw-rw-r-- 1 myon myon 414114 Jan 12 14:12 postgresql-unit_7.7.orig.tar.gz +``` + +This transport format is used for uploading to the Debian archive and for +retrieving the source code using `apt source`. (It is not stored in Git.) + +The `.orig.tar.gz` is the original source tarball as distributed by upstream, +either as download from the upstream homepage, or for projects hosted on +GitHub, often a tarball automatically generated by GitHub from an upstream Git +tag. + +The `.debiar.tar.xz` file contains the `debian/` directory. + +The `.dsc` file is a descriptor that contains pointers to the other files in +the source package, and more meta information. + +``` +$ cat postgresql-unit_7.7-1.dsc +Format: 3.0 (quilt) +Source: postgresql-unit +Binary: postgresql-16-unit +Architecture: any +Version: 7.7-1 +Maintainer: Christoph Berg <myon@debian.org> +Homepage: https://github.com/df7cb/postgresql-unit +Standards-Version: 4.6.1 +Vcs-Browser: https://github.com/df7cb/postgresql-unit +Vcs-Git: https://github.com/df7cb/postgresql-unit.git +Testsuite: autopkgtest +Testsuite-Triggers: make +Build-Depends: bison, debhelper-compat (= 13), flex, postgresql-server-dev-all (>= 217~) +Package-List: + postgresql-16-unit deb database optional arch=any +Checksums-Sha1: + c2f81968bfbe83fed49b084b737e3aba423bf15a 414114 postgresql-unit_7.7.orig.tar.gz + b8a1917ddecb99b1441218bc74a0b7cb30752235 3848 postgresql-unit_7.7-1.debian.tar.xz +Checksums-Sha256: + 411d05beeb97e5a4abf17572bfcfbb5a68d98d1018918feff995f6ee3bb03e79 414114 postgresql-unit_7.7.orig.tar.gz + 36e89c762e50ddf997b079703200c0df6967b4fe911bde8e9482d8e82dcb6a98 3848 postgresql-unit_7.7-1.debian.tar.xz +Files: + 33a22586c8b81564ba7e9c05f430ad40 414114 postgresql-unit_7.7.orig.tar.gz + a0b31860b86c12c7173a78d6ecd525cb 3848 postgresql-unit_7.7-1.debian.tar.xz +``` + +## Building the source package + +To get started with working with a Debian package, get the unpacked source +package. This could mean invoking `apt source`, but most often checking out the +packaging Git repository is the better option as it might contain changes that +have not been uploaded yet. It also makes contributing changes easier. For +packages, that are already part of Debian, the `debcheckout` tool can automate +that (it uses the `Vcs-Git` field in the metadata). + +To build the packed source packed from the unpacked one, enter the package +directory, and invoke `dpkg-buildpackage -S --no-sign`: + +``` +postgresql-unit $ dpkg-buildpackage -S --no-sign +dpkg-buildpackage: info: source package postgresql-unit +dpkg-buildpackage: info: source version 7.7-1 +dpkg-buildpackage: info: source distribution unstable +dpkg-buildpackage: info: source changed by Christoph Berg <myon@debian.org> + dpkg-source --before-build . + debian/rules clean +dh clean --with pgxs +... + dpkg-source -b . +dpkg-source: info: using source format '3.0 (quilt)' +dpkg-source: info: building postgresql-unit using existing ./postgresql-unit_7.7.orig.tar.gz +dpkg-source: info: building postgresql-unit in postgresql-unit_7.7-1.debian.tar.xz +dpkg-source: info: building postgresql-unit in postgresql-unit_7.7-1.dsc + dpkg-genbuildinfo --build=source -O../postgresql-unit_7.7-1_source.buildinfo + dpkg-genchanges --build=source -O../postgresql-unit_7.7-1_source.changes +dpkg-genchanges: info: including full source code in upload + dpkg-source --after-build . +dpkg-buildpackage: info: source-only upload (original source is included) +``` + +Note that the artifacts produced by `dpkg-buildpackage` are always in the *parent* directory of the working directory. +To make room for that, I always create *two* levels of directory for my working copies, so a typical case looks like this: + +``` +postgresql-unit/ +├── postgresql-unit/ <--- most commands are invoked from here +│ ├── debian/ +│ │ ├── changelog +│ │ ├── control +│ │ ├── control.in +│ │ ├── copyright +│ │ ├── files +│ │ ├── gitlab-ci.yml +│ │ ├── NEWS +│ │ ├── pgversions +│ │ ├── rules* +│ │ ├── source/ +│ │ │ └── format +│ │ ├── tests/ +│ │ │ ├── control +│ │ │ └── installcheck* +│ │ ├── upstream/ +│ │ │ └── metadata +│ │ └── watch +│ ├── Makefile +│ ├── NEWS.md +│ ├── powers.c +│ ├── powers.h +│ ├── README.md +│ ├── unit--7.sql.in +│ ├── unit.c +│ └── unit.control +├── postgresql-16-unit_7.7-1_amd64.deb +├── postgresql-16-unit-dbgsym_7.7-1_amd64.deb +├── postgresql-unit_7.7-1_amd64.changes +├── postgresql-unit_7.7-1.debian.tar.xz +├── postgresql-unit_7.7-1.dsc +└── postgresql-unit_7.7.orig.tar.gz +``` + +## Building binary packages + +Binary packages are built using `dpkg-buildpackage --no-sign`. + +``` + dpkg-buildpackage --no-sign +dpkg-buildpackage: info: source package postgresql-unit +dpkg-buildpackage: info: source version 7.7-1 +dpkg-buildpackage: info: source distribution unstable +dpkg-buildpackage: info: source changed by Christoph Berg <myon@debian.org> +dpkg-buildpackage: info: host architecture amd64 + dpkg-source --before-build . + debian/rules clean +dh clean --with pgxs +... + dpkg-source -b . +dpkg-source: info: using source format '3.0 (quilt)' +dpkg-source: info: building postgresql-unit using existing ./postgresql-unit_7.7.orig.tar.gz +dpkg-source: info: building postgresql-unit in postgresql-unit_7.7-1.debian.tar.xz +dpkg-source: info: building postgresql-unit in postgresql-unit_7.7-1.dsc + debian/rules binary +dh binary --with pgxs + dh_update_autotools_config + dh_autoreconf + dh_auto_configure + dh_auto_build --buildsystem=pgxs + pg_buildext build build-%v +### PostgreSQL 16 build ### +make[1]: Entering directory '/home/myon/projects/postgresql/postgresql-unit/postgresql-unit/build-16' +gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O2 -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fno-omit-frame-pointer -g -O2 -ffile-prefix-map=/home/myon/projects/postgresql/postgresql-unit/postgresql-unit=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fPIC -fvisibility=hidden -ffp-contract=off -I. -I/home/myon/postgresql/postgresql-unit/postgresql-unit -I/usr/include/postgresql/16/server -I/usr/include/postgresql/internal -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2 -c -o unit.o /home/myon/postgresql/postgresql-unit/postgresql-unit/unit.c +... +### End 16 build ### + create-stamp debian/debhelper-build-stamp + dh_prep + dh_auto_install --buildsystem=pgxs --destdir=debian/postgresql-16-unit/ + pg_buildext install build-%v postgresql-%v-unit +### PostgreSQL 16 install ### +make[1]: Entering directory '/home/myon/projects/postgresql/postgresql-unit/postgresql-unit/build-16' +/usr/bin/install -c -m 755 unit.so '/home/myon/postgresql/postgresql-unit/postgresql-unit/debian/postgresql-16-unit/usr/lib/postgresql/16/lib/unit.so' +... +### End 16 install ### + debian/rules override_dh_installdocs +make[1]: Entering directory '/home/myon/projects/postgresql/postgresql-unit/postgresql-unit' +dh_installdocs --all README.* +make[1]: Leaving directory '/home/myon/projects/postgresql/postgresql-unit/postgresql-unit' + dh_installchangelogs + dh_perl + dh_link + debian/rules override_dh_pgxs_test +make[1]: Entering directory '/home/myon/projects/postgresql/postgresql-unit/postgresql-unit' +# defer testing to autopkgtest, the data tables are not in /usr/share/postgresql yet +make[1]: Leaving directory '/home/myon/projects/postgresql/postgresql-unit/postgresql-unit' + dh_strip_nondeterminism + dh_compress + dh_fixperms + dh_missing + dh_dwz -a + dh_strip -a + dh_makeshlibs -a + dh_shlibdeps -a + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb +dpkg-deb: building package 'postgresql-16-unit' in '../postgresql-16-unit_7.7-1_amd64.deb'. +dpkg-deb: building package 'postgresql-16-unit-dbgsym' in '../postgresql-16-unit-dbgsym_7.7-1_amd64.deb'. + dpkg-genbuildinfo -O../postgresql-unit_7.7-1_amd64.buildinfo + dpkg-genchanges -O../postgresql-unit_7.7-1_amd64.changes +dpkg-genchanges: info: including full source code in upload + dpkg-source --after-build . +dpkg-buildpackage: info: full upload (original source is included) +``` + +Again, the resulting `.deb` files are placed in the parent directory. + +By default, this also builds the source. If this fails (often when there are +files that differ from the tarball version, more on patches later), use `-b` to +skip building the source: `dpkg-buildpackage -b --no-sign`. + +If building fails because of missing dependencies, install them using +`apt build-dep .`. + +There are various front-end utilities to automate these building steps better +(git-buildpackage, sbuild, pbuilder, debuild), but dpkg-buildpackage is just +fine. + +## The debian/ directory + +The `debian/` directory contains metadata and build instructions for the +package. "Creating a Debian package" really means editing the files in this +directory to make the package behave as desired. + +### debian/control + +The control file contains one section for the source package, followed by one +or more sections for binary packages. + +``` +$ cat debian/control +Source: postgresql-unit +Section: database +Priority: optional +Maintainer: Christoph Berg <myon@debian.org> +Build-Depends: + bison, + debhelper-compat (= 13), + flex, + postgresql-server-dev-all (>= 217~), +Standards-Version: 4.6.1 +Rules-Requires-Root: no +Vcs-Git: https://github.com/df7cb/postgresql-unit.git +Vcs-Browser: https://github.com/df7cb/postgresql-unit +Homepage: https://github.com/df7cb/postgresql-unit + +Package: postgresql-16-unit +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends}, postgresql-16 +Description: SI Units for PostgreSQL + postgresql-unit implements a PostgreSQL datatype for SI units, plus byte. The + base units can be combined to named and unnamed derived units using operators + defined in the PostgreSQL type system. SI prefixes are used for input and + output, and quantities can be converted to arbitrary scale. +``` + +(In the case of PostgreSQL extension packages, the control file is +automatically generated from `debian/control.in`, see below. Normal packages do +not have a control.in file.) + +### debian/rules + +The rules file handles the actual binary package building steps, in Makefile +syntax. + +Almost all packages today use a helper system called `debhelper` which consists +of various building blocks called `dh_*` that handle the build steps. +Historically, rules files would consist of long lists of `dh_*` steps (similar +to the build output above), but there is a "sequencer" command `dh` that knows +how to invoke the basic steps. + +Many packages that don't need any tweaking at that level have a very short +`debian/rules` file. (Make sure the indentation is a tab, not spaces!) + +``` +#!/usr/bin/make -f + +%: + dh $@ +``` + +Or in the case of PostgreSQL extensions: + +``` +#!/usr/bin/make -f + +%: + dh $@ --with pgxs +``` + +If any of the `dh_*` steps need changes, we can override them in the rules file +by adding a `override_dh_*` target: + +``` +#!/usr/bin/make -f + +override_dh_installdocs: + dh_installdocs --all README.* + +override_dh_pgxs_test: + # defer testing to autopkgtest, the data tables are not in /usr/share/postgresql yet + +%: + dh $@ --with pgxs +``` + +### Build steps + +The most interesting build steps to hook into are: + +#### `dh_auto_configure` + +Autodetects the build system and runs `./configure`, `cmake` and the like with +a set of default options. + +To add options, do: + +``` +override_dh_auto_configure: + dh_auto_configure -- -DEXTRA_OPTION=foo --with-bar +``` + +#### `dh_auto_build` + +The main build step. If the automatically run command is wrong, just override it. + +``` +override_dh_auto_build: + $(MAKE) -C some_sub_dir world +``` + +#### `dh_auto_install` + +Runs upstreams' `make install` or equivalent. The files are installed into +`DESTDIR=debian/foo` (single-binary package) or `DESTDIR=debian/tmp` +(multi-binary package). + +#### `dh_install` and `debian/foo.install` + +If there is more than one binary package, the files installed in `debian/tmp` +need to be distributed to the individual binary packages. This is done by +directory/file lists in `debian/*.install`. + +### debian/source/format + +Should be verbatim this: + +``` +3.0 (quilt) +``` + +(More on quilt and patches below.) + +### debian/copyright + +Debian wants copyright information on *all* files in a package. For private +package, this file can be omitted, but for anything official, this file has to +list all the copyright holders, along with any copyright terms and license +texts. + +### debian/watch + +To get informed about new upstream versions, Debian runs a "watch" system that +polls upstream download locations for new package versions. The `debian/watch` +file tells the `uscan` tool where to look and (optionally) how to transform +upstream's version naming scheme into a Debian-compatible one. + +``` +version=4 +https://github.com/df7cb/postgresql-unit/tags .*/([0-9.]*).tar.gz +``` + +This is a simple example where `uscan` looks at some GitHub "tags" URL, parses +the HTML, and recognizes all links pointing to .tar.gz files as new versions. +The regexp part of the URL in parentheses is used as the version number. + +The `uscan` tool is part of the `devscripts` package which holds a bunch of +utilities useful for packaging tasks. + +## Patching the upstream source + +Debian packages are based on upstream tarballs, and `dpkg-buildpackage` does +not like changed (or new) files (except in the `debian/` directory). Changes +need to be done using patch files stored in the `debian/patches/` directory, +and applied in the order listed in `debian/patches/series`. + +At package build time, support is built-in in dpkg-buildpackage. Patches can +edited with whatever tool, with `quilt` being the easiest solution. (It's an +optional package that likely isn't preinstalled.) `quilt` needs some +configuration in `~/.quiltrc`: + +``` +QUILT_DIFF_OPTS="-p" +QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index" +QUILT_PATCHES=debian/patches +``` + +Some useful commands: + +* Apply all patches: `quilt push -a` +* Unapply all patches: `quilt pop -a` +* Create a new patch: `quilt new foo` +* Add a file to a patch: `quilt add bar` (do this *before* changing the file!) +* Add a file and edit it: `quilt edit bar` +* Show current diff: `quilt diff` +* Save a patch after editing: `quilt refresh` + +Suppose we want to fix something in the `unit.c` file: + +``` +$ quilt new unit-dllexport +Patch unit-dllexport is now on top + +$ quilt add unit.c +File unit.c added to patch unit-dllexport + +$ vi unit.c + +$ quilt diff | cat +Index: postgresql-unit/unit.c +=================================================================== +--- postgresql-unit.orig/unit.c 2023-11-08 20:51:04.343207806 +0100 ++++ postgresql-unit/unit.c 2024-01-12 16:10:23.143509535 +0100 +@@ -136,7 +136,7 @@ unit_get_definitions(void) + + PG_MODULE_MAGIC; + +-void _PG_init(void); ++void PGDLLEXPORT _PG_init(void); + + void + _PG_init(void) + +$ quilt refresh +Refreshed patch unit-dllexport +``` + +This creates the `debian/patches/` directory: + +``` +postgresql-unit/debian/patches/ +├── series +└── unit-dllexport +``` + +At build-time, `dpkg-buildpackage` will then automatically apply and un-apply +patches as needed. + +## Tests + +Package tests are run in two flavors: at build-time and later independently on +packages installed on some system. + +### Build-time package tests + +If an upstream project has a test suite, it is recommended to run it at build +time. In many cases, `dh_auto_test` will guess how to do that and no extra +configuration is needed. If it guesses incorrectly, use `override_dh_auto_test` +to provide a better command. + +### Install-time package tests + +Next to tests at build-time, we can also run tests when the binary packages are +installed on some actual system. This has the advantage that it runs when all +files are in their final location, and can also interface with other packages +and services that might not be available at build time. It can also run +periodically to spot regression, while build-time tests would usually not be +repeated. + +Debian's system to run these tests is `autopkgtest`. The TL;DR version of the +documentation is this: In the `debian/tests/` directory, provide a command +(usually a shell script) that exercises some package smoke test or more complex +scenario. Register that test in `debian/tests/control`. + +``` +postgresql-unit/debian/tests/ +├── control +└── installcheck* + +$ cat debian/tests/control +Depends: @, make +Tests: installcheck +Restrictions: allow-stderr + +$ cat debian/tests/installcheck +#!/bin/sh +pg_buildext -i '--locale=C.UTF-8' installcheck +``` + +In `Depends` the `@` is a shorthand for all binary packages built from this +source. Other packages that the tests needs (and that the binaries don't depend +on) can be listed here. `Restrictions` declare tests properties. Examples are +`allow-stderr` (don't consider stderr output to be a test failure) and +`root-needed` (run test as root instead of an unprivileged user). + +In Debian, these tests are run automatically for QA, see +https://ci.debian.net/. More details are in the autopkgtest package +documentation in /usr/share/doc/autopkgtest/. + +# PostgreSQL extension packages + +Packages for PostgreSQL extensions work as described above, but since +extensions have to be compiled for each PostgreSQL major version separately, +things are a bit more complex. + +For Debian, the process is changed to still have one source package per +upstream project, but to build separate binary packages for each PostgreSQL +major version. The naming scheme is `postgresql-NN-foo`. (In case the upstream +project is called `pg_foo`, make a judgment call if `postgresql-NN-pg-foo` or +`postgresql-NN-foo` is better.) + +In Debian, only one PostgreSQL major version is supported at a time, but in the +https://apt.postgresql.org/ repository, many major versions are supported in +parallel (currently PostgreSQL 10 everything newer, even when 10 is already +EOL). + +## `debian/control.in` + +In order not to have to edit the list of binary packages built when a new +PostgreSQL major version comes out, or when a source package is built both for +Debian and for apt.postgresql.org, the `debian/control` file is generated from +a template in `debian/control.in`. + +``` +$ cat debian/control.in +Source: postgresql-unit +Section: database +Priority: optional +Maintainer: Christoph Berg <myon@debian.org> +Build-Depends: + bison, + debhelper-compat (= 13), + flex, + postgresql-server-dev-all (>= 217~), +Standards-Version: 4.6.2 +Rules-Requires-Root: no +Vcs-Git: https://github.com/df7cb/postgresql-unit.git +Vcs-Browser: https://github.com/df7cb/postgresql-unit +Homepage: https://github.com/df7cb/postgresql-unit + +Package: postgresql-PGVERSION-unit +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends}, ${postgresql:Depends} +Description: SI Units for PostgreSQL + postgresql-unit implements a PostgreSQL datatype for SI units, plus byte. The + base units can be combined to named and unnamed derived units using operators + defined in the PostgreSQL type system. SI prefixes are used for input and + output, and quantities can be converted to arbitrary scale. +``` + +The section with the `PGVERSION` token is duplicated for each major version +supported, with the version number filled in. + +## `debian/pgversions` + +Not every package supports all PostgreSQL major versions. The +`debian/pgversions` file is used to mark which versions are actually supported, +so apt.postgresql.org can skip building the other version. + +Unless we know the exact versions supported, we should use `all`: + +``` +$ cat debian/pgversions +all +``` + +If 14 or newer is supported: + +``` +$ cat debian/pgversions +14+ +``` + +### Supported versions + +`debian/pgversions` lists the versions supported *by the package*. The other +half of that system is the set of versions supported *by the system*. This list +is configured in `/etc/postgresql-common/supported_versions` or by setting the +`PG_SUPPORTED_VERSIONS` environment variable. (Set this variable to test +building for other major versions.) The actual build process will use the +intersection of these two lists. + +## `pg_buildext` + +The process of building PostgreSQL extensions for several major versions is +automated by the `pg_buildext` utility. It provides commands for the most +common tasks. + +Package building: + +* `pg_buildext supported-versions` - print list of supported versions. + Use this to loop over versions in `debian/rules`. +* `pg_buildext build build-%v` - build in `build-%v` directory +* `pg_buildext install build-%v postgresql-%v-unit` - invoke `make install` +* `pg_buildext installcheck build-%v postgresql-%v-unit` - invoke + `make installcheck` for build-time testing +* `pg_buildext loop postgresql-%v-unit` - use instead of + `build/install/installcheck` if the package doesn't support out-of-tree + builds in subdirectories +* `pg_buildext updatecontrol` - rebuild `debian/control` from + `debian/control.in`. Run this manually when the set of supported versions has + changed. This is not run automatically because the Debian packaging policy + forbids changing the set of binary packages at build time. (In environments + where this is not an issue, set `PG_UPDATECONTROL=yes`.) + +Package testing: + +* `pg_buildext installed-versions` - print list of installed versions. + Use this to loop over versions in `debian/tests/*`. +* `pg_buildext installcheck` - invoke `make installcheck` on installed packages + +## `dh --with pgxs` + +A debhelper extension `pgxs` is provided that adds builds steps to the `dh` +build sequence. + +``` +$ cat debian/rules +#!/usr/bin/make -f + +%: + dh $@ --with pgxs +``` + +If the package doesn't support out-of-tree builds, use +`dh $@ --with pgxs_loop`. + +``` + dh_auto_build --buildsystem=pgxs + pg_buildext build build-%v + dh_auto_install --buildsystem=pgxs + pg_buildext install build-%v postgresql-%v-unit + dh_pgxs_test + pg_buildext installcheck . build-%v postgresql-%v-unit +``` + +To override any of these steps, use `override_dh_auto_*` in `debian/rules`. + +## Package template + +To get started with a new package, the `dh_make_pgxs` tool can generate a +skeleton `debian/` directory: + +``` +$ dh_make_pgxs +``` + +If the auto-detected values are wrong, hit `^C` and add more command line +parameters. |