Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Building from source

You need this if you are on a platform with no prebuilt toolchain — Linux on arm64, or an Intel Mac — or if you intend to work on the compiler itself.

Everything below has been run on the platform it documents.

What the build needs

RequirementWhy
LLVM/MLIR 22Pinned by mlir-sys in Cargo.toml. A different major version fails to link with undefined MLIR C-API symbols.
Rust (stable)The compiler is written in Rust.
z3 — the binarySeam verification executes it. The library alone is not enough.
libffiThe dispatch runtime calls outlined kernels through their MLIR C interface.

Plus cmake, ninja, pkg-config, python3 and a C++ compiler.

macOS (Apple Silicon)

xcode-select --install

brew install llvm z3 cmake ninja pkg-config python3 rustup
rustup-init -y --default-toolchain stable

Check that Homebrew’s LLVM is the pinned major version:

$(brew --prefix llvm)/bin/llvm-config --version    # expect 22.x

If Homebrew has moved on, install the pinned one with brew install llvm@22 and run LLVM_VERSION=22 ./setup.sh.

Linux x86_64 (Ubuntu 24.04)

scripts/provision/setup_linux.sh installs everything:

./scripts/provision/setup_linux.sh

It installs build tooling (build-essential, ninja-build, cmake, pkg-config), libraries (libffi-dev, libz3-dev, z3, zlib1g-dev, libzstd-dev, libedit-dev, libxml2-dev), and LLVM 22 from apt.llvm.org — Ubuntu’s own repositories lag the pinned version.

libmlir-22-dev is the package people miss. It ships the MLIR C API that the Rust bindings link against, and it is not pulled in by llvm-22-dev.

Rust is installed separately by the script, via rustup.

Sizing, if you are provisioning a box for this: 40 GB of disk (a release build leaves target/ at about 2 GB, and cargo test adds a second profile), and as many cores as you can get. A reference release build takes about 1m48s on 36 vCPU with a warm crate cache.

Configure and build

Identical on both platforms:

./setup.sh           # writes config.local -- LLVM path, cargo/rustup homes, PATH
source config.local  # required in every new shell, before any cargo command
cargo build --release

setup.sh puts LLVM first on PATH, so an unsuffixed llvm-config, mlir-translate or clang++ resolves to the pinned version rather than to Xcode’s or to another LLVM on the box. It warns if what it found does not match the pin.

If you get llvm-config: command not found or cargo: command not found, you opened a new shell and did not source config.local. It is once per shell, every shell.

Verify

cat > /tmp/hello.vx <<'EOF'
fn main() -> i32 {
    let x: i32 = 21;
    return x * 2;
}
EOF

source config.local
./target/release/vxc --run /tmp/hello.vx

Expect the last line to read [JIT] Program exited with code: 42. Then run the suite:

cargo test

Optional components

The build succeeds without any of these; each unlocks one path.

Autodiff (Enzyme) — needed for the autodiff tests and for grad/jvp/vjp lowering:

./scripts/provision/install_enzyme.sh
export ENZYME_LIB="$(pwd)/.cargo/enzyme/LLVMEnzyme-22.dylib"   # .so on Linux

Apple neural engine primitives (macOS only)build.rs compiles CoreML primitive models, and invokes bare python3, so coremltools has to be importable from that interpreter:

python3 -m pip install coremltools

Without it the build prints warning: Failed to compile matmul_4x4 with coremlc and continues. Kernels fall back to CPU execution; only accelerator dispatch is unavailable.

CUDA (Linux) — detected automatically when /usr/local/cuda is present. Set VX_DISABLE_CUDA=1 to force it off. The toolkit alone is enough to build; a GPU is only needed to run.

Packaging a toolchain

To produce a redistributable tarball from a source build:

./scripts/release/package.sh v0.0.1

That stages the compiler, its runtime library, the standard library and the machine files under dist/, rewrites the linked library paths so the binaries find their own dependencies, generates the wrapper scripts, and writes a .tar.gz alongside its SHA-256.