Imported from codacy-open-source-projects-scans/postgis (
AGENTS.md). Install upstream withnpx skills add codacy-open-source-projects-scans/postgis. Copyright stays with the author.
PostGIS development environment
This document aims to get your development environment up as fast as possible so you can jump ahead into improving the PostGIS codebase. It assumes Ubuntu 24.04 as it is current on Codex space as the time of writing.
This repository does not ship ready-to-run binaries. Contributors are expected to build PostGIS and its extensions locally and to run the regression suites before submitting patches. The notes below summarise what the CI images (https://github.com/postgis/postgis-build-env) provide and adapt them to a plain Ubuntu host where Docker is unavailable.
1. Base system preparation
- Work as a user that is allowed to run
sudo. - Keep the system lean: always prefer
apt-getwith--no-install-recommends. - Make sure the packaged PostgreSQL client binaries precede any other build you
may already have in
PATH(see Section 2).
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
autoconf automake autotools-dev \
bison flex \
build-essential clang clang-tools clang-format llvm \
ca-certificates curl wget gnupg \
ccache cmake ninja-build pkg-config \
cppcheck \
gdb valgrind lcov \
git gettext \
libcunit1 libcunit1-dev \
libexpat1-dev libfreexl-dev \
libgdal-dev gdal-bin \
libgeos-dev \
libgmp-dev libmpfr-dev \
libgsl-dev \
libjson-c-dev \
libopenjp2-7-dev libpng-dev libtiff-dev libwebp-dev \
libpq-dev \
libproj-dev proj-bin \
libprotobuf-c-dev protobuf-c-compiler \
libprotobuf-dev protobuf-compiler \
libsfcgal-dev \
libsqlite3-dev sqlite3 \
libspatialite-dev \
libxml2-dev libxslt1-dev libxml2-utils \
libyaml-dev \
postgresql postgresql-client postgresql-server-dev-all \
python3 python3-distutils python3-pip python3-venv python3-psycopg2 \
xsltproc docbook-xsl docbook-xsl-ns docbook-xml \
zlib1g-dev
This installs software so local workflow can exercise sanitizers, formatters, and coverage reports.
2. Configure PostgreSQL for local testing
The CI images keep PostgreSQL entirely under /usr/local/pgsql. On Ubuntu we
use the packaged server binaries instead. When running as a privileged user (the
typical situation in this environment) reuse the default cluster owned by the
postgres system account:
export PG_MAJOR=$(pg_config --version | awk '{print $2}' | cut -d. -f1)
export PGHOME=/usr/lib/postgresql/${PG_MAJOR}
export PATH="${PGHOME}/bin:${PATH}"
# Start the packaged "main" cluster if it is not already online.
sudo -u postgres pg_ctlcluster "${PG_MAJOR}" main start
# Allow automated tools to connect without prompting for a password by editing the existing local entries.
sudo perl -0pi -e 's/^(host\s+all\s+all\s+127\.0\.0\.1\/32\s+)scram-sha-256/\1trust/m; s/^(host\s+all\s+all\s+::1\/128\s+)scram-sha-256/\1trust/m' \
/etc/postgresql/${PG_MAJOR}/main/pg_hba.conf
sudo -u postgres pg_ctlcluster "${PG_MAJOR}" main reload
# Make the current UNIX account a PostgreSQL superuser.
sudo -u postgres createuser -s $(whoami)
# Alternative: keep SCRAM authentication and set a password for automated tooling.
sudo -u postgres psql -c "ALTER ROLE $(whoami) WITH PASSWORD 'postgres';"
export PGPASSWORD=postgres
Revert the authentication edits once you finish testing so other users of the system are not left with trust rules in place.
If you prefer a completely isolated cluster, create an unprivileged build user
and run initdb as in the upstream documentation. The remainder of this guide
assumes the packaged cluster is used and listens on the default port 5432.
3. Enable core dumps and logbt (optional but recommended)
The ci/github/logbt helper captures backtraces from crashes. On Ubuntu you
need elevated privileges once to reconfigure the kernel core pattern.
sudo ./ci/github/logbt --setup
sudo sysctl kernel.core_pattern
# Keep the directory writable:
sudo mkdir -p /tmp/logbt-coredumps
sudo chmod 1777 /tmp/logbt-coredumps
ulimit -c unlimited
When running under constrained CI where you cannot change kernel.core_pattern,
skip the logbt steps; the test suite still runs but you will not get automatic
core backtraces.
4. Build prerequisites
The following projects are detected automatically via pkg-config or helper
scripts during ./configure. After installing the Ubuntu packages you should
have:
- GEOS (
geos-config) - PROJ (
proj>= 7) - GDAL (
gdal-config) - JSON-C (
json-c>= 0.13) - PROTOBUF-C (for
ST_AsMVT) - SFCGAL (for 3D/advanced geometry tests)
- Libxml2, libxslt and docbook stylesheets (for documentation targets)
- Valgrind (for CUnit leak checks)
Verify their presence if ./configure fails.
5. Building PostGIS
./autogen.sh
./configure \
--with-jsondir=/usr \
--with-projdir=/usr \
--with-raster \
--with-topology \
--with-sfcgal
make -j"$(nproc)"
When iterating repeatedly, make clean or make distclean may be necessary if
you switch compilers or change major dependencies.
6. Running the regression tests
Tests expect the PostgreSQL cluster started in section 2 to be running and the current user to be able to create databases. Export the connection parameters so every helper uses the same cluster:
export PGHOST=127.0.0.1
export PGPORT=5432 # adjust if your cluster uses another port
export PGUSER=$(whoami)
export PGDATABASE=postgres
Before running the tests, install the freshly built artifacts into PostgreSQL so that the regression harness can locate the control files and shared libraries:
sudo make install
Execute the same test targets used in CI:
# Standard compile + regression suite
make check RUNTESTFLAGS="--verbose --extension --raster --topology --sfcgal"
# Undefined behaviour sanitiser runs
CC=clang ./configure CFLAGS="-g3 -O0 -fno-omit-frame-pointer -fsanitize=undefined" LDFLAGS="-fsanitize=undefined"
make -j"$(nproc)"
make check RUNTESTFLAGS="--verbose --extension --raster --topology --sfcgal"
# Coverage build (requires lcov and a clean tree)
make distclean
CFLAGS="-g -O0 --coverage" LDFLAGS="--coverage" ./configure --enable-debug \
--with-jsondir=/usr --with-projdir=/usr --with-raster --with-topology --with-sfcgal
make -j"$(nproc)"
make check RUNTESTFLAGS="--verbose --extension --raster --topology --sfcgal"
Additional targets of interest:
make garden– runs documentation and extra QA checks.make check RUNTESTFLAGS="--upgrade --extension --verbose"– exercises extension upgrade paths; make suresudo make installhas been executed into the same PostgreSQL instance before invoking this.make installcheck– runs tests against an installed copy (aftermake install).
Running a single C unit test
After building the tree (Section 5), you can exercise one CUnit suite in isolation. From the repository root run:
cd liblwgeom/cunit
make cu_tester
./cu_tester geodetic # replace "geodetic" with another suite or test name as needed
The cu_tester binary also accepts individual test names if you need to drill
down further.
Running a single SQL regression test
With PostgreSQL running as configured above and the extension installed via
sudo make install, target one SQL file by passing it to the regression driver:
export PGPASSWORD=postgres # or reuse another password if you kept SCRAM auth
make -C regress check RUNTESTFLAGS="--extension" TESTS="$(pwd)/regress/core/affine"
Swap regress/core/affine for the test you need.
7. Inspecting coverage results
Coverage builds rely on the lcov utilities. After executing the coverage make check run:
# Capture data from the build tree
lcov --capture --directory . --output-file coverage.info
# Optionally filter out system libraries and generated files
lcov --remove coverage.info '/usr/*' '*/tests/*' --output-file coverage.filtered.info
# Produce an HTML report for browsing
genhtml coverage.filtered.info --output-directory coverage-html
# Quickly spot uncovered lines in the terminal
lcov --list coverage.filtered.info | less
Open coverage-html/index.html in a browser or upload the report to your CI
artifacts to explore missing lines interactively.
If you rely on the ci/github/run_*.sh wrappers, export PGHOME and PGDATA as
shown above and replace /usr/local/pgsql/bin/pg_ctl in those scripts with the
packaged location or create a symlink at /usr/local/pgsql/bin pointing to
${PGHOME}/bin.
8. Cleaning up
To reclaim disk space:
sudo -u postgres pg_ctlcluster "${PG_MAJOR}" main stop
sudo rm -rf /tmp/logbt-coredumps
If you created a private cluster instead of using the packaged one, stop it with
pg_ctl -D "$PGDATA" stop and remove the data directory manually.
9. Maintaining formatting
Before submitting patches that modify C or C++ files, run clang-format only on the relevant hunks to avoid unrelated churn:
git clang-format
The command formats staged changes by default. Use git clang-format <commit> to
reflow a specific range, or pass --extensions c,cpp,h when touching files with
non-standard suffixes. Validate that the resulting diff stays focused on the
code you touched.
Review STYLE file in root of the repository for other stylistic preferences.
For release policies, upgrade implications, and naming
conventions for new features, skim doc/developer.md (PostGIS Developer
How-To) for a concise overview of those workflows.
The Codecov upload commands in ci/github/run_coverage.sh and
ci/github/run_garden.sh require outbound network access; they are harmless to
ignore locally.