Clause
← All documentation

Using the compiler

./build/debug/bin/clau --parse-check examples/project/src/main.erl
./build/debug/bin/clau --print-pp -I include -DDEBUG examples/project/src/main.erl
./build/debug/bin/clau --print-ast examples/project/src/main.erl

On macOS, ./run-macos.sh --parse-check examples/project/src/main.erl builds first and runs the latest executable, passing all arguments unchanged. It accepts BUILD_DIR, BUILD_TYPE and JOBS environment overrides.

clau [options] <source.erl>...
  --project <path>        Read a TOML project instead of positional sources
  --target <name>         Select a target; repeat for more (default: all)
  --new-project <filename>  Create an annotated starter; append .toml when needed
  --preprocess-check       Check preprocessing only
  --parse-check            Preprocess and check syntax
  --print-pp               Print expanded Erlang source
  --print-ast              Print an indented syntax tree
  --print-source           Print each module as Erlang source
  --print-types            Print each module as source annotated with inferred types
  --print-ir               Print verified IR with Erlang source comments before LLVM optimization
  --print-optimized-ir     Print verified IR with Erlang source comments after LLVM optimization
  --emit obj|llvm-ir|llvm-bc  Write one artifact per module
  --artifact-dir <dir>     Override the artifact root (requires --emit)
  --target-triple <triple>  Select the machine/OS/ABI
  -O0 / -O2 / -Os         Generic O0 (default) / speed / size optimization
  --no-type-specialization  Disable compiler variants at either optimization level
  --verbose               Trace files and compilation phases to stderr
  --impldebug <n[,n...]>   Enable debug output for selected implementation steps
  -I, --include <dir>      Add an include directory (last supplied searched first)
  -D, --define <name[=term]>  Define a macro (default value: true)
  --app-dir <app=dir>      Set an include_lib application directory
  --enable-feature <name>  Enable a language feature
  --disable-feature <name> Disable a language feature
  -h, --help              Show all options
  --version               Show version
  --                      Treat remaining arguments as input paths

Quote paths containing spaces and macro values containing shell punctuation:

./build/debug/bin/clau --parse-check -I include '-DVERSION={1,0}' \
  --app-dir myapp=examples/project examples/project/src/main.erl

Check modes are silent on success; diagnostics go to stderr. Print modes write to stdout and can be combined: --print-pp --print-ast prints source before the tree for each input. Adding --preprocess-check does not disable parsing requested by --parse-check or --print-ast. Errors may leave partial printed output.

With no check/print action, source inputs and --project run the complete pipeline through verified native object buffers in memory. Positional inputs form one batch; each project target forms its own batch. --emit writes artifacts under build/aot or --artifact-dir; projects append an encoded target name and use a manifest-relative default root. Filenames encode module identity. -o PATH links positional inputs, or one selected project target, into an executable with Clang and the runtime library (entry: --entry MODULE[:FUNCTION], manifest entry, or the only module exporting main/1). Without -o, project targets with an output or entry key link to their TOML output (default build/<target>), publishing only after every selected target linked. See executables for the entry, argument and exit-status contract.

clau -O2 -o demo answer.erl client.erl && ./demo
clau -O2 --emit obj answer.erl client.erl
clau --print-ir --print-optimized-ir -O2 answer.erl
clau --print-types answer.erl client.erl

IR inspection allows both stages together and stops before object emission. Multiple snapshots are separate modules; use --emit llvm-ir for individual assembly files. Type inspection stops before LLVM and prints each module as source with inferred function signatures and Expression :: Type annotations. It accepts preprocessing/project/verbosity options, but rejects other actions, output destinations and backend policy. See compilation options.

--verbose prints [pp] <filename> for source files and resolved preprocessor includes, and [parse] <filename> when each source enters the parser. Nested and library includes are traced as they are loaded; inactive includes are skipped. The parser consumes expanded tokens incrementally, so its trace can precede include traces. [comp] adds semantic/backend phases and bounded specialization decisions as they start. Tracing goes to stderr in every mode, including projects.

--impldebug 23 or --impldebug 23,24,27 selects optional implementation-step debug output independently of --verbose. Repeated options combine their selections; duplicates are ignored. Values are signed 32-bit decimal integers, with optional +/- signs and no spaces or empty list members. Steps 23–27 print inferred function inputs/results and parameter relations to stderr with the selected step prefix (for example, [impldebug 27]). These are analyzed lowering inputs, not an IR dump. Future steps can check their own number; selecting a step without debug output has no effect. The same selection applies to positional inputs and every selected project target. Frontend-only check/print actions do not run inference.

Exit codes: 0 for success (including warnings), 1 for source/project errors, 2 for usage errors or unknown target names. Each input has independent preprocessing state; any source error makes the overall command fail.

Syntax checks do not validate semantics or execute parse transforms. Check/print modes do not create output files and reject -o/--output. Default compilation without -o writes no executable.

See preprocessing, parser usage and validation status for further details.

Projects

Run the included two-target example:

./build/debug/bin/clau --parse-check --project examples/project/project.toml
./build/debug/bin/clau --print-ast --project examples/project/project.toml --target app
./build/debug/bin/clau --preprocess-check --project examples/project/project.toml --target tests --target app

Create an annotated project in an existing directory:

mkdir -p build/project-demo
./build/debug/bin/clau --new-project build/project-demo/demo
mkdir -p build/project-demo/src
cp examples/project/src/main.erl build/project-demo/src/main.erl
./build/debug/bin/clau --parse-check --project build/project-demo/demo.toml

Creation writes only the requested TOML file and refuses existing destinations. The starter contains one app target using src, with all frontend options at their defaults. Add source files before checking it.

Manifest paths are relative to the TOML file; CLI paths are relative to the invocation directory. All targets run by default. Repeat --target to choose an ordered subset; repeat selections run once. sources supports literal filenames and *, ?, ** patterns; source_dirs recursively discovers .erl files. Source search paths only locate explicitly listed files. CLI include paths take precedence, CLI application roots replace matching names, CLI feature settings apply last, and duplicate macro definitions remain errors.

See project format and workflows. Projects support every CLI action; executable generation remains unimplemented.

The admitted guard catalog includes checked is_integer/3, qualified calls and top-level legacy tests; process/node and native record identities retain explicit capability diagnostics.