Building SIPI from Source Code¶
Prerequisites¶
Kakadu (JPEG 2000)¶
To build SIPI from source code, you must have
Kakadu, a JPEG 2000 development toolkit
that is not provided with SIPI and must be licensed separately. The
Kakadu source code archive v8_5-01382N.zip must be placed in the
vendor subdirectory of the source tree before building.
Adobe ICC Color Profiles¶
SIPI uses the Adobe ICC Color profiles, which are automatically
downloaded by the build process. The user is responsible for reading
and agreeing with Adobe's license conditions, which are specified in
the file Color Profile EULA.pdf.
Vendored Dependencies¶
SIPI builds all external libraries from source. Source archives are vendored in the
vendor/ directory and tracked with Git LFS. This ensures
builds are reproducible and work offline — no internet access is needed during compilation.
First-time setup (Git LFS)¶
After cloning the repository, pull the LFS objects:
Dependency management¶
All dependency metadata (version, URL, SHA-256 hash) is centralized in
cmake/dependencies.cmake. The build system uses local archives from vendor/
when present, and falls back to downloading from the URL if not.
| Command | Description |
|---|---|
make vendor-download |
Download all dependency archives to vendor/ |
make vendor-verify |
Verify SHA-256 checksums of all archives |
make vendor-checksums |
Print current checksums (for updating the manifest) |
Updating a dependency¶
- Edit
cmake/dependencies.cmake— updateDEP_<NAME>_VERSION,DEP_<NAME>_URL, andDEP_<NAME>_FILENAME - Run
make vendor-downloadto fetch the new archive - Run
make vendor-checksumsand updateDEP_<NAME>_SHA256in the manifest - Run
make vendor-verifyto confirm - Clean build and test:
rm -rf build && make zig-build-local && make zig-test
Adding a new dependency¶
- Add
DEP_<NAME>_*variables tocmake/dependencies.cmake - Create
ext/<name>/CMakeLists.txtwith the local fallback pattern (see existing deps for examples) - Add
add_subdirectory(ext/<name>)to the rootCMakeLists.txt - Run
make vendor-downloadandmake vendor-checksums - Update the SHA-256 hash in the manifest
Building with Docker (Recommended)¶
The simplest way to build SIPI is using Docker. This requires Docker with buildx support.
All commands are run from the repository root via make:
# Build Docker image (compiles SIPI, runs unit tests inside container)
make docker-build
# Run smoke tests against the locally built Docker image
make test-smoke
The Docker build uses ubuntu:24.04 as the base image and installs only
the minimal system dependencies needed for compilation. The Dockerfile
handles cmake configuration, compilation, unit testing, and debug symbol
extraction in a multi-stage build.
Platform-specific builds (used by CI)¶
# Build for specific architectures (used in CI release pipeline)
make docker-test-build-amd64
make docker-test-build-arm64
Building with Zig (Experimental, Parallel to Docker)¶
Zig-based builds are enabled for local development and static Linux binary production, but Docker remains a first-class release path during rollout. For CI/release workflow details (validation jobs, gates, and artifact publishing), see CI and Release.
Prerequisites¶
- Place the Kakadu archive
v8_5-01382N.zipin thevendor/directory - Install Zig
0.15.2 - Install build tools (
cmake,autoconf,automake,libtool)
OpenSSL, libcurl, and libmagic are built from source by SIPI's CMake build; they do not need to be preinstalled as system libraries.
Local Zig build¶
Static Linux Zig builds¶
Static Zig builds in Docker (local CI mirror)¶
For testing the zig-static build in a Docker container that mirrors the CI
build environment (Alpine 3.21 + Zig). Alpine is used because its /usr/include
contains musl headers natively, avoiding the glibc header contamination that
occurs on Ubuntu (where zig cc unconditionally adds /usr/include).
make zig-static-docker-arm64 # build + unit test aarch64-linux-musl in Docker
make zig-static-docker-amd64 # build + unit test x86_64-linux-musl in Docker
These use Dockerfile.zig-static which installs Zig, configures the
toolchain, builds SIPI, and runs ctest — all inside the container. The
local targets use build-static/ as the build directory (CI uses build/).
E2e tests are not included because the resulting Linux ELF binary cannot run
on a macOS host. CI handles the portability proof by running e2e on a bare
Ubuntu runner against the Alpine-built binary — see CI and Release
for details.
Validation commands¶
# Linux static binary must not have dynamic NEEDED entries
# (local Makefile targets use build-static/; CI uses build/)
readelf -d build-static/sipi | grep NEEDED
# Should report static
ldd build-static/sipi
# macOS policy: only libSystem is allowed
otool -L build-zig-macos/sipi
Building with Nix (Native Development)¶
For native development, SIPI uses Nix to provide a reproducible development environment with all required dependencies.
Setup¶
- Install Nix
- Place the Kakadu archive
v8_5-01382N.zipin thevendor/directory - Enter the Nix development shell:
# GCC environment (default, used by CI)
nix develop
# Clang environment (alternative)
nix develop .#clang
Build and Test¶
All nix-* targets must be run from inside a Nix development shell:
# Build SIPI (debug mode with code coverage enabled)
make nix-build
# Run unit tests
make nix-test
# Run end-to-end tests
make nix-test-e2e
# Run all three in sequence (as CI does)
make nix-build && make nix-test && make nix-test-e2e
Run the Server¶
Code Coverage¶
# Generate XML coverage report (gcovr, used by CI/Codecov)
make nix-coverage
# Generate HTML coverage report (lcov, for local viewing)
make nix-coverage-html
Debugging¶
Building on macOS without Zig (Not Recommended)¶
Building directly on macOS without Nix is unsupported but possible:
You will need CMake and a C++23-compatible compiler. All library dependencies (including OpenSSL, libcurl, libmagic) are built from source automatically by the build system.
All Make Targets¶
Run make help to see all available targets:
Key target groups:
| Target | Description |
|---|---|
docker-build |
Build Docker image locally |
docker-test-build-{amd64,arm64} |
Build + test for specific architecture |
test-smoke |
Run smoke tests against Docker image |
zig-build-local |
Build SIPI natively with Zig (experimental) |
zig-test |
Run unit tests for Zig local build |
zig-test-e2e |
Run end-to-end tests for Zig local build |
zig-build-{amd64,arm64} |
Build static Linux binaries with Zig (experimental) |
zig-static-docker-{arm64,amd64} |
Build + test static binaries in Docker (local CI mirror) |
nix-build |
Build SIPI natively (debug + coverage) |
nix-test |
Run unit tests |
nix-test-e2e |
Run end-to-end tests |
nix-coverage |
Generate XML coverage report |
nix-run |
Run SIPI server |
nix-valgrind |
Run with Valgrind |
docs-build |
Build documentation |
docs-serve |
Serve documentation locally |
vendor-download |
Download all dependency archives to vendor/ |
vendor-verify |
Verify SHA-256 checksums of vendored archives |
vendor-checksums |
Print SHA-256 checksums for all archives |
clean |
Remove build artifacts |