A compiler to convert Cairo's intermediate representation "Sierra" code
to machine code via MLIR and LLVM.
For in-depth documentation, see the developer documentation.
đźš§ Cairo Native is still being built therefore API breaking changes might happen often so use it at your own risk. đźš§
For versions under 1.0 cargo doesn't comply with
semver, so we advise to pin the version you
use. This can be done by adding cairo-native = "0.9.0-rc.0" to your Cargo.toml
- Linux or macOS (aarch64 included) only for now
- LLVM 19 with MLIR: On debian you can use apt.llvm.org, on macOS you can use brew
- Rust 1.78.0 or later, since we make use of the u128 abi change.
- Python 3
- Git
This step applies to all operating systems.
Run the following make target to install the dependencies (both Linux and macOS):
make depsSince Linux distributions change widely, you need to install LLVM 19 via your package manager, compile it or check if the current release has a Linux binary.
If you are on Debian/Ubuntu, check out the repository https://apt.llvm.org/. Then you can install with:
sudo apt-get install llvm-19 llvm-19-dev llvm-19-runtime clang-19 clang-tools-19 lld-19 libpolly-19-dev libmlir-19-dev mlir-19-toolsIf you decide to build from source, here are some indications:
Install LLVM from source instructions
# Go to https://github.com/llvm/llvm-project/releases
# Download the latest LLVM 19 release:
# The blob to download is called llvm-project-19.x.x.src.tar.xz
# For example
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-19.1.7/llvm-project-19.1.7.src.tar.xz
tar xf llvm-project-19.1.5.src.tar.xz
cd llvm-project-19.1.5.src.tar
mkdir build
cd build
# The following cmake command configures the build to be installed to /opt/llvm-19
cmake -G Ninja ../llvm \
-DLLVM_ENABLE_PROJECTS="mlir;clang;clang-tools-extra;lld;polly" \
-DLLVM_BUILD_EXAMPLES=OFF \
-DLLVM_TARGETS_TO_BUILD="Native" \
-DCMAKE_INSTALL_PREFIX=/opt/llvm-19 \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DLLVM_PARALLEL_LINK_JOBS=4 \
-DLLVM_ENABLE_BINDINGS=OFF \
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_ENABLE_LLD=ON \
-DLLVM_ENABLE_ASSERTIONS=OFF
ninja installSetup a environment variable called MLIR_SYS_190_PREFIX, LLVM_SYS_191_PREFIX
and TABLEGEN_190_PREFIX pointing to the llvm directory:
# For Debian/Ubuntu using the repository, the path will be /usr/lib/llvm-19
export MLIR_SYS_190_PREFIX=/usr/lib/llvm-19
export LLVM_SYS_191_PREFIX=/usr/lib/llvm-19
export TABLEGEN_190_PREFIX=/usr/lib/llvm-19Alternatively, if installed from Debian/Ubuntu repository, then you can use
env.sh to automatically setup the environment variables.
source env.shThe makefile deps target (which you should have ran before) installs LLVM 19
with brew for you, afterwards you need to execute the env.sh script to setup
the needed environment variables.
source env.shIf you are using vscode as your code editor, you'll need to add this to you settings.json:
"rust-analyzer.cargo.extraEnv": {
"MLIR_SYS_190_PREFIX": "<path-to-llvm-19>",
"LLVM_SYS_191_PREFIX": "<path-to-llvm-19>",
"TABLEGEN_190_PREFIX": "<path-to-llvm-19>",
}if you are on MacOs, you'll need to add this extra line:
"LIBRARY_PATH": "/opt/homebrew/lib",Without this additional config, rust-analyzer won't be able to work properly
Running make by itself will check whether the required LLVM installation and
corelib is found, and then list available targets.
% make
LLVM is correctly set at /opt/homebrew/opt/llvm.
./scripts/check-corelib-version.sh 2.12.3
Usage:
deps: Installs the necesary dependencies.
build: Builds the cairo-native library and binaries in release mode.
build-native: Builds cairo-native with the target-cpu=native rust flag.
build-dev: Builds cairo-native under a development-optimized profile.
check: Checks format and lints.
test: Runs all tests.
proptest: Runs property tests.
coverage: Runs all tests and computes test coverage.
doc: Builds documentation.
doc-open: Builds and opens documentation in browser.
bench: Runs the hyperfine benchmark script.
bench-ci: Runs the criterion benchmarks for CI.
install: Invokes cargo to install the cairo-native tools.
clean: Cleans the built artifacts.
stress-test Runs a command which runs stress tests.
stress-plot Plots the results of the stress test command.
stress-clean Clean the cache of AOT compiled code of the stress test command.Aside from the compilation and execution engine library, Cairo Native includes a few command-line tools to aid development, and some useful scripts.
These are:
- The contents of the
/scripts/folder cairo-native-compilecairo-native-dumpcairo-native-runcairo-native-testcairo-native-stressscarb-native-dumpscarb-native-test
Compiles Cairo/Sierra to Native machine code.
Outputs the generated MLIR, and the final shared library.
Usage: cairo-native-compile [OPTIONS] <PATH> [OUTPUT_MLIR] [OUTPUT_LIBRARY]
Arguments:
<PATH> The input path to compile. By default, it is intrepreted as a Cairo project
[OUTPUT_MLIR] The output path for the generated MLIR [default: out.mlir]
[OUTPUT_LIBRARY] The output path for the shared library [default: out.dylib]
Options:
-s, --single-file Whether path is a single Cairo file
--sierra-json Whether path is a single Sierra JSON file
-O, --opt-level <OPT_LEVEL> Optimization level (Valid: 0, 1, 2, 3). Values higher than 3 are considered as 3 [default: 0]
--stats-path <STATS_PATH> The compilation statistics path
-h, --help Print help (see more with '--help')
-V, --version Print versionUsage: cairo-native-dump [OPTIONS] <INPUT>
Arguments:
<INPUT>
Options:
-o, --output <OUTPUT> [default: -]
--starknet Compile a starknet contract
-h, --help Print helpThis tool allows to run programs using cairo-native, similar to the cairo-run
tool.
For example, the following calculates factorial of 1000.
cairo-native-run -- -s programs/recursion.cairo --available-gas 10000000Exits with 1 if the compilation or run fails, otherwise 0.
Usage: cairo-native-run [OPTIONS] <PATH>
Arguments:
<PATH> The Cairo project path to compile and run its tests
Options:
-s, --single-file Whether path is a single file
--allow-warnings Allows the compilation to succeed with warnings
--available-gas <AVAILABLE_GAS> In cases where gas is available, the amount of provided gas
--run-mode <RUN_MODE> Run with JIT or AOT (compiled) [default: jit] [possible values: aot, jit]
-O, --opt-level <OPT_LEVEL> Optimization level, Valid: 0, 1, 2, 3. Values higher than 3 are considered as 3 [default: 0]
-h, --help Print help
-V, --version Print versionThis tool mimics the cairo-test
tool
and is identical to it in interface. The only feature it doesn't have is the
profiler.
Compiles a Cairo project and runs all the functions marked as `#[test]`.
Exits with 1 if the compilation or run fails, otherwise 0.
Usage: cairo-native-test [OPTIONS] <PATH>
Arguments:
<PATH> The Cairo project path to compile and run its tests
Options:
-s, --single-file Whether path is a single file
--allow-warnings Allows the compilation to succeed with warnings
-f, --filter <FILTER> The filter for the tests, running only tests containing the filter string [default: ]
--include-ignored Should we run ignored tests as well
--ignored Should we run only the ignored tests
--starknet Should we add the starknet plugin to run the tests
-O, --opt-level <OPT_LEVEL> Optimization level, Valid: 0, 1, 2, 3. Values higher than 3 are considered as 3 [default: 0]
--compare-with-cairo-vm Compares test result with Cairo VM
-h, --help Print help
-V, --version Print versionFor single files, you can use the -s, --single-file option. For a project, it
needs to have a cairo_project.toml specifying the crate_roots.
For example, the following tests the corelib.
cairo-native-test ./corelib/This tool runs a stress test on Cairo Native.
A stress tester for Cairo Native
Usage: cairo-native-stress [OPTIONS] <ROUNDS>
Arguments:
<ROUNDS> Amount of rounds to execute
Options:
-o, --output <OUTPUT> Output file for JSON formatted logs
-h, --help Print help (see more with '--help')To quickly run a stress test and save logs as json, run:
make stress-testThis takes a lot of time to finish (it will probably crash first), you can kill the program at any time.
To plot the results, run:
make stress-plotTo clear the cache directory, run:
make stress-cleanThis tool mimics the scarb build
command.
This tool should be run at the directory where a Scarb.toml file is and it
will behave like scarb build, leaving the MLIR files under the target/
folder besides the generated JSON sierra files.
For example, the following compiles the alexandria project:
cd tests/alexandria
scarb-native-dump
file target/dev/alexandria.mlirThis tool mimics the scarb test
command.
Compiles all packages from a Scarb project matching `packages_filter` and
runs all functions marked with `#[test]`. Exits with 1 if the compilation
or run fails, otherwise 0.
Usage: scarb-native-test [OPTIONS]
Options:
-p, --package <SPEC> Packages to run this command on, can be a concrete package name (`foobar`) or a prefix glob (`foo*`) [env: SCARB_PACKAGES_FILTER=] [default: *]
-w, --workspace Run for all packages in the workspace
-f, --filter <FILTER> Run only tests whose name contain FILTER [default: ]
--include-ignored Run ignored and not ignored tests
--ignored Run only ignored tests
-t, --test-kind <TEST_KIND> Choose test kind to run [possible values: unit, integration, all]
-O, --opt-level <OPT_LEVEL> Optimization level, Valid: 0, 1, 2, 3. Values higher than 3 are considered as 3 [default: 0]
--compare-with-cairo-vm Compares test result with Cairo VM
-h, --help Print help
-V, --version Print versionIn addition to the general requirements, you need:
- hyperfine:
cargo install hyperfine
You can then run the bench makefile target:
make benchThe bench target will run the ./scripts/bench-hyperfine.sh script. This
script runs hyperfine commands to compare the execution time of programs in
the ./programs/benches/ folder. Each program is compiled and executed via the
execution engine with the cairo-native-run command and via the cairo-vm with
the cairo-run command provided by the deps Makefile target.
This project is dual-licensed under Apache 2.0 and MIT. You may choose either license.
See Apache 2.0 License or MIT License for more information.