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):

postgres@debian11pg:/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:

postgres@debian11pg:/home/postgres/ [pg16] mkdir postgresql-build
postgres@debian11pg:/home/postgres/ [pg16] cd postgresql-build/

The source code of PostgreSQL in this case is on the same level as the build directory:

postgres@debian11pg:/home/postgres/postgresql-build/ [pg16] pwd
/home/postgres/postgresql-build
11:58:49 postgres@debian11pg:/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:

postgres@debian11pg:/home/postgres/postgresql-build/ [pg16] PGHOME=/var/tmp/pgsql
postgres@debian11pg:/home/postgres/postgresql-build/ [pg16] SEGSIZE=2
postgres@debian11pg:/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):

postgres@debian11pg:/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:

postgres@debian11pg:/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:

postgres@debian11pg:/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):

postgres@debian11pg:/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:

postgres@debian11pg:/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 postgres@debian11pg:/home/postgres/postgresql-build/ [pg16] 

Quite easy and all is there:

postgres@debian11pg:/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

postgres@debian11pg:/home/postgres/postgresql-build/ [pg16] export PGPORT=8888
postgres@debian11pg:/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
postgres@debian11pg:/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.