Clause
← All documentation

Building Clause

How to build clau and clause_runtime, configure the build, run the tests and use the developer tools. Test design and results are in validation.

Requirements

On macOS (Erlang optional):

xcode-select --install
brew install cmake boost tomlplusplus llvm@23 erlang

Configure and build

cmake --preset debug                    # build/debug, single configuration
cmake --build --preset debug

On Windows, from an x64 developer shell with clang-cl and ninja on PATH:

cmake --preset windows                  # build/windows, Ninja Multi-Config
cmake --build --preset windows-debug
cmake --build --preset windows-release

The debug preset puts clau in build/debug/bin; the windows preset in build/windows/bin/<Config>/clau.exe, with the runtime in build/windows/lib/<Config>/clause_runtime.lib. clau finds the runtime archive and the library/ modules relative to its own location.

Wrappers

Environment overrides: BUILD_DIR, TOOL_BUILD_DIR, BUILD_TYPE, JOBS, CMAKE, CTEST, CMAKE_ARGS, CLANG_FORMAT.

MakefileWindowsDoes
make buildmake-build.batBuild clau in build/tool without tests (the batch script builds Release and the runtime too)
make test, make test-fullmake-test.batConfigure build/debug with tests, build everything, run CTest
make format, make format-allmake-format.batclang-format changed (or, with FORMAT_SCOPE=all, all) C++ files
make benchmarkmake-benchmark.batRelease build in build/bench, then compare with the host OTP
make cleanmake-clean.batRemove build/ and cmake-build*/

The batch scripts enter the Visual Studio x64 environment themselves when needed, add %ProgramFiles%\LLVM\bin to PATH when clang-cl is missing and reconfigure a build directory made by another generator or compiler; set CLAUSE_TOOLCHAIN=default to keep CMake's own choice. clau.bat (Windows) and run-macos.sh build build/tool first, then run clau with all arguments, keeping the caller's working directory and exit code.

Configure options

OptionPurpose
-DBUILD_TESTING=ONBuild tests and their helper programs (default OFF)
-DCLAUSE_BUILD_COMPILER=OFFBuild only the LLVM-free runtime library
-DCLAUSE_BUILD_RUNTIME=OFFBuild only the compiler
-DLLVM_DIR=/prefix/lib/cmake/llvmSelect an LLVM 23.1.x SDK (an invalid explicit path fails)
-DCLAUSE_DOWNLOAD_LLVM=OFFRequire an installed SDK
-DCLAUSE_BOOST_ROOT=..., -DCLAUSE_TOML_ROOT=..., -DCLAUSE_SQLITE_ROOT=..., -DCLAUSE_PCRE2_ROOT=...Select a dependency source or installation (offline setup)
-DCLAUSE_CLANG_EXECUTABLE=C:/path/to/clang.exeSelect the Windows Clang executable
-DCLAUSE_OTP_AUDITS=ON, -DCLAUSE_ESCRIPT=/path/to/escriptEnable optional live OTP audits and select the OTP 29 used
-DCLAUSE_TEST_DEBUG_INFO=ONBuild test programs with debug information (to debug a crash)
-DCLAUSE_OPTIMIZED_COMPILER=OFFBuild clau and the compiler libraries unoptimized in Debug (to debug a clau crash)

Windows notes: the default CRT is /MDd (Debug) or /MD; an explicit CMAKE_MSVC_RUNTIME_LIBRARY must match the LLVM SDK. MSVC cl works in a separate build directory; MinGW is not supported. Project targets treat warnings as errors and include dependencies as SYSTEM headers, so avoid adding dependency paths through global -I flags such as CXXFLAGS (in CLion, clear a cached value with -DCMAKE_CXX_FLAGS:STRING=); use the root options instead.

Tests

cmake --preset debug -DBUILD_TESTING=ON
cmake --build --preset debug
ctest --preset debug-fast                # or windows-debug-fast
ctest --preset debug -j 16               # full mode

CLAUSE_TEST_MODE=fast (the *-fast presets, make test, make-test.bat) runs a reduced optimization/driver matrix and skips full_only tests; full (the default when unset, make test-full, TEST_MODE=full) runs everything. Each test reserves two CTest slots, so -j N runs N/2 tests at once.

Quality gate

Lizard and clang-tidy, pinned in tools/requirements-quality.txt and installed into .venv-quality/ (use .venv-quality/bin/python outside Windows):

python -m venv .venv-quality
.venv-quality/Scripts/python -m pip install -r tools/requirements-quality.txt
cmake --build build/debug --target check-quality       # changed files
cmake --build build/debug --target check-quality-all   # whole tree

check-quality checks files changed since HEAD (or CLAUSE_QUALITY_BASE) plus one translation unit per changed header (check-quality-all covers every dependent) and needs a build with both compiler and runtime enabled; check-complexity-all and check-clang-tidy-all run one tool. cmake/CheckClangTidy.cmake accepts QUALITY_SHARD=K/N to split a long run.

Benchmarks and listings

make benchmark / make-benchmark.bat build a Release clau in build/bench and compare the benchmarks/bench_*.erl programs against the host OTP, and with --baseline REV against another Clause commit; benchmarks/run.py --help lists the options (benchmarks). They are never part of the tests.

benchmarks/compile_times.py times clau itself: it runs a compile workload (--workload W1, or clau arguments after --) several times on the performance cores with --no-cache --print-stage-times, and reports the median, minimum and spread of every phase and inference pass, the slowest inference components, and whether the pass counters and stdout agree between runs. With --baseline <clau.exe> the two builds alternate and the summary shows their ratio. It refuses to time while builds, tests or another clau run, unless given --force-noisy, and writes JSON to build/bench/compile-times/.

decompile-debug.bat <module> and decompile-release.bat <module> write the Debug or Release assembly of one Clause C++ source to <module>.debug.asm / <module>.release.asm, with source lines and demangled names (tools/asm.py, clang-cl builds; --function TEXT filters).