Last year, around this time, there started a thread on hackers which was about building PostgreSQL with meson. I didn’t know anything about Meson at this time, and don’t know much more right now, but as it seems to be related to build times and times to get test results I though I’ll have a look (there are more, and even more serious reasons mentioned in the thread, but you can read that on your own).
Getting Meson and Ninja (the backend systems by Meson by default) onto a Debian 11 system is just installing the packages (pretty much the same for Red Hat base systems):
[email protected]:/home/postgres/ [pg16] sudo apt install -y meson ninja-build
One requirement of Meson is, that the build has to happen outside of the source tree, so lets create an empty directory for that:
[email protected]:/home/postgres/ [pg16] mkdir postgresql-build
post[email protected]:/home/postgres/ [pg16] cd postgresql-build/
The source code of PostgreSQL in this case is on the same level as the build directory:
[email protected]:/home/postgres/postgresql-build/ [pg16] pwd
/home/postgres/postgresql-build
11:58:49 [email protected]:/home/postgres/postgresql-build/ [pg16] ls ../postgresql
aclocal.m4 config configure configure.ac contrib COPYRIGHT doc GNUmakefile.in HISTORY Makefile meson.build meson_options.txt postgresql-14-A4.pdf README README.git src
We (dbi) usually define the location where we want to have PostgreSQL installed, the segment size and the block size be defining these variables:
[email protected]:/home/postgres/postgresql-build/ [pg16] PGHOME=/var/tmp/pgsql
[email protected]:/home/postgres/postgresql-build/ [pg16] SEGSIZE=2
[email protected]:/home/postgres/postgresql-build/ [pg16] BLOCKSIZE=8
What usually follows is the configure phase, which we do like this:
./configure --prefix=${PGHOME} \
--exec-prefix=${PGHOME} \
--bindir=${PGHOME}/bin \
--libdir=${PGHOME}/lib \
--sysconfdir=${PGHOME}/etc \
--includedir=${PGHOME}/include \
--datarootdir=${PGHOME}/share \
--datadir=${PGHOME}/share \
--with-pgport=5432 \
--with-perl \
--with-python \
--with-openssl \
--with-pam \
--with-ldap \
--with-libxml \
--with-libxslt \
--with-segsize=${SEGSIZE} \
--with-blocksize=${BLOCKSIZE} \
--with-llvm LLVM_CONFIG='/usr/bin/llvm-config' \
--with-uuid=ossp \
--with-lz4 \
--with-zstd \
--with-gssapi \
--with-systemd \
--with-icu \
--with-system-tzdata=/usr/share/zoneinfo
With Meson this changes. First, we need to initialize the build directory (The first dot is the build directory, the second path is the location of the source code):
[email protected]:/home/postgres/postgresql-build/ [pg16] meson setup . ../postgresql
The Meson build system
Version: 0.56.2
Source dir: /home/postgres/postgresql
Build dir: /home/postgres/postgresql-build
Build type: native build
Project name: postgresql
Project version: 16devel
C compiler for the host machine: cc (gcc 10.2.1 "cc (Debian 10.2.1-6) 10.2.1 20210110")
C linker for the host machine: cc ld.bfd 2.35.2
Host machine cpu family: x86_64
...
Program xmllint found: NO
Configuring version.sgml using configuration
Message: checking for file conflicts between source and build directory
Build targets in project: 384
Found ninja-1.10.1 at /usr/bin/ninja
We could already have configured the build options with the setup stage, but now we can easily check what is available:
[email protected]:/home/postgres/postgresql-build/ [pg16] meson configure
Core properties:
Source dir /home/postgres/postgresql
Build dir /home/postgres/postgresql-build
Main project options:
Core options Current Value Possible Values Description
------------ ------------- --------------- -----------
auto_features auto [enabled, disabled, auto] Override value of all 'auto' features
backend ninja [ninja, vs, vs2010, vs2015, vs2017, vs2019, xcode] Backend to use
buildtype release [plain, debug, debugoptimized, release, minsize, custom] Build type to use
debug false [true, false] Debug
default_library shared [shared, static, both] Default library type
force_fallback_for [] Force fallback for those subprojects
install_umask 0022 [preserve, 0000-0777] Default umask to apply on permissions of installed files
layout mirror [mirror, flat] Build directory layout
optimization 3 [0, g, 1, 2, 3, s] Optimization level
strip false [true, false] Strip targets on install
unity off [on, off, subprojects] Unity build
unity_size 4 >=2 Unity block size
warning_level 1 [0, 1, 2, 3] Compiler warning level to use
werror false [true, false] Treat warnings as errors
wrap_mode default [default, nofallback, nodownload, forcefallback] Wrap mode
cmake_prefix_path [] List of additional prefixes for cmake to search
pkg_config_path [] List of additional paths for pkg-config to search
Backend options Current Value Possible Values Description
--------------- ------------- --------------- -----------
backend_max_links 0 >=0 Maximum number of linker processes to run or 0 for no limit
Base options Current Value Possible Values Description
------------ ------------- --------------- -----------
b_asneeded true [true, false] Use -Wl,--as-needed when linking
b_colorout always [auto, always, never] Use colored output
b_coverage false [true, false] Enable coverage tracking.
b_lto false [true, false] Use link time optimization
b_lundef true [true, false] Use -Wl,--no-undefined when linking
b_ndebug false [true, false, if-release] Disable asserts
b_pch false [true, false] Use precompiled headers
b_pgo off [off, generate, use] Use profile guided optimization
b_pie false [true, false] Build executables as position independent
b_sanitize none [none, address, thread, undefined, memory, address,undefined] Code sanitizer to use
b_staticpic true [true, false] Build static libraries as position independent
Compiler options Current Value Possible Values Description
---------------- ------------- --------------- -----------
c_args [] Extra arguments passed to the c compiler
c_link_args [] Extra arguments passed to the c linker
c_std none [none, c89, c99, c11, c17, c18, c2x, gnu89, gnu99, gnu11, C language standard to use
gnu17, gnu18, gnu2x]
Directories Current Value Possible Values Description
----------- ------------- --------------- -----------
bindir bin Executable directory
datadir share Data file directory
includedir include Header file directory
infodir share/info Info page directory
libdir lib64 Library directory
libexecdir libexec Library executable directory
localedir share/locale Locale data directory
localstatedir var Localstate data directory
mandir share/man Manual page directory
prefix /usr/local/pgsql Installation prefix
sbindir sbin System executable directory
sharedstatedir com Architecture-independent data directory
sysconfdir etc Sysconf data directory
Testing options Current Value Possible Values Description
--------------- ------------- --------------- -----------
errorlogs true [true, false] Whether to print the logs from failing tests
stdsplit true [true, false] Split stdout and stderr in test logs
Project options Current Value Possible Values Description
--------------- ------------- --------------- -----------
BISON [bison, win_bison] path to bison binary
DTRACE dtrace path to dtrace binary
FLEX [flex, win_flex] path to flex binary
GZIP gzip path to gzip binary
LZ4 lz4 path to lz4 binary
PERL perl path to perl binary
PG_TEST_EXTRA Enable selected extra tests
PROVE prove path to prove binary
PYTHON [python3, python] path to python binary
SED gsed path to sed binary
TAR tar path to tar binary
XMLLINT xmllint path to xmllint binary
XSLTPROC xsltproc path to xsltproc binary
ZIC zic path to zic binary, when cross-compiling
ZSTD zstd path to zstd binary
atomics true [true, false] whether to use atomic operations
blocksize 8 [1, 2, 4, 8, 16, 32] set relation block size in kB
bonjour auto [enabled, disabled, auto] build with Bonjour support
bsd_auth auto [enabled, disabled, auto] build with BSD Authentication support
cassert false [true, false] enable assertion checks (for debugging)
darwin_sysroot select a non-default sysroot path
dtrace disabled [enabled, disabled, auto] DTrace support
extra_include_dirs [] non-default directories to be searched for headers
extra_lib_dirs [] non-default directories to be searched for libs
extra_version append STRING to the PostgreSQL version number
gssapi auto [enabled, disabled, auto] GSSAPI support
icu auto [enabled, disabled, auto] ICU support
krb_srvnam postgres Default Kerberos service principal for GSSAPI
ldap auto [enabled, disabled, auto] LDAP support
libedit_preferred false [true, false] Prefer BSD Libedit over GNU Readline
libxml auto [enabled, disabled, auto] XML support
libxslt auto [enabled, disabled, auto] XSLT support in contrib/xml2
llvm disabled [enabled, disabled, auto] whether to use llvm
lz4 auto [enabled, disabled, auto] LZ4 support
nls auto [enabled, disabled, auto] native language support
pam auto [enabled, disabled, auto] build with PAM support
pgport 5432 >=1, <=65535 Default port number for server and clients
plperl auto [enabled, disabled, auto] build Perl modules (PL/Perl)
plpython auto [enabled, disabled, auto] build Python modules (PL/Python)
pltcl auto [enabled, disabled, auto] build with TCL support
readline auto [enabled, disabled, auto] use GNU Readline or BSD Libedit for editing
segsize 1 Segment size, in gigabytes
selinux disabled [enabled, disabled, auto] build with SELinux support
spinlocks true [true, false] whether to use spinlocks
ssl none [none, openssl] use LIB for SSL/TLS support (openssl)
system_tzdata use system time zone data in specified directory
systemd auto [enabled, disabled, auto] build with systemd support
tap_tests auto [enabled, disabled, auto] Whether to enable tap tests
tcl_version tcl specify TCL version
uuid none [none, bsd, e2fs, ossp] build contrib/uuid-ossp using LIB
wal_blocksize 8 [1, 2, 4, 8, 16, 32, 64] WAL block size, in kilobytes
zlib auto [enabled, disabled, auto] whether to use zlib
zstd auto [enabled, disabled, auto] whether to use zstd
This is a really nice, human readable, overview of what options are available. To get something comparable to what the “./configure” is doing above we need this:
[email protected]:/home/postgres/postgresql-build/ [pg16] meson configure -Dprefix=${PGHOME} \
-Dbindir=${PGHOME}/bin \
-Ddatadir=${PGHOME}/share \
-Dincludedir=${PGHOME}/include \
-Dlibdir=${PGHOME}/lib \
-Dsysconfdir=${PGHOME}/etc \
-Dpgport=5432 \
-Dplperl=enabled \
-Dplpython=enabled \
-Dssl=openssl \
-Dpam=enabled \
-Dldap=enabled \
-Dlibxml=enabled \
-Dlibxslt=enabled \
-Dsegsize=${SEGSIZE} \
-Dblocksize=${BLOCKSIZE} \
-Dllvm=enabled \
-Duuid=ossp \
-Dzstd=enabled \
-Dlz4=enabled \
-Dgssapi=enabled \
-Dsystemd=enabled \
-Dicu=enabled \
-Dsystem_tzdata=/usr/share/zoneinfo
That’s it, ready to compile (parallelism is detected by default):
[email protected]:/home/postgres/postgresql-build/ [pg16] ninja
[0/1] Regenerating build files.
The Meson build system
Version: 0.56.2
Source dir: /home/postgres/postgresql
Build dir: /home/postgres/postgresql-build
Build type: native build
Project name: postgresql
Project version: 16devel
...
Configuring version.sgml using configuration
Message: checking for file conflicts between source and build directory
Build targets in project: 390
Option prefix is: /var/tmp/pgsql [default: /usr/local/pgsql]
Found ninja-1.10.1 at /usr/bin/ninja
[236/1876] Compiling C object src/interfaces/libpq/libpq.a.p/fe-print.c.o
[1876/1876] Linking target src/interfaces/ecpg/test/thread/alloc
Ready to install:
[email protected]:/home/postgres/postgresql-build/ [pg16] ninja install
[0/1] Installing files.
Installing subdir /home/postgres/postgresql/src/include/access to /var/tmp/pgsql/include/postgresql/server/access
Installing /home/postgres/postgresql/src/include/access/rmgrlist.h to /var/tmp/pgsql/include/postgresql/server/access
Installing /home/postgres/postgresql/src/include/access/attmap.h to /var/tmp/pgsql/include/postgresql/server/access
Installing /home/postgres/postgresql/src/include/access/xlogrecovery.h to /var/tmp/pgsql/include/postgresql/server/access
Installing /home/postgres/postgresql/src/include/access/xlogarchive.h to /var/tmp/pgsql/include/postgresql/server/access
...
Installing /home/postgres/postgresql/src/test/perl/PostgreSQL/Test/Utils.pm to /var/tmp/pgsql/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test
Installing /home/postgres/postgresql/src/test/perl/PostgreSQL/Test/SimpleTee.pm to /var/tmp/pgsql/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test
Installing /home/postgres/postgresql/src/test/perl/PostgreSQL/Test/RecursiveCopy.pm to /var/tmp/pgsql/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test
Installing /home/postgres/postgresql/src/test/perl/PostgreSQL/Test/Cluster.pm to /var/tmp/pgsql/lib/postgresql/pgxs/src/test/perl/PostgreSQL/Test
20:07:21 p[email protected]:/home/postgres/postgresql-build/ [pg16]
Quite easy and all is there:
[email protected]:/home/postgres/postgresql-build/ [pg16] /var/tmp/pgsql/bin/initdb -D /var/tmp/dummy
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
creating directory /var/tmp/dummy ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Europe/Zurich
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
Success. You can now start the database server using:
/var/tmp/pgsql/bin/pg_ctl -D /var/tmp/dummy -l logfile start
[email protected]:/home/postgres/postgresql-build/ [pg16] export PGPORT=8888
[email protected]:/home/postgres/postgresql-build/ [pg16] /var/tmp/pgsql/bin/pg_ctl -D /var/tmp/dummy start
waiting for server to start....2022-10-18 20:10:29.674 CEST [8469] LOG: starting PostgreSQL 16devel on x86_64, compiled by gcc-10.2.1
2022-10-18 20:10:29.675 CEST [8469] LOG: listening on IPv6 address "::1", port 8888
2022-10-18 20:10:29.675 CEST [8469] LOG: listening on IPv4 address "127.0.0.1", port 8888
2022-10-18 20:10:29.689 CEST [8469] LOG: listening on Unix socket "/tmp/.s.PGSQL.8888"
2022-10-18 20:10:29.718 CEST [8472] LOG: database system was shut down at 2022-10-18 20:09:40 CEST
2022-10-18 20:10:29.735 CEST [8469] LOG: database system is ready to accept connections
done
server started
[email protected]:/home/postgres/postgresql-build/ [pg16] /var/tmp/pgsql/bin/psql
psql (16devel)
Type "help" for help.
postgres=# select version();
version
------------------------------------------------------
PostgreSQL 16devel on x86_64, compiled by gcc-10.2.1
(1 row)
Not much more work than the traditional way, but I like the output of the various steps. It is much easier to read. I did not do any tests, if this is really faster and did not look at other advantages of this approach. Maybe this will a topic for a follow up post. This should give you enough information to get started.
Last, but not least, there is a nice comparison of the “old” against the “new” commands in the PostgreSQL wiki. The question is: Does “old” mean, the traditional way of building PostgreSQL will go away? Have a look at the bottom of the Wiki page to get an idea about what might be happening.