Clause
← Toute la documentation

Traduit de l'original anglais · 06042fa · 2026-10-09 · Lire en anglais

Compilation

clau compile des modules Erlang/OTP 29 via LLVM en IR vérifié, en bitcode ou en objets natifs. -o/--output lie les entrées positionnelles (ou une cible de projet sélectionnée), leur objet de démarrage d'entrée et le runtime en un exécutable (édition de liens) ; les compilations de projet lient les cibles exécutables vers les sorties de leur manifeste (projets). Les objets émis peuvent aussi s'exécuter via un harnais C++ lié au runtime (voir l'exemple ci-dessous).

Sous-ensemble de source accepté

Modules nommés avec exports et clauses de fonction ordonnées. Les têtes et les correspondances dans les corps acceptent les variables, _, les alias, les noms répétés et les motifs sur atomes, entiers arbitraires, flottants finis, tuples, listes/chaînes, maps, bitstrings et records ordinaires sous forme de tuples. Les corps sont des séquences de correspondances, constructeurs, opérateurs/BIF de garde vérifiés, erlang:display/1 (affichage), halt/0,1 (code de sortie), les fonctions qui lèvent error/1,2,3, exit/1, throw/1 et erlang:raise/3 (ABI), les autres builtins du pont (erlang:function_exported/3) et les funs de builtins, case/if, catch Expr, try ... of ... catch Class:Reason:Stack ... after avec traces de pile, maybe ... else ... end, les comprehensions de liste, de binary et de map (motifs) et les appels directs locaux ou distants littéraux au sein du lot, y compris la récursion sur soi, mutuelle et entre modules sur des cadres de processus explicites avec de vrais appels terminaux (modèle d'exécution) ; la récursion non terminale est bornée par la pile du processus (sans plafond par défaut), non par la pile native. Les gardes prennent en charge tout le catalogue admis. Voir motifs, gardes et termes.

Les valeurs fonctionnelles fun F/A, fun M:F/A, les funs anonymes et nommées avec variables capturées, les appels de funs et les appels dynamiques (M:F(...), apply/2,3) s'exécutent (funs). Rejetés avec diagnostics, même dans les fonctions inutilisées : receive, funs de builtins, processus et messagerie. Attributs acceptés : module, export, file, record tuple et natif, export_record, import_record, formes type/spec, doc/moduledoc, author, vsn, copyright, deprecated, -compile avec {no_auto_import, ...} ou des options nowarn_* qui ne concernent que les avertissements (par exemple nowarn_deprecated_catch) et -import des BIF de garde d'erlang. Les autres attributs (on_load, parse transforms, autres options compile, modules paramétrés) sont rejetés. Les sources commençant par #! suivent les règles des escripts (module implicite et export de main/1, -mode accepté). Les formes type/spec sont analysées mais ne modifient jamais le code généré. Les modes purement syntaxiques (--parse-check, --print-ast, --print-source, ...) acceptent la grammaire complète.

Exécuter l'exemple de module compilé

client:main/1 fait de l'exemple un programme :

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

Les mêmes modules s'exécutent aussi via un harnais C++. Depuis un Developer PowerShell Windows x64 avec le compilateur construit :

$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

Il affiche 42, -7, record, map, binary, list, integer, other, un par ligne. Le harnais enregistre explicitement les modules, crée un contexte et décode les résultats ; c'est un hôte d'exemple, pas un point d'entrée de production. Sous Unix, utiliser build/debug/bin/clau, clang++ et -DGENERATED_DIR="$PWD/build/example-aot" (les exécutions natives n'y sont pas encore validées).

Autres actions sur les mêmes sources :

& $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

Affichage du source

--print-source (une action du frontend, comme --print-ast) affiche chaque module analysé sous forme de source Erlang ; --print-types affiche le même texte avec des annotations de type. L'afficheur (print_source, expression_source, type_source dans printing.hpp ; compiler/src/printing/source_*) est réutilisable :

Options

OptionComportement
--emit obj|llvm-ir|llvm-bcPublie un artefact par module
--artifact-dir DIRRacine des artefacts (exige --emit)
-o PATH / --output PATHLie un exécutable (édition de liens) ; incompatible avec --emit
--linker PATH, --runtime-library PATHPilote Clang et archive du runtime pour -o
--entry MODULE[:FUNCTION]Fonction d'entrée/1 de l'exécutable ; validée dans tous les modes de compilation et ajoute l'artefact de démarrage clausev1_start (exécutables)
--target-triple TRIPLEMachine cible ; --target sert à sélectionner une cible de projet
-O0 / -O2 / -OsCode générique par défaut + LLVM O0 / spécialisation bornée + LLVM O2 / LLVM Os, sans spécialisation, une section par symbole et élimination par l'éditeur de liens du code et des données non référencés
--no-type-specializationDésactive les variantes quel que soit l'ordre des options
--print-ir / --print-optimized-irIR vérifié avant/après les passes LLVM, avec les lignes du source Erlang en commentaires
--print-typesChaque module sous forme de source Erlang annoté des types inférés (sémantique) ; s'arrête avant LLVM
--verboseÉvénements de phase [pp], [parse] et [comp] sur stderr
--impldebug n[,n...]Sortie de débogage par étape d'implémentation sur stderr (par ex. 23 : résumés d'inférence)

Backend

SDK LLVM

LLVM stable 23.1.x, au minimum 23.1.1. LLVM est une dépendance de l'hôte : l'architecture, la bibliothèque standard C++ et le CRT Windows doivent correspondre à ceux de l'outil de compilation. Le code du projet conserve les exceptions/RTTI ; aucune exception ne doit traverser LLVM lors du déroulement de la pile. Le runtime n'utilise jamais LLVM.

Configuration Windows x64 de référence (2026-09-29) : clang-cl 23.1.2 de l'hôte dans C:/Program Files/LLVM/bin, SDK thirdparty/clang+llvm-23.1.2-x86_64-pc-windows-msvc, outils Visual Studio 18 x64, Windows SDK 10.0.26100.0, Ninja, /MT, _ITERATOR_DEBUG_LEVEL=0. La sélection automatique applique /MT et les réglages d'itérateur ; un LLVM_DIR explicite ne le fait pas, et la sonde d'édition de liens échoue alors.

Référence macOS historique : llvm 23.1.1_1 de Homebrew (arm64, libLLVM.23.1.dylib partagée, assertions désactivées) avec AppleClang 21.

Autres prérequis : CMake ≥ 3.28, un compilateur C++23, Boost ≥ 1.90, toml++ 3.4.0 et les outils de qualité. OTP n'est nécessaire que pour les audits optionnels et la régénération des fixtures.