Building ESBMC-AI
This guide covers building ESBMC-AI locally and as a container image.
Local Build
ESBMC-AI uses Hatch as its build backend and project manager.
Building a Wheel
# Build the wheel package
hatch build
# Output: dist/esbmc_ai-<version>-py3-none-any.whlDevelopment Environment
# Run without installing (uses hatch environment)
hatch run esbmc-ai <command>
# Enter development shell
hatch shell
# Run tests
hatch testThe build process is defined in pyproject.toml:41-43 using the hatchling build backend.
Container Build
ESBMC-AI uses a multi-stage Containerfile for efficient image builds.
Build Commands
# Using hatch scripts (recommended)
hatch run podman-build [extra_packages] [esbmc_version]
hatch run docker-build [extra_packages] [esbmc_version]
# Examples
hatch run podman-build # Default: latest ESBMC
hatch run podman-build "langchain-google-genai" # With extra packages
hatch run podman-build "" "v7.4" # Specific ESBMC versionBuild Script
The scripts/container/build.sh script:
- Accepts runtime (docker/podman), optional extra packages, and ESBMC version
- Extracts version from
esbmc_ai/__about__.py - Tags images as
esbmc-ai:latest,esbmc-ai:<version>, andesbmc-ai:<git-commit> - Passes build arguments to the Containerfile
Containerfile Architecture
The Containerfile uses a two-stage build process (Containerfile:1-118):
Stage 1: Builder
- Base: Ubuntu 24.04
- Installs Python 3.12 and pipx
- Installs Hatch via pipx
- Runs
hatch buildto create the wheel - Output:
/src/dist/*.whl
Stage 2: Runtime
System Setup:
- Base: Ubuntu 24.04
- Installs Python 3.12, pipx, git, wget, and C/C++ development headers
- Downloads and installs ESBMC binary from GitHub releases (lines 68-78)
ESBMC-AI Installation:
- Copies wheel from builder stage (line 84)
- Installs via pipx with CPU-only PyTorch (lines 87-90)
- Optionally injects extra packages via
EXTRA_PIP_PACKAGESbuild arg (lines 93-97)
Runtime Configuration:
- Sets
ESBMCAI_VERIFIER__ESBMC__PATH=/bin/esbmc(line 104) - Declares API key environment variables (lines 107-109)
- Sets working directory to
/workspace(line 112) - Copies and sets entrypoint script (lines 100-115)
- Default command:
esbmc-ai(shows help)
Build Arguments
ESBMC_VERSION: ESBMC version to install (default: “latest”)EXTRA_PIP_PACKAGES: Space-separated list of additional pip packagesquay_expiration: Image expiration for Quay.io (default: “1m”)
Container Entrypoint
The scripts/container/entrypoint.sh script (lines 1-24):
- Checks if
ESBMCAI_CONFIG_FILEis set and exists - Parses
[extras.packages]from config.toml using Python’s tomllib - Injects extra packages into esbmc-ai environment via
pipx inject(idempotent) - Executes the user’s command
This allows runtime package injection by mounting a config file:
podman run --rm \
--env ESBMCAI_CONFIG_FILE=/config/config.toml \
-v ./config.toml:/config/config.toml:z \
esbmc-ai:latest \
fix-code file.cWorking Directory
The container uses /workspace as the default working directory (line 112). Mount your source code here:
podman run --rm -v my-src-folder:/workspace:z -e OPENAI_API_KEY esbmc-ai:latest fix-code file.cWhy Multi-Stage Build?
The multi-stage approach reduces final image size by:
- Excluding Hatch and build tools from runtime image
- Only copying the built wheel, not source code
- Keeping build artifacts in the builder stage (marked safe-to-remove)
Runtime image contains only: ESBMC, Python, pipx, esbmc-ai wheel, and minimal C/C++ headers.