Clause
← Toda a documentação

O original em inglês mudou desde esta tradução, pelo que partes dela podem estar desatualizadas. Ler em inglês

Traduzido do original em inglês · 1e3a39c8-dirty · 2026-10-26

Projetos TOML

Um manifesto de projeto seleciona grupos ordenados de códigos-fonte Erlang e configura cada alvo de forma independente. Todas as ações da CLI aceitam projetos. Ver o exemplo funcional.

Manifesto (schema 1)

schema_version = 1

[[targets]]
name = "app"
sources = ["main.erl", "src/workers/*.erl", "shared/**/*.erl"]
source_dirs = ["src/support"]
output = "build/app"
entry = "main:main"
build_dir = "build"

[targets.options]
source_search_paths = ["src", "generated"]
include_dirs = ["include", "vendor/include"]
defines = ["DEBUG", "LIMIT=100", 'LABEL="demo"']
enable_features = ["maybe_expr"]
disable_features = ["compr_assign"]
ignore_dirs = ["src/legacy", "deps/*/test"]
ignore_modules = ["telemetry", "*_SUITE"]
keep_exports = false
shell = false
cache_inference_in_dirs = ["deps/*"]

[targets.options.applications]
my_dependency = "vendor/my_dependency"

CLI e seleção de alvos

clau [options] <source.erl>...
clau [options] --project <path> [--target <name>]...
clau --new-project <filename>

Cada alvo selecionado é um lote de compilação separado, com as suas próprias sessões de pré-processamento. O planeamento (descodificar, selecionar, descobrir, verificar colisões de saídas) termina antes de qualquer código-fonte ser processado; a execução processa então os alvos/ficheiros por ordem e regista as falhas. A saída útil vai para stdout pela ordem alvo/ficheiro, sem cabeçalhos (exceto as linhas de alvo de --print-inputs); o contexto e os diagnósticos vão para stderr. Um alvo com diagnósticos é nomeado uma vez, numa linha <manifest> [target <name>]: antes do primeiro; os próprios diagnósticos (error: file:line:col: message) não levam prefixo de ferramenta nem de alvo.

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

Executáveis

clau --project FILE [--target T]... (sem --emit, sem ação de verificação/impressão) liga cada alvo selecionado que tenha uma chave output ou entry, ou ao qual se dirijam -o/--entry da CLI, num executável por alvo:

./build/debug/bin/clau --project tests/fixtures/linking/project/project.toml

Criar um projeto

--new-project <filename> escreve um manifesto anotado e nada mais.

Diretório de compilação

Cada alvo de projeto tem um diretório de compilação onde o Clause guarda os seus próprios ficheiros temporários e as suas caches: o build_dir do alvo, relativo ao manifesto, por omissão <manifest-dir>/build. --build-dir DIR (relativo à invocação) substitui-o para todos os alvos selecionados. As entradas posicionais não têm nenhum, a não ser que seja dado --build-dir.

Caches de compilação

Os resultados que vale a pena manter entre execuções vivem abaixo de <build_dir>/cache; --no-cache não os lê nem os escreve. São as respostas do carregador de parse transforms e a lista de módulos sticky do OTP anfitrião, para que uma compilação com cache quente não arranque nenhum erl anfitrião para módulos cujas entradas de transformação não mudaram, o resultado da compilação de cada lote e os resultados de inferência dos módulos em diretórios configurados.

Cache de inferência

Os módulos de biblioteca (os códigos-fonte de stdlib, kernel, compiler e syntax_tools do OTP encontrados através de source_search_paths, a própria biblioteca do Clause) raramente mudam, pelo que os módulos em diretórios configurados guardam os seus resultados de inferência de tipos na cache de compilação, por módulo, e as compilações seguintes reutilizam-nos em vez de os inferirem de novo.

Caminhos e descoberta

Índice de diretórios

As pesquisas por nome não sondam todos os diretórios candidatos. Um índice por invocação do clau, partilhado por todos os alvos, guarda os nomes das entradas de cada diretório pesquisado: listados uma vez, sem recursão, quando uma pesquisa precisa deles pela primeira vez, ou registados pelos percursos recursivos que expandem ** em sources, source_dirs, source_search_paths, include_dirs e transform_paths, para que nenhum diretório seja listado duas vezes. Responde às falhas da pesquisa de módulos (a biblioteca, depois source_search_paths), aos códigos-fonte de transformações, aos sources literais encontrados através de source_search_paths e à resolução de includes (o diretório do ficheiro que inclui, o diretório de trabalho, os diretórios de inclusão por ordem, depois as aplicações de include_lib); um candidato que o índice contém continua a ser aberto ou verificado como antes, pelo que a precedência, ignore_dirs e os relatórios de erros não mudam. Os nomes de include com partes de diretório (sub/x.hrl) são procurados no diretório que nomeiam; os nomes com passos .., os nomes absolutos, os diretórios relativos e as listagens que falham são sondados como antes.

Códigos-fonte ignorados

ignore_dirs e ignore_modules mantêm códigos-fonte fora de um alvo sem os remover da árvore, por exemplo testes de dependências incluídas, código legado ou módulos que só importam sob o OTP. Um código-fonte ignorado é saltado silenciosamente: nunca é lido, analisado, compilado ou ligado, pelo que pode até conter erros de sintaxe.

[targets.options]
source_search_paths = ["deps/**"]
ignore_dirs = ["deps/*/test", "src/legacy"]
ignore_modules = ["telemetry", "*_SUITE"]

Opções efetivas

DefiniçãoCombinação do manifesto e da CLI
include_dirsOrdem do manifesto, depois dos -I da CLI (o último -I da CLI é pesquisado primeiro); uma entrada com curingas (deps/*/include, apps/**/include) expande-se no lugar para os diretórios existentes a que corresponde, ordenados pelos bytes UTF-8 do caminho (** também corresponde a nenhum, as ligações simbólicas a diretórios são saltadas); um padrão sem correspondência é um erro
source_search_pathsRaízes de recurso para códigos-fonte literais e para os módulos que o alvo nomeia mas não lista; os padrões expandem-se como em include_dirs (sem correspondência: unmatched source search path pattern)
definesPrimeiro o manifesto, depois a CLI; duplicados entre ambos são erros
applicationsMap do manifesto; as entradas da CLI substituem os nomes correspondentes
Listas de featuresDefinições do manifesto, depois as alterações ordenadas da CLI; a CLI prevalece
outputPor alvo, apenas alvos executáveis; -o da CLI substitui-o para um único alvo selecionado
entryPor alvo; --entry da CLI substitui-o para um único alvo selecionado
cache_inference_in_dirsPadrões OTP implícitos, depois os do manifesto, depois --cache-inference-in-dirs da CLI (cache de inferência)

Dependência de compilação

toml++ 3.4.0 (MIT), privado do compilador, apenas cabeçalhos com exceções, sintaxe não publicada desativada. SHA-256 do arquivo 8517f65938a4faae9ccf8ebb36631a38c1cadfb5efa85d9a72e15b9e97d25155.

A cache de compilação usa a amalgamação SQLite 3.54.0 (domínio público), compilada apenas na biblioteca de cache do compilador (clause_sqlite, sem as flags de aviso do projeto). O CMake descarrega https://www.sqlite.org/2026/sqlite-amalgamation-3540000.zip para thirdparty/ em todos os anfitriões e verifica o seu SHA-256 68e913b0fe8ec6b4e5f391c594a28872884e80d6cd042a1e50c957be46b5aa4d; -DCLAUSE_SQLITE_ROOT=<directory with sqlite3.c and sqlite3.h> tem precedência e desativa a transferência.

Limites

Tamanho do manifesto 1 MiB; no máximo 1024 alvos e 100 000 nós TOML. Cada expansão de códigos-fonte permite 100 000 entradas visitadas, 128 níveis de diretórios e 16 000 000 de transições de curingas. O esgotamento é um erro explícito; estes são limites de trabalho, não prazos de E/S.