Clause
← Toda a documentação

Traduzido do original em inglês · 06042fa · 2026-10-09 · Ler em inglês

Compilação

O clau compila módulos Erlang/OTP 29 através do LLVM para IR verificada, bitcode ou objetos nativos. -o/--output liga as entradas posicionais (ou um alvo de projeto selecionado), o respetivo objeto de arranque de entrada e o runtime num executável (ligação); as compilações de projetos ligam os alvos executáveis às saídas do seu manifesto (projetos). Os objetos emitidos também podem correr através de um harness C++ ligado ao runtime (ver o exemplo abaixo).

Subconjunto de código-fonte aceite

Módulos com nome, com exportações e cláusulas de função ordenadas. As cabeças e as correspondências no corpo aceitam variáveis, _, aliases, nomes repetidos e padrões sobre átomos, inteiros arbitrários, floats finitos, tuplos, listas/strings, maps, bitstrings e records comuns em tuplo. Os corpos são sequências de correspondências, construtores, operadores/guard BIFs verificados, erlang:display/1 (impressão), halt/0,1 (código de saída), os que lançam exceções error/1,2,3, exit/1, throw/1 e erlang:raise/3 (ABI), os restantes builtins da ponte (erlang:function_exported/3) e funs de builtins, case/if, catch Expr, try ... of ... catch Class:Reason:Stack ... after com rastreios de pilha, maybe ... else ... end, comprehensions de lista, binary e map (padrões) e chamadas diretas locais ou remotas literais dentro do lote, incluindo recursão própria, mútua e entre módulos sobre frames de processo explícitos com chamadas de cauda próprias (modelo de execução); a recursão no corpo é limitada pela pilha do processo (sem limite por omissão), não pela pilha nativa. As guards suportam todo o catálogo admitido. Ver padrões, guards e termos.

Os valores de função fun F/A, fun M:F/A, as funs anónimas e com nome com variáveis capturadas, as chamadas de funs e as chamadas dinâmicas (M:F(...), apply/2,3) correm (funs). São rejeitados com diagnósticos, mesmo em funções não usadas: receive, funs de builtins, processos e troca de mensagens. Atributos aceites: module, export, file, record em tuplo e nativo, export_record, import_record, formas de type/spec, doc/moduledoc, author, vsn, copyright, deprecated, -compile com {no_auto_import, ...} ou opções nowarn_* que só afetam avisos (por exemplo nowarn_deprecated_catch) e -import das guard BIFs de erlang. Os restantes atributos (on_load, parse transforms, outras opções de compile, módulos parametrizados) são rejeitados. Os códigos-fonte que começam por #! seguem as regras de escript (módulo implícito e exportação de main/1, -mode aceite). As formas type/spec são analisadas, mas nunca alteram o código gerado. Os modos só de sintaxe (--parse-check, --print-ast, --print-source, ...) aceitam a gramática completa.

Correr o exemplo de módulos compilados

client:main/1 faz do exemplo um programa:

./build/debug/bin/clau -O2 -o build/demo examples/compile/answer.erl examples/compile/client.erl
./build/demo     # prints 42, -7 and {record,map,binary,list,integer,other}

Os mesmos módulos também correm através de um harness C++. A partir de uma Developer PowerShell do Windows x64 com o compilador compilado:

$tool = './build/debug/bin/clau.exe'
& $tool -O0 --emit obj --artifact-dir build/example-aot examples/compile/answer.erl examples/compile/client.erl
cmake -S examples/compile -B build/example-native -G Ninja -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=Debug "-DGENERATED_DIR:PATH=$((Resolve-Path build/example-aot).Path)"
cmake --build build/example-native
./build/example-native/bin/Debug/compiled_modules.exe

Imprime 42, -7, record, map, binary, list, integer, other, um por linha. O harness regista os módulos explicitamente, cria um contexto e descodifica os resultados; é um anfitrião de exemplo, não um ponto de entrada de produção. Em Unix, use-se build/debug/bin/clau, clang++ e -DGENERATED_DIR="$PWD/build/example-aot" (as execuções nativas aí ainda não estão validadas).

Outras ações sobre os mesmos códigos-fonte:

& $tool -O2 --emit llvm-ir --artifact-dir build/example-ir examples/compile/answer.erl examples/compile/client.erl
& $tool --print-types --verbose examples/compile/answer.erl examples/compile/client.erl
& $tool --print-ir --print-optimized-ir examples/compile/answer.erl examples/compile/client.erl
& $tool -O2 --no-type-specialization --verbose examples/compile/answer.erl examples/compile/client.erl

Impressão do código-fonte

--print-source (uma ação do frontend, como --print-ast) imprime cada módulo analisado como código-fonte Erlang; --print-types imprime o mesmo texto com anotações de tipos. O impressor (print_source, expression_source, type_source em printing.hpp; compiler/src/printing/source_*) é reutilizável:

Opções

OpçãoComportamento
--emit obj|llvm-ir|llvm-bcPublica um artefacto por módulo
--artifact-dir DIRRaiz dos artefactos (requer --emit)
-o PATH / --output PATHLiga um executável (ligação); incompatível com --emit
--linker PATH, --runtime-library PATHDriver do Clang e arquivo do runtime para -o
--entry MODULE[:FUNCTION]Função de entrada/1 do executável; validada em todos os modos de compilação e acrescenta o artefacto de arranque clausev1_start (executáveis)
--target-triple TRIPLEMáquina alvo; --target é a seleção do alvo do projeto
-O0 / -O2 / -OsCódigo genérico por omissão + LLVM O0 / especialização limitada + LLVM O2 / LLVM Os, sem especialização, uma secção por símbolo e eliminação pelo linker do código e dos dados não referenciados
--no-type-specializationDesativa as variantes independentemente da ordem das opções
--print-ir / --print-optimized-irIR verificada antes/depois das passagens do LLVM, com as linhas do código-fonte Erlang como comentários
--print-typesCada módulo como código-fonte Erlang anotado com os tipos inferidos (análise semântica); para antes do LLVM
--verboseEventos das fases [pp], [parse] e [comp] em stderr
--impldebug n[,n...]Saída de depuração dos passos de implementação em stderr (p. ex. 23: resumos de inferência)

Backend

SDK do LLVM

LLVM estável 23.1.x, no mínimo 23.1.1. O LLVM é uma dependência do anfitrião: a arquitetura, a biblioteca padrão de C++ e o CRT do Windows têm de corresponder aos da ferramenta do compilador. O código do projeto mantém exceções/RTTI; nenhuma exceção pode propagar-se através do LLVM. O runtime nunca usa o LLVM.

Configuração de referência em Windows x64 (2026-09-29): clang-cl 23.1.2 do anfitrião em C:/Program Files/LLVM/bin, SDK thirdparty/clang+llvm-23.1.2-x86_64-pc-windows-msvc, ferramentas x64 do Visual Studio 18, Windows SDK 10.0.26100.0, Ninja, /MT, _ITERATOR_DEBUG_LEVEL=0. A seleção automática aplica as definições /MT e do iterador; um LLVM_DIR explícito não o faz, e a sonda de ligação falha nesse caso.

Referência histórica para macOS: llvm 23.1.1_1 do Homebrew (arm64, libLLVM.23.1.dylib partilhada, asserções desativadas) com AppleClang 21.

Outros pré-requisitos: CMake ≥ 3.28, um compilador C++23, Boost ≥ 1.90, toml++ 3.4.0 e as ferramentas de qualidade. O OTP só é necessário para auditorias opcionais e para regenerar fixtures.