Build Guide
ESBMC builds on Linux, macOS, FreeBSD and Windows. Pick your platform below and
follow the steps. Each tab produces a working esbmc with the Z3 solver; the
heavier dependencies (LLVM/Clang, fmt, nlohmann-json, yaml-cpp and immer) are
downloaded and built automatically with -DDOWNLOAD_DEPENDENCIES=1 where the
platform supports it.
Note
At least 6 GB of RAM is recommended. ESBMC is distributed mainly under the Apache License 2.0.
For a build with several solvers, or CHERI/fuzzing support, see Building with all solvers and Advanced.
Build ESBMC
Install prerequisites
sudo apt-get update
sudo apt-get install -y build-essential cmake ninja-build git bison flex \
python3 libboost-all-dev g++-multilibLLVM/Clang, Z3 and the libraries fmt, nlohmann-json, yaml-cpp and immer are
fetched by -DDOWNLOAD_DEPENDENCIES=1, so they are not installed here.
Get the source
git clone https://github.com/esbmc/esbmc.git
cd esbmcConfigure and build
cmake -GNinja -Bbuild -DDOWNLOAD_DEPENDENCIES=1 -DENABLE_Z3=1
ninja -C buildThe binary is written to build/src/esbmc/esbmc.
Optional: run the regression tests
Add the testing flags when configuring, then run ctest:
cmake -GNinja -Bbuild -DDOWNLOAD_DEPENDENCIES=1 -DENABLE_Z3=1 \
-DBUILD_TESTING=On -DENABLE_REGRESSION=On
ninja -C build
ctest --test-dir build -j"$(nproc)" -L esbmc --timeout 120Optional: enable a frontend or extra solvers
For Python, Solidity or IBEX support see Optional frontends. For a multi-solver build see Building with all solvers.
Dependency reference
| package | required | minimum version |
|---|---|---|
| clang | yes | 11.0.0 |
| boost | yes | 1.77 |
| CMake | yes | 3.18.0 |
| Boolector | no | 3.2.2 |
| CVC4 | no | 1.8 |
| CVC5 | no | 1.1.2 |
| MathSAT | no | 5.5.4 |
| Yices | no | 2.6.4 |
| Z3 | no | 4.13.3 |
| Bitwuzla | no | 0.9.0 |
The version requirements are stable but can change between releases. For all available CMake options, see Options.cmake.
Optional frontends
These are extra CMake flags added to the configure step in any platform tab above.
Python
Add -DENABLE_PYTHON_FRONTEND=On to the configure step:
cmake -GNinja -Bbuild -DDOWNLOAD_DEPENDENCIES=1 -DENABLE_Z3=1 -DENABLE_PYTHON_FRONTEND=Onast2json is vendored in the source tree, so no pip install is needed.
Optionally install mypy (e.g. pipx install mypy) for
Python type checks.
Solidity
Add -DENABLE_SOLIDITY_FRONTEND=On to the configure step. The Solidity frontend
verifies smart contracts against predefined safety properties (bounds, overflow,
underflow) and user-defined assertions.
IBEX (interval constraint solving)
Enables --goto-contractor. Install IBEX following its
instructions, then:
cmake -GNinja -Bbuild -DENABLE_GOTO_CONTRACTOR=ON -DIBEX_DIR=path-to-ibexAPI documentation
Add -DBUILD_DOC=On to the configure step to build the Doxygen API reference
alongside ESBMC (requires doxygen and graphviz). See the
API Reference guide for details.
Building with all solvers
ESBMC supports Bitwuzla, Boolector, CVC4, CVC5, MathSAT, Yices 2 and Z3. All are optional, but without at least one solver ESBMC cannot verify most programs. For a single-solver build, the platform tabs above are enough.
The recipe below mirrors the multi-solver build used in ESBMC’s CI: build each solver into the project directory, then point the configure step at them. Build only the solvers you need.
Prepare a Clang/LLVM toolchain
For a static build, let ESBMC download Clang/LLVM:
ESBMC_CLANG=-DDOWNLOAD_DEPENDENCIES=On
ESBMC_STATIC=ONFor a shared build, use the system LLVM/Clang instead (Ubuntu example):
sudo apt-get install libclang-cpp16-dev
ESBMC_CLANG="-DLLVM_DIR=/usr/lib/llvm-16/lib/cmake/llvm -DClang_DIR=/usr/lib/cmake/clang-16"
ESBMC_STATIC=OFFBuild the solvers
Boolector
git clone --depth=1 --branch=3.2.3 https://github.com/boolector/boolector && cd boolector && ./contrib/setup-lingeling.sh && ./contrib/setup-btor2tools.sh && ./configure.sh --prefix $PWD/../boolector-release && cd build && make -j9 && make install && cd ../..Z3
# Linux
wget https://github.com/Z3Prover/z3/releases/download/z3-4.13.3/z3-4.13.3-x64-glibc-2.35.zip && unzip z3-4.13.3-x64-glibc-2.35.zip && mv z3-4.13.3-x64-glibc-2.35 z3
# macOS
brew install z3 && cp -rp $(brew info z3 | egrep "/usr[/a-zA-Z\.0-9]+ " -o) z3Bitwuzla
Requires MPFR >= 4.2.1 (apt-get install libmpfr-dev / brew install mpfr).
git clone --depth=1 --branch=0.9.0 https://github.com/bitwuzla/bitwuzla.git && cd bitwuzla && ./configure.py --prefix $PWD/../bitwuzla-release && cd build && meson install && cd ../..CVC4 (Linux only)
pip3 install toml && git clone https://github.com/CVC4/CVC4.git && cd CVC4 && git reset --hard b826fc8ae95fc && ./contrib/get-antlr-3.4 && ./configure.sh --optimized --prefix=../cvc4 --static --no-static-binary && cd build && make -j4 && make install && cd ../..CVC5
pip3 install toml && git clone https://github.com/CVC5/CVC5.git && cd CVC5 && git switch --detach cvc5-1.1.2 && ./configure.sh --prefix=../cvc5 --auto-download --static --no-static-binary && cd build && make -j4 && make install && cd ../..MathSAT
# Linux
wget http://mathsat.fbk.eu/release/mathsat-5.5.4-linux-x86_64.tar.gz -O mathsat.tar.gz && tar xf mathsat.tar.gz && mv mathsat-5.5.4-linux-x86_64 mathsat
# macOS
wget http://mathsat.fbk.eu/release/mathsat-5.5.4-darwin-libcxx-x86_64.tar.gz -O mathsat.tar.gz && tar xf mathsat.tar.gz && mv mathsat-5.5.4-darwin-libcxx-x86_64 mathsat && ln -s /usr/local/include/gmp.h mathsat/include/gmp.hYices (Linux)
Yices needs a static GMP first:
wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.xz && tar xf gmp-6.1.2.tar.xz && cd gmp-6.1.2 && ./configure --prefix $PWD/../gmp --disable-shared ABI=64 CFLAGS=-fPIC CPPFLAGS=-DPIC && make -j4 && make install && cd ..
git clone https://github.com/SRI-CSL/yices2.git && cd yices2 && git checkout Yices-2.6.4 && autoreconf -fi && ./configure --prefix $PWD/../yices --with-static-gmp=$PWD/../gmp/lib/libgmp.a && make -j9 && make static-lib && make install && cp ./build/x86_64-pc-linux-gnu-release/static_lib/libyices.a ../yices/lib && cd ..Configure and build ESBMC
Pass the directories of the solvers you built. Drop the flags for any solver you skipped.
cd esbmc && cmake -GNinja -Bbuild -DBUILD_TESTING=On -DENABLE_REGRESSION=On \
$ESBMC_CLANG -DBUILD_STATIC=${ESBMC_STATIC:-ON} \
-DBoolector_DIR=$PWD/../boolector-release -DZ3_DIR=$PWD/../z3 \
-DENABLE_MATHSAT=ON -DMathsat_DIR=$PWD/../mathsat \
-DENABLE_YICES=On -DYices_DIR=$PWD/../yices -DCVC4_DIR=$PWD/../cvc4 \
-DGMP_DIR=$PWD/../gmp -DBitwuzla_DIR=$PWD/../bitwuzla-release \
-DCMAKE_INSTALL_PREFIX:PATH=$PWD/../release
ninja -C build && ninja -C build installESBMC is installed into the release folder. Add -DCMAKE_BUILD_TYPE=Debug to
enable ESBMC’s internal assertions.
Advanced
Build in a Docker container
A minimal Debian-based image that builds ESBMC with Z3, letting
-DDOWNLOAD_DEPENDENCIES=1 fetch LLVM/Clang and the libraries:
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake ninja-build git bison flex \
python3 libboost-all-dev g++-multilib \
&& rm -rf /var/lib/apt/lists/*
RUN git clone --depth=1 https://github.com/esbmc/esbmc.git /esbmc
WORKDIR /esbmc
RUN cmake -GNinja -Bbuild -DDOWNLOAD_DEPENDENCIES=1 -DENABLE_Z3=1 \
&& ninja -C buildBuild the image with docker build -t esbmc .; the binary is at
/esbmc/build/src/esbmc/esbmc.
Shared (dynamic) builds
A non-static ESBMC links against system libraries/solvers. Shared linking is the
default when CMake is invoked with -DBUILD_STATIC=Off (or the variable unset).
When Clang is built with CLANG_LINK_CLANG_DYLIB=On, ESBMC links the dynamic
libclang-cpp and does not bundle Clang’s headers. Header bundling is controlled
by CLANG_HEADERS_BUNDLED (On/Off/detect); the default detect bundles
headers only for static Clang links. Not bundling speeds up source translation by
avoiding a temporary header-extraction directory, but ESBMC must be recompiled
when the system Clang is updated.
CHERI-C support (experimental)
CHERI-enabled ESBMC uses CHERI Clang (release 20210817, clang 13). Build it, then configure ESBMC against it:
wget https://github.com/CTSRD-CHERI/llvm-project/archive/refs/tags/cheri-rel-20210817.tar.gz
sudo apt-get install lld
tar xf cheri-rel-20210817.tar.gz && mkdir clang13 && cd llvm-project-cheri-rel-20210817 && mkdir build && cd build
cmake -GNinja -S ../llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='llvm;clang' -DLLVM_INSTALL_BINUTILS_SYMLINKS=TRUE -DLLVM_ENABLE_LIBXML2=FALSE -DLLVM_ENABLE_ZLIB=FALSE '-DLLVM_TARGETS_TO_BUILD=AArch64;ARM;Mips;RISCV;X86;host' -DCMAKE_INSTALL_PREFIX=../../clang13
ninja && ninja install && cd ../..
ESBMC_CLANG=$(echo -D{LLVM,Clang}_DIR=$PWD/clang13)A CHERI sysroot is needed for programs that use the C standard library. The cheribuild tool is the recommended way to obtain one:
git clone https://github.com/CTSRD-CHERI/cheribuild.git && cd cheribuild && python3 cheribuild.py cheribsd-sdk-riscv64-purecap -dThen configure ESBMC with:
-DESBMC_CHERI=On -DESBMC_CHERI_HYBRID_SYSROOT=<path> -DESBMC_CHERI_PURECAP_SYSROOT=<path>e.g. <path> pointing at $HOME/cheri/output/sdk/sysroot-riscv64-purecap.
Fuzzing targets
ESBMC ships libFuzzer targets. They must be built with Clang, so configure ESBMC to use it and enable fuzzing:
cmake -GNinja -Bbuild -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_FUZZER=1Passing the compiler options for the first time clears the CMake cache, so some variables may need to be re-set.