When working with PostgreSQL source code, we actually have this code part in each extension’s make file. In postgres source code, the actual extension source code is placed inside the contrib directory, and in each extension’s makefile, you can see the code part related to the pg_config. pg_config is a utility program of PostgreSQL that displays information about the PostgreSQL installation on your system, such as installation directories, compiler options, version, and build configuration.
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/amcheck
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
This part of the code is about building and installing the postgres extension. The postgres extension is installed in a certain way. When you run make and tell it where to find pg_config, the build system uses this pg_config.
Example:
make USE_PGXS=1 PG_CONFIG=/usr/lib/postgresql/18/bin/pg_config
sudo make USE_PGXS=1 PG_CONFIG=/usr/lib/postgresql/18/bin/pg_config install
The pg_config helps the build system figure out where to put the extension and how to build it. So the postgres extension is installed for the postgres that is associated with this pg_config.
You can check the path of the pg_config by using the command below.
which pg_config
Result:
/usr/bin/pg_config
We can also read the contents of this pg_config by just directly calling this utility.
/usr/bin/pg_config
Result:
BINDIR = /usr/lib/postgresql/18/bin
DOCDIR = /usr/share/doc/postgresql-doc-18
HTMLDIR = /usr/share/doc/postgresql-doc-18
INCLUDEDIR = /usr/include/postgresql
PKGINCLUDEDIR = /usr/include/postgresql
INCLUDEDIR-SERVER = /usr/include/postgresql/18/server
LIBDIR = /usr/lib/x86_64-linux-gnu
PKGLIBDIR = /usr/lib/postgresql/18/lib
LOCALEDIR = /usr/share/locale
MANDIR = /usr/share/postgresql/18/man
SHAREDIR = /usr/share/postgresql/18
SYSCONFDIR = /etc/postgresql-common
PGXS = /usr/lib/postgresql/18/lib/pgxs/src/makefiles/pgxs.mk
CONFIGURE = '--build=x86_64-linux-gnu' '--prefix=/usr' '--includedir=${prefix}/include' '--mandir=${prefix}/share/man' '--infodir=${prefix}/share/info' '--sysconfdir=/etc' '--localstatedir=/var' '--disable-option-checking' '--disable-silent-rules' '--libdir=${prefix}/lib/x86_64-linux-gnu' '--runstatedir=/run' '--disable-maintainer-mode' '--disable-dependency-tracking' '--with-tcl' '--with-perl' '--with-python' '--with-pam' '--with-openssl' '--with-libxml' '--with-libxslt' '--mandir=/usr/share/postgresql/18/man' '--docdir=/usr/share/doc/postgresql-doc-18' '--sysconfdir=/etc/postgresql-common' '--datarootdir=/usr/share/' '--datadir=/usr/share/postgresql/18' '--bindir=/usr/lib/postgresql/18/bin' '--libdir=/usr/lib/x86_64-linux-gnu/' '--libexecdir=/usr/lib/postgresql/' '--includedir=/usr/include/postgresql/' '--with-extra-version= (Ubuntu 18.4-1.pgdg22.04+1)' '--enable-nls' '--enable-thread-safety' '--enable-debug' '--disable-rpath' '--with-uuid=e2fs' '--with-gnu-ld' '--with-gssapi' '--with-ldap' '--with-pgport=5432' '--with-system-tzdata=/usr/share/zoneinfo' 'AWK=mawk' 'MKDIR_P=/bin/mkdir -p' 'PROVE=/usr/bin/prove' 'PYTHON=/usr/bin/python3' 'TAR=/bin/tar' 'XSLTPROC=xsltproc --nonet' 'CFLAGS=-g -O2 -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer' 'LDFLAGS=-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now' '--enable-tap-tests' '--with-icu' '--with-llvm' 'LLVM_CONFIG=/usr/bin/llvm-config-15' 'CLANG=/usr/bin/clang-15' '--with-lz4' '--with-zstd' '--with-libcurl' '--with-libnuma' 'LIBNUMA_CFLAGS= ' 'LIBNUMA_LIBS=-lnuma' '--with-liburing' '--with-systemd' '--with-selinux' '--enable-dtrace' 'build_alias=x86_64-linux-gnu' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2' 'CXXFLAGS=-g -O2 -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security'
CC = gcc
CPPFLAGS = -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2
CFLAGS = -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 -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer
CFLAGS_SL = -fPIC
LDFLAGS = -Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now -Wl,--as-needed
LDFLAGS_EX =
LDFLAGS_SL =
LIBS = -lpgcommon -lpgport -lselinux -lzstd -llz4 -lxslt -lxml2 -lpam -lssl -lcrypto -lgssapi_krb5 -lz -lreadline -lm -lnuma
VERSION = PostgreSQL 18.4 (Ubuntu 18.4-1.pgdg22.04+1)
BIN Directory
BINDIR = /usr/lib/postgresql/18/bin
Check the contents inside the bin directory.
ls /usr/lib/postgresql/18/bin
Result:
check_unique_constraint.py dropdb oid2name pgbench pg_config pg_ctl pg_isready pg_restore pg_upgrade postgres vacuumlo
clusterdb dropuser pg_amcheck pg_bsd_indent pg_controldata pg_dump pg_receivewal pg_rewind pg_verifybackup psql vacuum_maintenance.py
createdb dump_partition.py pg_archivecleanup pg_checksums pgcopydb pg_dumpall pg_recvlogical pg_test_fsync pg_waldump reindexdb
createuser initdb pg_basebackup pg_combinebackup pg_createsubscriber pgindent pg_resetwal pg_test_timing pg_walsummary vacuumdb
The BIN directory contains the executable programs that make up the postgres command-line toolkit. These utilities support server administration, database creation, backup and recovery, replication, performance testing, maintenance, and troubleshooting. Most day-to-day postgres related administration tasks are performed using the programs located in this directory.
Documentation Directory
DOCDIR = /usr/share/doc/postgresql-doc-18
HTMLDIR = /usr/share/doc/postgresql-doc-18
Check the contents of the documentation directory.
ls /usr/share/doc/postgresql-doc-18/extension/
Result:
fix_missing_procedures.md migrate_to_declarative.md migrate_to_partman.md pg_partman_5.0.1_upgrade.md pg_partman_howto.md pg_partman.md pgtt.md README.md
The HTMLDIR path tells us where to find the HTML documentation of postgres. This is really useful because it gives us a version of the manuals and guides that we can look at in a web browser. We can use the postgres documentation when we do not have internet.
Include Directory
INCLUDEDIR = /usr/include/postgresql
PKGINCLUDEDIR = /usr/include/postgresql
Check the contents of the include directory.
ls /usr/include/postgresql
Result:
18 internal libpq libpq-events.h libpq-fe.h pg_config.h pg_config_manual.h pg_config_os.h postgres_ext.h
The INCLUDEDIR directory provides the public header files required for compiling applications that interact with postgres. These headers expose the interfaces needed by client programs while also providing configuration information generated during the build process of postgres.
Server Include Directory
INCLUDEDIR-SERVER = /usr/include/postgresql/18/server
Check the contents of the server include directory.
ls /usr/include/postgresql/18/server
Result:
access common foreign mb pg_config.h pgtime.h plpy_elog.h plpy_resultobject.h plpy_util.h postgres.h snowball varatt.h
archive datatype funcapi.h miscadmin.h pg_config_manual.h pg_trace.h plpy_exec.h plpy_spi.h port postmaster statistics windowapi.h
bootstrap executor getopt_long.h nodes pg_config_os.h plperl.h plpy_main.h plpy_subxactobject.h portability ppport.h storage
catalog extension jit optimizer pg_getopt.h plperl_system.h plpy_planobject.h plpython.h port.h regex tcop
c.h fe_utils lib parser pgstat.h plpgsql.h plpy_plpymodule.h plpython_system.h postgres_ext.h replication tsearch
commands fmgr.h libpq partitioning pgtar.h plpy_cursorobject.h plpy_procedure.h plpy_typeio.h postgres_fe.h rewrite utils
The INCLUDEDIR-SERVER folder has the postgres server header files. These headers show the APIs, data structures, macros, and function declarations that the postgres server uses itself.
Unlike INCLUDEDIR, which's, for client application development, INCLUDEDIR-SERVER is mainly used when building postgres server-side parts like extensions, custom data types, background workers, hooks, index access methods, and changes to the PostgreSQL source code.
Library Directory
LIBDIR = /usr/lib/x86_64-linux-gnu
Check the contents of the library directory.
ls /usr/lib/x86_64-linux-gnu
Result:
aisleriot libedataserverui-1.2.so.3 liblcms2.so.2.0.12 libsemanage.so.2
alsa-lib libedataserverui-1.2.so.3.0.0 libldap-2.5.so.0 libsensors.so.5
ao libedit.so.2 libldap-2.5.so.0.1.15 libsensors.so.5.0.0
audit libedit.so.2.0.68 libldap.a libsepol.a
avahi libefiboot.so.1 libldap_r.a libsepol.so
The LIBDIR directory contains the shared libraries (.so) and static libraries (.a) installed on the system. These libraries are used by postgres and many other applications during compilation and execution.
When postgres or a client application is linked, the linker searches this directory for the required libraries.
Package Library Directory
PKGLIBDIR = /usr/lib/postgresql/18/lib
Check the contents of the package library directory.
ls /usr/lib/postgresql/18/lib
Result:
amcheck.so cube.so euc_tw_and_big5.so libpgcommon.a pageinspect.so pg_partman_bgw.so pg_walinspect.so tcn.so utf8_and_euc_tw.so
auth_delay.so cyrillic_and_mic.so file_fdw.so libpgcommon_shlib.a passwordcheck.so pg_prewarm.so pgxml.so test_decoding.so utf8_and_gb18030.so
auto_explain.so dblink.so fuzzystrmatch.so libpgfeutils.a pg_background.so pgq_lowlevel.so pgxs tsm_system_rows.so utf8_and_gbk.so
autoinc.so dict_int.so hstore.so libpgport.a pg_bigm.so pgq_triggers.so plpgsql.so tsm_system_time.so utf8_and_iso8859_1.so
basebackup_to_shell.so dict_snowball.so http.so libpgport_shlib.a pg_buffercache.so pgrowlocks.so postgres_fdw.so unaccent.so utf8_and_iso8859.so
basic_archive.so dict_xsyn.so hypopg.so libpqwalreceiver.so pgcrypto.so pg_stat_statements.so refint.so utf8_and_big5.so utf8_and_johab.so
bitcode earthdistance.so insert_username.so llvmjit.so pg_freespacemap.so pgstattuple.so regress.so utf8_and_cyrillic.so utf8_and_sjis2004.so
bloom.so euc2004_sjis2004.so _int.so llvmjit_types.bc pg_logicalinspect.so pg_surgery.so seg.so utf8_and_euc2004.so utf8_and_sjis.so
btree_gin.so euc_cn_and_mic.so isn.so lo.so pg_net.so pg_trgm.so sepgsql.so utf8_and_euc_cn.so utf8_and_uhc.so
btree_gist.so euc_jp_and_sjis.so latin2_and_win1250.so ltree.so pgoutput.so pgtt.so sslinfo.so utf8_and_euc_jp.so utf8_and_win.so
citext.so euc_kr_and_mic.so latin_and_mic.so moddatetime.so pg_overexplain.so pg_visibility.so tablefunc.so utf8_and_euc_kr.so uuid-ossp.so
Locale Directory
LOCALEDIR = /usr/share/locale
Check the contents of the locale directory.
ls /usr/share/locale
Result:
aa ar bar bo cgg cy en_AU et fr_CA gu hy jbo kn lb mhr ms nl pam qu shn sr@Latn th tzm wal zu
ab arn be br ch da en@boldquot eu frp gv ia jv ko lg mi mt nn pap ro si st ti ug wo
ace ary be@latin brx chr de en_CA fa fur ha id ka kok ln mjw my nso pi ru sk sv tig uk xh
ach as bem bs ckb de_DE en_GB fa_AF fy haw io kab ks_IN lo mk na nv pl rw sl sw tk ur yo
af as_IN bg byn co dv en@quot ff ga he is ki ku locale.alias ml nah oc pms sa so szl tl uz zh_CN
ak ast bi ca crh dz en@shaw fi gd hi it kk ku_IQ lt mn nb om ps sc son ta tr ve zh_Hans
am ay bn ca@valencia cs ee eo fil gez hr iu kl kv lv mnw nb_NO or pt sco sq ta_LK trv vec zh_Hant
am_ET az bn_BD ce csb el es fo gl ht ja km kw mai mo nds os pt_BR sd sr te tt vi zh_HK
an ba bn_IN ceb cv en es_MX fr gn hu jam kmr ky mg mr ne pa pt_PT se sr@latin tg tt@iqtelif wa zh_TW
The folder called LOCALEDIR holds the language and location files that are used by the postgres and other programs on the system. These files have translations, which let programs show information in languages depending on how the user has set up their location settings.
Manual Directory
MANDIR = /usr/share/postgresql/18/man
Check the contents of the manual directory.
ls /usr/share/postgresql/18/man
Result:
man1 man7
The MANDIR contains two manual sections:
Man1 - stores documentation for the postgres command-line utilities such as psql, postgres, pg_dump, and pg_restore.
Man7 - Stores reference documentation for SQL statements and PostgreSQL features, including commands such as SELECT, CREATE TABLE, VACUUM, and EXPLAIN.
ls /usr/share/postgresql/18/man/man1
Result:
clusterdb.1.gz dropuser.1.gz pg_archivecleanup.1.gz pg_combinebackup.1.gz pg_dump.1.gz pg_recvlogical.1.gz pg_test_fsync.1.gz pg_waldump.1.gz reindexdb.1.gz
createdb.1.gz initdb.1.gz pg_basebackup.1.gz pg_controldata.1.gz pg_dumpall.1.gz pg_resetwal.1.gz pg_test_timing.1.gz pg_walsummary.1.gz vacuumdb.1.gz
createuser.1.gz oid2name.1.gz pgbench.1.gz pg_createsubscriber.1.gz pg_isready.1.gz pg_restore.1.gz pg_upgrade.1.gz postgres.1.gz vacuumlo.1.gz
dropdb.1.gz pg_amcheck.1.gz pg_checksums.1.gz pg_ctl.1.gz pg_receivewal.1.gz pg_rewind.1.gz pg_verifybackup.1.gz psql.1.gz
Check the contents of the man7 directory.
ls /usr/share/postgresql/18/man/man7
Result:
ABORT.7.gz ALTER_TEXT_SEARCH_TEMPLATE.7.gz CREATE_PUBLICATION.7.gz DROP_FUNCTION.7.gz IMPORT_FOREIGN_SCHEMA.7.gz
ALTER_AGGREGATE.7.gz ALTER_TRIGGER.7.gz CREATE_ROLE.7.gz DROP_GROUP.7.gz INSERT.7.gz
ALTER_COLLATION.7.gz ALTER_TYPE.7.gz CREATE_RULE.7.gz DROP_INDEX.7.gz LISTEN.7.gz
ALTER_CONVERSION.7.gz ALTER_USER.7.gz CREATE_SCHEMA.7.gz DROP_LANGUAGE.7.gz LOAD.7.gz
ALTER_DATABASE.7.gz ALTER_USER_MAPPING.7.gz CREATE_SEQUENCE.7.gz DROP_MATERIALIZED_VIEW.7.gz LOCK.7.gz
Shared Directory
SHAREDIR = /usr/share/postgresql/18
Check the contents of the shared directory.
ls /usr/share/postgresql/18
Result:
catalog_version errcodes.txt information_schema.sql pg_hba.conf.sample pg_service.conf.sample postgresql.conf.sample snowball_create.sql system_constraints.sql system_views.sql tsearch_data
contrib extension man pg_ident.conf.sample postgres.bki psqlrc.sample sql_features.txt system_functions.sql timezonesets typedefs.list
The SHAREDIR directory has a lot of things that the postgres uses. This includes scripts for SQL, information about extensions files that help set up postgres example configuration files, documentation, time zone data, and resources for searching text.
These files do not depend on the system architecture. Postgres uses them when it is being installed, when databases are being set up, when extensions are being managed, and when the server is running normally.
System Configuration Directory
SYSCONFDIR = /etc/postgresql-common
Check the contents of the system configuration directory.
ls /etc/postgresql-common
Result:
createcluster.conf pg_upgradecluster.d root.crt user_clusters
Postgres uses the SYSCONFDIR directory to keep all the configuration files that the postgres management utilities need. The SYSCONFDIR directory has a lot of files. It has the default settings for creating postgres clusters. The SYSCONFDIR directory also has helper scripts that make it easier to upgrade postgres.
The SYSCONFDIR directory has the SSL certificate configuration and the mappings of users to postgres clusters. The operating systems postgres package takes care of these files in the SYSCONFDIR directory. This helps make it easier to manage the postgres clusters.
PostgreSQL Extension Building Infrastructure
PGXS = /usr/lib/postgresql/18/lib/pgxs/src/makefiles/pgxs.mk
The PostgreSQL extension Building Infrastructure file, also known as PGXS is a file called a Makefile that comes with postgresql. This file makes it easier to build and install extensions for postgres. The PGXS file has all the rules and options that are needed to compile and install postgresql extensions without having to rebuild the postgres system.
When someone uses PGXS to build an extension, they only have to create a Makefile for that extension. The PGXS system automatically gets all the information, such as the compiler flags, directories for included files, library paths, and installation directories, from the postgres system that is already installed on the computer. This makes it a lot easier to build and install postgres extensions using PGXS.
Build Configuration (CONFIGURE)
CONFIGURE = '--build=x86_64-linux-gnu' '--prefix=/usr' '--includedir=${prefix}/include' '--mandir=${prefix}/share/man' '--infodir=${prefix}/share/info' '--sysconfdir=/etc' '--localstatedir=/var' '--disable-option-checking' '--disable-silent-rules' '--libdir=${prefix}/lib/x86_64-linux-gnu' '--runstatedir=/run' '--disable-maintainer-mode' '--disable-dependency-tracking' '--with-tcl' '--with-perl' '--with-python' '--with-pam' '--with-openssl' '--with-libxml' '--with-libxslt' '--mandir=/usr/share/postgresql/18/man' '--docdir=/usr/share/doc/postgresql-doc-18' '--sysconfdir=/etc/postgresql-common' '--datarootdir=/usr/share/' '--datadir=/usr/share/postgresql/18' '--bindir=/usr/lib/postgresql/18/bin' '--libdir=/usr/lib/x86_64-linux-gnu/' '--libexecdir=/usr/lib/postgresql/' '--includedir=/usr/include/postgresql/' '--with-extra-version= (Ubuntu 18.4-1.pgdg22.04+1)' '--enable-nls' '--enable-thread-safety' '--enable-debug' '--disable-rpath' '--with-uuid=e2fs' '--with-gnu-ld' '--with-gssapi' '--with-ldap' '--with-pgport=5432' '--with-system-tzdata=/usr/share/zoneinfo' 'AWK=mawk' 'MKDIR_P=/bin/mkdir -p' 'PROVE=/usr/bin/prove' 'PYTHON=/usr/bin/python3' 'TAR=/bin/tar' 'XSLTPROC=xsltproc --nonet' 'CFLAGS=-g -O2 -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer' 'LDFLAGS=-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now' '--enable-tap-tests' '--with-icu' '--with-llvm' 'LLVM_CONFIG=/usr/bin/llvm-config-15' 'CLANG=/usr/bin/clang-15' '--with-lz4' '--with-zstd' '--with-libcurl' '--with-libnuma' 'LIBNUMA_CFLAGS= ' 'LIBNUMA_LIBS=-lnuma' '--with-liburing' '--with-systemd' '--with-selinux' '--enable-dtrace' 'build_alias=x86_64-linux-gnu' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2' 'CXXFLAGS=-g -O2 -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security'The CONFIGURE field records the exact options that were supplied to the postgres configure script before the source code was compiled. These options determine which features are enabled, where the postgres is installed, which external libraries are linked, and how the server is built.
When postgres is compiled from source, the configure script examines the operating system, checks for required libraries, and generates the appropriate build configuration.
Preprocessor Flags
CPPFLAGS = -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2
The CPPFLAGS field contains the options passed to the C preprocessor before the source code is compiled. These options define macros and specify additional directories where header files should be searched.
C Compiler Flags
CFLAGS = -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 -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer
The CFLAGS variable controls how PostgreSQL source code is compiled. It enables compiler warnings, optimization, debugging support, and security protections while defining rules for generating machine code.
Shared Library Compiler Flags
CFLAGS_SL = -fPIC
The CFLAGS_SL field contains compiler options used specifically when building shared libraries.
Linker Flags
LDFLAGS = -Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now -Wl,--as-needed
The LDFLAGS field contains options passed to the linker when creating PostgreSQL executables and shared libraries.
Executable Linker Flags
LDFLAGS_EX =
The LDFLAGS_EX field specifies additional linker options that apply only to executable programs.
In this installation, the field is empty, indicating that no extra executable-specific linker options were used.
Shared Library Linker Flags
LDFLAGS_SL =.
The LDFLAGS_SL field specifies additional linker options used only when creating shared libraries.
In this installation, no additional shared-library-specific linker options are defined.
Linked libraries
LIBS = -lpgcommon -lpgport -lselinux -lzstd -llz4 -lxslt -lxml2 -lpam -lssl -lcrypto -lgssapi_krb5 -lz -lreadline -lm -lnuma
The LIBS field lists the libraries linked with PostgreSQL during compilation.
Version
VERSION = PostgreSQL 18.4 (Ubuntu 18.4-1.pgdg22.04+1)
Specifies the version of PostgreSQL.
The pg_config utility is an important tool for PostgreSQL developers and administrators. It provides details about the PostgreSQL installation, including installation paths, compiler settings, build options, libraries, and version information. These details help build PostgreSQL extensions correctly and ensure they are installed for the intended postgres instance. Understanding the information returned by pg_config also makes it easier to work with PostgreSQL source code, troubleshoot build issues, and develop extensions with confidence.