This is the next post in this little series about PostgreSQL on FreeBSD. You can find the previous one here:

The downside with installing from packages on FreeBSD is, that you can only run one version of PostgreSQL. If you want to run more than one, you need to install from source code, and this is the topic of this post.

AS the first step lets remove the PostgreSQL installation we did in the last post:

root@freebsd:~ $ pkg remove postgresql13-server postgresql13-client
Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 2 packages (of 0 packages in the universe):

Installed packages to be REMOVED:
        postgresql13-client: 13.1
        postgresql13-server: 13.1_1

Number of packages to be removed: 2

The operation will free 53 MiB.

Proceed with deinstalling packages? [y/N]: y
[1/2] Deinstalling postgresql13-server-13.1_1...
[1/2] Deleting files for postgresql13-server-13.1_1: 100%
==> You should manually remove the "postgres" user. 
==> You should manually remove the "postgres" group 
[2/2] Deinstalling postgresql13-client-13.1...
[2/2] Deleting files for postgresql13-client-13.1: 100%

As this will not remove $PGDATA lets get rid of that as well:

root@freebsd:~ $ rm -rf /var/db/postgres/data13/

We should also remove the auto start configuration:

root@freebsd:~ $ sed -i".bak" '$d' /etc/rc.conf
root@freebsd:~ $ cat /etc/rc.conf
hostname="freebsd.it.dbi-services.com"
keymap="ch.kbd"
ifconfig_em0="DHCP"
ifconfig_em1="inet 192.168.22.17 netmask 255.255.255.0"
sshd_enable="YES"
ntpd_enable="YES"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"
zfs_enable="YES"

When we installed PostgreSQL from packages some additional packages have been installed as well, lets remove them, too:

root@freebsd:~ $ pkg remove libffi libedit libxml2 python37 perl5 lua52 llvm11 icu-68
No packages matched for pattern 'icu-68'

Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 7 packages (of 0 packages in the universe):

Installed packages to be REMOVED:
        libedit: 3.1.20191231,1
        libffi: 3.3_1
        libxml2: 2.9.10_2
        llvm11: 11.0.1
        lua52: 5.2.4
        perl5: 5.32.1_1
        python37: 3.7.9_1

Number of packages to be removed: 7

The operation will free 884 MiB.

Proceed with deinstalling packages? [y/N]: y
[1/7] Deinstalling llvm11-11.0.1...
[1/7] Deleting files for llvm11-11.0.1: 100%
[2/7] Deinstalling python37-3.7.9_1...
[2/7] Deleting files for python37-3.7.9_1: 100%
[3/7] Deinstalling lua52-5.2.4...
[3/7] Deleting files for lua52-5.2.4: 100%
[4/7] Deinstalling libffi-3.3_1...
[4/7] Deleting files for libffi-3.3_1: 100%
[5/7] Deinstalling libedit-3.1.20191231,1...
[5/7] Deleting files for libedit-3.1.20191231,1: 100%
[6/7] Deinstalling libxml2-2.9.10_2...
[6/7] Deleting files for libxml2-2.9.10_2: 100%
[7/7] Deinstalling perl5-5.32.1_1...
[7/7] Deleting files for perl5-5.32.1_1: 100%

Now we should have the same state of the system as before we installed PostgreSQL from packages. We’ll not delete the postgres user and group, as we can just re-use them for installing from source code.

To download the source code we need something like wget, and to make life a bit easier we’ll also install sudo:

root@freebsd:~ $ pkg install wget sudo
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 4 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        libidn2: 2.3.0_1
        libunistring: 0.9.10_1
        sudo: 1.9.5p2
        wget: 1.20.3_1

Number of packages to be installed: 4

The process will require 11 MiB more space.
2 MiB to be downloaded.

Proceed with this action? [y/N]: y
[1/4] Fetching wget-1.20.3_1.txz: 100%  651 KiB 666.2kB/s    00:01    
[2/4] Fetching sudo-1.9.5p2.txz: 100%  943 KiB 966.1kB/s    00:01    
[3/4] Fetching libidn2-2.3.0_1.txz: 100%  111 KiB 113.3kB/s    00:01    
[4/4] Fetching libunistring-0.9.10_1.txz: 100%  527 KiB 539.8kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/4] Installing libunistring-0.9.10_1...
[1/4] Extracting libunistring-0.9.10_1: 100%
[2/4] Installing libidn2-2.3.0_1...
[2/4] Extracting libidn2-2.3.0_1: 100%
[3/4] Installing wget-1.20.3_1...
[3/4] Extracting wget-1.20.3_1: 100%
[4/4] Installing sudo-1.9.5p2...
[4/4] Extracting sudo-1.9.5p2: 100%

The sudo configuration in FreeBSD is not in /etc but in /usr/local/etc, and as we trust the postgres user we allow everything without a password:

root@freebsd:~ $ cat /usr/local/etc/sudoers | grep postgres
postgres ALL=(ALL) NOPASSWD: ALL

Lets download the source code:


root@freebsd:~ # su - postgres
$ pwd
/var/db/postgres
$ wget https://ftp.postgresql.org/pub/source/v13.2/postgresql-13.2.tar.bz2
$ ls -l
total 20585
-rw-r--r--  1 postgres  postgres  21057276 Feb  8 23:07 postgresql-13.2.tar.bz2
$ tar xvf postgresql-13.2.tar.bz2
$ ls -l
total 20593
drwxr-xr-x  6 postgres  postgres        19 Feb  8 23:07 postgresql-13.2
-rw-r--r--  1 postgres  postgres  21057276 Feb  8 23:07 postgresql-13.2.tar.bz2
$ cd postgresql-13.2

Before can run “configure” we need to install all the dependencies:

$ sudo pkg install perl5 perl5-devel python3 libressl-devel libxml2 libxslt openldap-client llvm11
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 14 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        libedit: 3.1.20191231,1
        libffi: 3.3_1
        libgcrypt: 1.8.7
        libgpg-error: 1.41
        libressl-devel: 3.3.1
        libxml2: 2.9.10_2
        libxslt: 1.1.34_1
        llvm11: 11.0.1
        lua52: 5.2.4
        openldap-client: 2.4.57
        perl5: 5.32.1_1
        perl5-devel: 5.33.4.81
        python3: 3_3
        python37: 3.7.9_1

Number of packages to be installed: 14

The process will require 975 MiB more space.
20 MiB to be downloaded.

Proceed with this action? [y/N]: y
[1/7] Fetching perl5-devel-5.33.4.81.txz: 100%   14 MiB   3.8MB/s    00:04    
[2/7] Fetching python3-3_3.txz: 100%    1 KiB   1.1kB/s    00:01    
[3/7] Fetching libressl-devel-3.3.1.txz: 100%    3 MiB   3.2MB/s    00:01    
[4/7] Fetching libxslt-1.1.34_1.txz: 100%  233 KiB 238.4kB/s    00:01    
[5/7] Fetching openldap-client-2.4.57.txz: 100%    1 MiB   1.1MB/s    00:01    
[6/7] Fetching libgcrypt-1.8.7.txz: 100%  740 KiB 757.9kB/s    00:01    
[7/7] Fetching libgpg-error-1.41.txz: 100%  292 KiB 299.5kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/14] Installing libffi-3.3_1...
[1/14] Extracting libffi-3.3_1: 100%
[2/14] Installing libgpg-error-1.41...
[2/14] Extracting libgpg-error-1.41: 100%
[3/14] Installing libedit-3.1.20191231,1...
[3/14] Extracting libedit-3.1.20191231,1: 100%
[4/14] Installing perl5-5.32.1_1...
[4/14] Extracting perl5-5.32.1_1: 100%
[5/14] Installing libxml2-2.9.10_2...
[5/14] Extracting libxml2-2.9.10_2: 100%
[6/14] Installing python37-3.7.9_1...
[6/14] Extracting python37-3.7.9_1: 100%
[7/14] Installing libgcrypt-1.8.7...
[7/14] Extracting libgcrypt-1.8.7: 100%
[8/14] Installing lua52-5.2.4...
[8/14] Extracting lua52-5.2.4: 100%
[9/14] Installing perl5-devel-5.33.4.81...
[9/14] Extracting perl5-devel-5.33.4.81: 100%
[10/14] Installing python3-3_3...
[10/14] Extracting python3-3_3: 100%
[11/14] Installing libressl-devel-3.3.1...
[11/14] Extracting libressl-devel-3.3.1: 100%
[12/14] Installing libxslt-1.1.34_1...
[12/14] Extracting libxslt-1.1.34_1: 100%
[13/14] Installing openldap-client-2.4.57...
[13/14] Extracting openldap-client-2.4.57: 100%
[14/14] Installing llvm11-11.0.1...
[14/14] Extracting llvm11-11.0.1: 100%
=====
Message from python37-3.7.9_1:

--
Note that some standard Python modules are provided as separate ports
as they require additional dependencies. They are available as:

py37-gdbm       databases/py-gdbm@py37
py37-sqlite3    databases/py-sqlite3@py37
py37-tkinter    x11-toolkits/py-tkinter@py37
=====
Message from openldap-client-2.4.57:

--
The OpenLDAP client package has been successfully installed.

Edit
  /usr/local/etc/openldap/ldap.conf
to change the system-wide client defaults.

Try `man ldap.conf' and visit the OpenLDAP FAQ-O-Matic at
  http://www.OpenLDAP.org/faq/index.cgi?file=3
for more information.

Here is the configure command (this might look differently for you, depending on what you want to have enabled):

$ sudo mkdir -p /u01/app
$ sudo chown postgres:postgres /u01/app
$ bash
[postgres@freebsd ~/postgresql-13.2]$ PGHOME=/u01/app/postgres/product/13/db_2/
[postgres@freebsd ~/postgresql-13.2]$ SEGSIZE=2
[postgres@freebsd ~/postgresql-13.2]$ BLOCKSIZE=8
[postgres@freebsd ~/postgresql-13.2]$ ./configure --prefix=${PGHOME} --exec-prefix=${PGHOME} --bindir=${PGHOME}/bin --libdir=${PGHOME}/lib --with-libraries=/usr/local/lib  --with-includes=/usr/local/include --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/local/llvm11/bin/llvm-config' 
...
config.status: creating GNUmakefile
config.status: creating src/Makefile.global
config.status: creating src/include/pg_config.h
config.status: creating src/include/pg_config_ext.h
config.status: creating src/interfaces/ecpg/include/ecpg_config.h
config.status: linking src/backend/port/tas/dummy.s to src/backend/port/tas.s
config.status: linking src/backend/port/posix_sema.c to src/backend/port/pg_sema.c
config.status: linking src/backend/port/sysv_shmem.c to src/backend/port/pg_shmem.c
config.status: linking src/include/port/freebsd.h to src/include/pg_config_os.h

Compile and install:

[postgres@freebsd ~/postgresql-13.2]$ make all
You must use GNU make to build PostgreSQL.
*** Error code 1

Stop.
make: stopped in /var/db/postgres/postgresql-13.2

Ok, so we missed to install make:

[postgres@freebsd ~/postgresql-13.2]$ sudo pkg install gmake
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        gmake: 4.3_2

Number of packages to be installed: 1

The process will require 2 MiB more space.
416 KiB to be downloaded.

Proceed with this action? [y/N]: y
[1/1] Fetching gmake-4.3_2.txz: 100%  416 KiB 425.6kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/1] Installing gmake-4.3_2...
[1/1] Extracting gmake-4.3_2: 100%
[postgres@freebsd ~/postgresql-13.2]$ make world
Using GNU make found at /usr/local/bin/gmake
...
/usr/local/bin/gmake -C config all
gmake[1]: Entering directory '/var/db/postgres/postgresql-13.2/config'
gmake[1]: Nothing to be done for 'all'.
gmake[1]: Leaving directory '/var/db/postgres/postgresql-13.2/config'
gmake[2]: Leaving directory '/var/db/postgres/postgresql-13.2/contrib/ltree_plpython'
gmake[1]: Leaving directory '/var/db/postgres/postgresql-13.2/contrib'
PostgreSQL, contrib, and documentation successfully made. Ready to install.

That’s it. Finally, install:

[postgres@freebsd ~/postgresql-13.2]$ make install-world
...
cd '/u01/app/postgres/product/13/db_2//lib/bitcode' && /usr/local/llvm11/bin/llvm-lto -thinlto -thinlto-action=thinlink -o ltree_plpython3.index.bc ltree_plpython3/ltree_plpython.bc
gmake[2]: Leaving directory '/var/db/postgres/postgresql-13.2/contrib/ltree_plpython'
gmake[1]: Leaving directory '/var/db/postgres/postgresql-13.2/contrib'
PostgreSQL, contrib, and documentation installation complete.

If you script that, it is not much more work than installing from packages, and you have the full flexibility. The downside is, that you need to come with your on start/stop scripts and that you need to compile any third party extension for your own.