z3.rs

repository·master·Indexed 19 days ago

https://github.com/prove-rs/z3.rs

Rust bindings for the Z3 theorem prover. The project consists of three crates: `z3` for high-level idiomatic wrappers, `z3-sys` for low-level unsafe FFI access to the raw C API, and `z3-src` for Z3 source distribution and vendored build logic. It supports multiple installation methods including system-installed Z3, vendored builds via CMake, vcpkg, and pre-compiled binaries from GitHub releases.

Tokens
13.5K
Snippets
41
Records
62
Agent score
67%

What's inside z3.rs

  1. Choose between `z3`, `z3-sys`, and `z3-src`

    master

    The z3.rs project is split into three main crates depending on your needs:

    • z3: The high-level, idiomatic Rust bindings. This is the recommended crate for almost all users (99% of use cases).
    • z3-sys: Low-level, unsafe FFI bindings that expose the raw C API of the Z3 solver. Use this only if you need a Z3 feature not yet wrapped by the z3 crate, or if you are building your own high-level API.
    • z3-src: Contains the Z3 source distribution and the logic required to handle vendored builds.
  2. Z3 Version Compatibility and Requirements

    master

    The compatibility between the Rust crates and the upstream Z3 solver depends on the version of the crates you are using.

    For z3 ≥ 0.20.0 (and z3-sys ≥ 0.11.0)

    • Minimum Upstream Z3: 4.8.17 is required. This is due to API requirements (e.g., Regexp methods) and DeclKind enum correctness.
    • Special Feature: Optimize::translate and Optimize::clone require upstream Z3 ≥ 4.16.0. These are gated behind the z3_4_16 feature flag.

    For z3 ≤ 0.19.x (and z3-sys ≤ 0.10.x)

    • Upstream Z3: Supports versions ≥ 4.8.12.
  3. Use system-installed Z3

    master

    By default, the crate looks for Z3 in your system paths. If you are using Homebrew on macOS and the headers are not found, you must set the Z3_SYS_Z3_HEADER environment variable. You may also need to set Z3_LIBRARY_PATH_OVERRIDE for the linker.

    To make these settings permanent for your project, add them to .cargo/config.toml.

    # Via environment variables
    Z3_SYS_Z3_HEADER=/opt/homebrew/include/z3.h cargo build
    
    # Or via .cargo/config.toml
    [env]
    Z3_LIBRARY_PATH_OVERRIDE = "/opt/homebrew/lib"
    Z3_SYS_Z3_HEADER = "/opt/homebrew/include/z3.h"
  4. Configure Z3 library discovery in z3-sys

    master

    The z3-sys crate requires a Z3 installation to function. You can configure how the crate finds the Z3 libraries using one of the following four methods:

    1. System Installation (Default)

    By default, the crate searches for a system-installed copy of Z3 (e.g., via apt on Linux or brew install z3 on macOS).

    • Override path: Use the Z3_LIBRARY_PATH_OVERRIDE environment variable to manually specify the library search path.

    2. Vendored Build (Static Linking)

    Enable the vendored feature (note: bundled is a deprecated alias). This uses cmake to build and statically link Z3 from source using the z3-src crate.

    • Using a custom Z3 checkout: Set the Z3_SRC_SOURCE_DIR environment variable to the absolute path of your Z3 source tree.
      Z3_SRC_SOURCE_DIR=/absolute/path/to/z3 cargo build
    • Relative paths in Cargo config: To use a path relative to your project root, add it to .cargo/config.toml:
      [env]
      Z3_SRC_SOURCE_DIR = { value = "path/to/z3", relative = true }
    • Note: Submodules or local z3 directories are not picked up automatically; you must point to them explicitly.

    3. vcpkg Feature

    Enable the vcpkg feature to use vcpkg to build and install a copy of Z3.

    4. GitHub Release Feature

    Enable the gh-release feature to download a pre-compiled Z3 binary from GitHub releases for your platform.

    • Pin version: Set the Z3_SYS_Z3_VERSION environment variable to specify a version.
    • Avoid Throttling: If you encounter 403 errors (common in CI or frequent rebuilds), provide a GitHub Personal Access Token via the READ_ONLY_GITHUB_TOKEN environment variable to authenticate requests.
    [env]
    Z3_SRC_SOURCE_DIR = { value = "path/to/z3", relative = true }
  5. Build Z3 from source with the vendored feature

    master

    Enabling the vendored feature uses cmake to build Z3 locally.

    If you want to use your own Z3 source tree instead of the one provided by z3-src, set the Z3_SRC_SOURCE_DIR environment variable to the absolute path of your Z3 source.

    Note: A z3 directory within your project or workspace is not automatically detected; you must point to it explicitly.

    To use a path relative to your project root, use the relative = true key in .cargo/config.toml.

    # Using an absolute path
    Z3_SRC_SOURCE_DIR=/absolute/path/to/z3 cargo build
    
    # Using a relative path in .cargo/config.toml
    [env]
    Z3_SRC_SOURCE_DIR = { value = "path/to/z3", relative = true }
  6. Use z3-src as a build dependency to compile Z3 from source

    master

    If you are maintaining your own Z3 FFI bindings and want to compile Z3 from source instead of linking against a system-installed copy, add z3-src as a build-dependency in your Cargo.toml.

    In your build.rs, call z3_src::build() to compile the source. The returned artifacts object provides access to the include directory and library directory, and includes a helper method print_cargo_metadata() which emits the necessary cargo:rustc-link-search and cargo:rustc-link-lib directives for Cargo to link the static library correctly.

    // Cargo.toml
    [build-dependencies]
    z3-src = "416"
    
    // build.rs
    fn main() {
        let artifacts = z3_src::build();
        artifacts.print_cargo_metadata();
        // artifacts.include_dir() — path containing z3.h
        // artifacts.lib_dir()     — path containing the static library
    }
  7. Prerequisites for building z3-src

    master

    To successfully build z3-src, ensure the following are available on your system:

    1. CMake: Must be available on your PATH during the build process.
    2. C++ compiler: A compiler supported by Z3's CMake build system (e.g., GCC, Clang, or MSVC).

    Note on build time: Compilation is resource-intensive and typically takes approximately 5 minutes on modern hardware. Incremental rebuilds are cached by Cargo in the OUT_DIR directory.

  8. Enable `Optimize::translate` and `Optimize::clone` via features

    master

    If you are using z3 version 0.20 or higher and require Optimize::translate or Optimize::clone, you must ensure your upstream Z3 version is at least 4.16.0 and enable the z3_4_16 feature flag in your Cargo.toml.

    [dependencies]
    z3 = { version = "0.20", features = ["z3_4_16"] }
  9. Configure Z3 library discovery methods

    master

    The z3 crate requires the Z3 library to be present on your system. You can control how the crate finds Z3 using specific feature flags in your Cargo.toml:

    • Default (No flags): Searches for a system-installed copy of Z3 (e.g., via apt, brew, etc.).
    • vendored: Builds and statically links Z3 from source using cmake. The source is provided by the z3-src crate. (Note: bundled is a deprecated alias for vendored).
    • vcpkg: Uses a copy of Z3 installed via the vcpkg package manager.
    • gh-release: Downloads a pre-compiled copy of Z3 from GitHub releases for your platform.
    # Example using gh-release
    [dependencies]
    z3 = {version="0", features = ["gh-release"]}
    
    # Example using vcpkg
    [dependencies]
    z3 = {version="0", features = ["vcpkg"]}