Clause
← Toda la documentación

El original en inglés ha cambiado desde que se hizo esta traducción, por lo que partes de ella pueden estar desactualizadas. Leer en inglés

Traducido del original en inglés · 1e3a39c8-dirty · 2026-10-26

Proyectos TOML

Un manifiesto de proyecto selecciona grupos ordenados de fuentes Erlang y configura cada destino (target) de forma independiente. Todas las acciones de la CLI aceptan proyectos. Véase el ejemplo funcional.

Manifiesto (esquema 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 y selección de destinos

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

Cada destino seleccionado es un lote de compilación independiente con sus propias sesiones de preprocesado. La planificación (decodificar, seleccionar, buscar, comprobar colisiones de salida) termina antes de procesar ningún fuente; después la ejecución procesa los destinos/archivos en orden y retiene los fallos. La salida de contenido va a stdout en orden de destino/archivo sin encabezados (salvo las líneas de destino de --print-inputs); el contexto y los diagnósticos van a stderr. Un destino con diagnósticos se nombra una sola vez, en una línea <manifest> [target <name>]: antes del primero; los propios diagnósticos (error: file:line:col: message) no llevan prefijo de herramienta ni de destino.

./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

Ejecutables

clau --project FILE [--target T]... (sin --emit ni acción de comprobación/impresión) enlaza cada destino seleccionado que tenga una clave output o entry, o al que se dirijan -o/--entry de la CLI, en un ejecutable por destino:

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

Crear un proyecto

--new-project <filename> escribe un manifiesto comentado y nada más.

Directorio de compilación

Cada destino de proyecto tiene un directorio de compilación donde Clause guarda sus propios archivos temporales y sus cachés: el build_dir del destino, relativo al manifiesto, por defecto <manifest-dir>/build. --build-dir DIR (relativo a la invocación) lo sustituye para todos los destinos seleccionados. Las entradas posicionales no tienen ninguno salvo que se indique --build-dir.

Cachés de compilación

Los resultados que merece la pena conservar entre ejecuciones viven bajo <build_dir>/cache; --no-cache ni los lee ni los escribe. Son las respuestas del cargador de parse transforms y la lista de módulos sticky del OTP anfitrión, de modo que una compilación en caliente no arranca ningún erl anfitrión para los módulos cuyas entradas de transformación no han cambiado, el resultado de compilación de cada lote y los resultados de inferencia de los módulos de los directorios configurados.

Caché de inferencia

Los módulos de biblioteca (los fuentes de stdlib, kernel, compiler y syntax_tools de OTP encontrados a través de source_search_paths, y la biblioteca propia de Clause) rara vez cambian, por lo que los módulos de los directorios configurados conservan sus resultados de inferencia de tipos en la caché de compilación, por módulo, y las compilaciones posteriores los reutilizan en lugar de volver a inferirlos.

Rutas y búsqueda

Índice de directorios

Las búsquedas por nombre no prueban cada directorio candidato. Un único índice por invocación de clau, compartido por todos los destinos, guarda los nombres de las entradas de cada directorio explorado: se enumera una vez, de forma no recursiva, cuando una búsqueda lo necesita por primera vez, o lo registran los recorridos recursivos que expanden ** en sources, source_dirs, source_search_paths, include_dirs y transform_paths, de modo que ningún directorio se enumera dos veces. Responde a los fallos de la búsqueda de módulos (la biblioteca y después source_search_paths), a los fuentes de transformaciones, a los sources literales encontrados a través de source_search_paths y a la resolución de includes (el directorio del archivo que incluye, el directorio de trabajo, los directorios de inclusión en orden y después las aplicaciones de include_lib); un candidato que contiene el índice se sigue abriendo o comprobando como antes, por lo que la precedencia, ignore_dirs y los informes de error no cambian. Los nombres de include con partes de directorio (sub/x.hrl) se buscan en el directorio que nombran; los nombres con pasos .., los nombres absolutos, los directorios relativos y las enumeraciones que fallan se prueban como antes.

Fuentes ignorados

ignore_dirs e ignore_modules mantienen fuentes fuera de un destino sin quitarlos del árbol, por ejemplo pruebas incluidas de terceros, código heredado o módulos que solo importan con OTP. Un fuente ignorado se omite en silencio: nunca se lee, analiza, compila ni enlaza, por lo que puede incluso contener errores de sintaxis.

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

Opciones efectivas

AjusteCombinación de manifiesto y CLI
include_dirsOrden del manifiesto, después de -I de la CLI (el último -I de la CLI se busca primero); una entrada con comodines (deps/*/include, apps/**/include) se expande en su sitio a los directorios existentes con los que encaja, ordenados por los bytes UTF-8 de la ruta (** también encaja con ninguno, los enlaces simbólicos a directorios se omiten); un patrón sin coincidencias es un error
source_search_pathsRaíces de reserva para los fuentes literales y para los módulos que el destino nombra pero no enumera; los patrones se expanden como en include_dirs (sin coincidencias: unmatched source search path pattern)
definesPrimero el manifiesto, después la CLI; los duplicados entre ambos son errores
applicationsMap del manifiesto; las entradas de la CLI reemplazan los nombres coincidentes
Listas de funcionalidadesAjustes del manifiesto, después los cambios ordenados de la CLI; prevalece la CLI
outputPor destino, solo destinos ejecutables; -o de la CLI lo sustituye para un único destino seleccionado
entryPor destino; --entry de la CLI lo sustituye para un único destino seleccionado
cache_inference_in_dirsPatrones implícitos de OTP, después los del manifiesto y después --cache-inference-in-dirs de la CLI (caché de inferencia)

Dependencia de compilación

toml++ 3.4.0 (MIT), privado del compilador, solo cabeceras, con excepciones y con la sintaxis no publicada desactivada. SHA-256 del archivo 8517f65938a4faae9ccf8ebb36631a38c1cadfb5efa85d9a72e15b9e97d25155.

La caché de compilación usa la amalgamación de SQLite 3.54.0 (dominio público), compilada solo en la biblioteca de caché del compilador (clause_sqlite, sin los flags de advertencias del proyecto). CMake descarga https://www.sqlite.org/2026/sqlite-amalgamation-3540000.zip en thirdparty/ en todos los anfitriones y verifica su SHA-256 68e913b0fe8ec6b4e5f391c594a28872884e80d6cd042a1e50c957be46b5aa4d; -DCLAUSE_SQLITE_ROOT=<directory with sqlite3.c and sqlite3.h> tiene prioridad y desactiva la descarga.

Límites

Tamaño del manifiesto 1 MiB; como máximo 1.024 destinos y 100.000 nodos TOML. Cada expansión de fuentes permite 100.000 entradas visitadas, 128 niveles de directorio y 16.000.000 de transiciones de comodines. El agotamiento es un error explícito; son límites de trabajo, no plazos de E/S.