Skip to main content

Build-matrix tool for C/C++ projects — compile with multiple compiler/flag variants.

Project description

Anvil

Anvil is a build-matrix tool for C/C++ projects. It compiles your code multiple times with different compilers, optimization levels, and compiler flags — all driven by simple JSON configuration files.

Perfect for:

  • Benchmarking across compiler configurations (GCC, Clang, Zig, etc.)
  • Testing code with different optimization levels and build flags
  • CI/CD workflows that need multi-variant builds
  • Exploring compiler behavior with systematically varied flags

Features

  • Three build modes: Direct file compilation, folder recursion, or CMake projects
  • Multi-compiler support: GCC, Clang, Zig, etc. (any compiler with a compatible CLI)
  • Per-variant configuration: Each variant specifies compiler, C++ standard, optimization flags, and defines
  • Parallel builds: Build multiple variants simultaneously for faster turnaround
  • Config discovery: Looks for project config files named anvil_project.json or anvil.project.json, and variant files named anvil_variants.json or anvil.variants.json near the target or project directory
  • Flexible output: Artifacts and metadata collected in a single directory

Installation

From source (editable)

git clone https://github.com/michezio/anvil.git
cd anvil
pip install -e .

Then use as:

python -m anvil --target myfile.cpp
# or
anvil --target myfile.cpp

From PyPI (future)

pip install anvil-matrix
anvil --target myfile.cpp

Quick Start

1. Compile a single file with default variants

python -m anvil --target src/myapp.cpp

Produces three binaries (O2, O3, Ofast):

.out/anvil_build/myapp/
  ├── myapp__o2_baseline
  ├── myapp__o3_baseline
  ├── myapp__ofast_fastmath
  └── build_summary.json

2. Compile all files in a folder

python -m anvil --target src/myproject/

3. Use custom variants

Create a variants file such as anvil_variants_quick.json (the repository examples use the same underscore-based naming):

[
  {
    "name": "gcc_o3",
    "compiler": "g++",
    "standard": "c++23",
    "cxx_flags": "-O3",
    "defines": []
  },
  {
    "name": "clang_o3",
    "compiler": "clang++",
    "standard": "c++23",
    "cxx_flags": "-O3",
    "defines": []
  }
]

Then point Anvil at it explicitly:

python -m anvil --target src/myapp.cpp --variants path/to/anvil_variants_quick.json

4. Control build behavior with config files

Create anvil_project.json next to your source. The sample project config in this repository uses the same nested cmake shape:

{
  "name": "myproject",
  "build_dir": "/build/anvil/myproject",
  "out_dir": ".out/anvil_build/myproject",
  "cmake": {
    "target": "my_target",
    "build_type": "Release",
    "args": []
  },
  "include_dirs": ["/opt/deps/include"],
  "link_flags": "-L/opt/deps/lib -lmydep",
  "jobs": 0,
  "parallel_variants": 4,
  "stop_on_error": false,
  "clean": false,
  "verbose": false
}

Then:

python -m anvil --target src/ --project path/to/anvil_project.json

Configuration

anvil_project.json

Field Type Default Description
name string (inferred from parent directory) Project name, used in output paths
build_dir string /build/anvil/<name> CMake build directory (CMake mode)
out_dir string .out/anvil_build/<name> Output directory for artifacts
cmake.target string "" CMake target name (required for CMake mode)
cmake.build_type string Release CMake build type used in CMake mode
cmake.args array [] Extra cmake configure arguments
env_setup string "" Script to source before building
include_dirs array [] Extra -I paths (direct mode)
link_flags string "" Extra linker flags
jobs int 0 Compile jobs per variant (0 = auto via nproc)
parallel_variants int 1 Number of variants to build simultaneously
stop_on_error bool false Abort on first variant failure
clean bool false Clean build directories before building
verbose bool false Print full compiler commands

Variants JSON

Anvil reads a top-level JSON array of variant objects. The file can be named anvil_variants.json or anvil.variants.json, or passed explicitly via --variants.

[
  {
    "name": "o3_baseline",
    "compiler": "g++",
    "standard": "c++23",
    "cxx_flags": "-O3",
    "defines": ["MY_DEFINE=1"]
  }
]
Field Type Default Description
name string (required) Variant identifier
compiler string g++ Compiler command (supports multi-word forms like zig c++)
standard string c++23 C++ standard flag (for example c++20 or c++23)
cxx_flags string "" Compiler flags (for example -O3 -march=native)
defines array [] Preprocessor defines (for example ["NDEBUG", "MY_FLAG=1"])

Command Line

usage: anvil [-h] [--target TARGET] [--project PROJECT] [--variants VARIANTS]
             [--clean] [--stop-on-error] [--jobs JOBS] [--parallel PARALLEL]
             [--verbose] [--extra-args [EXTRA_ARGS ...]]

Build-matrix tool: compiles C/C++ targets with multiple variant configurations.

options:
  --target TARGET              Path to a .cpp file, folder, or CMake project root
  --project PROJECT            Path to an anvil_project.json or anvil.project.json file/folder
  --variants VARIANTS          Path to an anvil_variants.json or anvil.variants.json file/folder
  --clean                      Clean build directories before building
  --stop-on-error              Stop on first variant failure
  --jobs JOBS, -j JOBS         Compile jobs per variant (0 = nproc)
  --parallel PARALLEL, -p      Variants to build in parallel
  --verbose, -v                Print full compilation commands
  --extra-args [...]           Extra compiler/linker arguments (direct mode only)

Examples

See the examples/ directory for sample configurations.

Single-file benchmark

python -m anvil --target benchmark.cpp \
  --variants examples/anvil_variants_full.json \
  --parallel 4 --jobs 2

CMake project with custom environment

python -m anvil --target myproject \
  --project myproject/anvil_project.json \
  --variants myproject/anvil_variants_quick.json \
  --clean

Verbose output with stop-on-error

python -m anvil --target src/ --verbose --stop-on-error

Output

Artifacts are collected under out_dir (default: .out/anvil_build/<name>):

.out/anvil_build/myproject/
  ├── myproject__o2_gcc
  ├── myproject__o3_gcc
  ├── myproject__ofast_gcc
  ├── myproject__o2_gcc.json        # Metadata
  ├── myproject__o3_gcc.json
  ├── myproject__ofast_gcc.json
  └── build_summary.json            # Build stats

Each .json file contains:

  • Variant name and configuration
  • Compiler used
  • Effective flags and defines
  • Build directory
  • Artifact path

License

MIT — see LICENSE

Contributing

Contributions welcome! Please open issues and PRs on GitHub.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anvil_matrix-0.2.1.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

anvil_matrix-0.2.1-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file anvil_matrix-0.2.1.tar.gz.

File metadata

  • Download URL: anvil_matrix-0.2.1.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for anvil_matrix-0.2.1.tar.gz
Algorithm Hash digest
SHA256 d35dc1df0088a359bdc6e27b23b52f7abef9a76cfac4ef23449decaa391ff42f
MD5 01f4259da8ef10e89239d77864e491de
BLAKE2b-256 c5db8adb7738142c54c8653c4be015d3b72cbc95c4e7a81ea81a869c5a05c1e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for anvil_matrix-0.2.1.tar.gz:

Publisher: python-publish.yml on michezio/anvil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anvil_matrix-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: anvil_matrix-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for anvil_matrix-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 99fb2363555f6f28dfcd39097d37ecc4868c76aa1f1cb04ba3666f3519cb1a2a
MD5 f9e335d792dffe7bbba65c7ac5a2f228
BLAKE2b-256 f281a97a1f80ed3b3a597cf1e5a1462bd80ed6d578f75dcc2d8fe2f1c4791195

See more details on using hashes here.

Provenance

The following attestation bundles were made for anvil_matrix-0.2.1-py3-none-any.whl:

Publisher: python-publish.yml on michezio/anvil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page