Clause
← Toute la documentation

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

Exécutables

Contrat des programmes construits par clau -o ou par un build de projet. Les entrées positionnelles, ou exactement une cible de projet sélectionnée, sont liées dans le chemin -o ; un build de projet lie chaque cible exécutable sélectionnée à son output du manifeste (édition de liens, projets).

Choix du point d'entrée

Le point d'entrée est une fonction exportée d'arité 1 qui reçoit la liste des arguments.

SourceÉcriturePortée
CLI--entry MODULE[:FUNCTION]Lot positionnel, ou l'unique cible de projet sélectionnée
Manifesteentry = "MODULE[:FUNCTION]" dans une table [[targets]]Cette cible
Par défautL'unique escript, sinon l'unique module exportant main/1Seulement lorsqu'un exécutable est demandé (-o, ou une cible de projet avec output)
ÉchecDiagnostic (code de sortie 1)
Module absent du lot<origin>: entry module M is not among the compiled modules (origine : --entry ou manifeste file:line:col [target t] (entry))
Pas de F/1<file>:<line>:<col>: entry function M:F/1 is not defined à la déclaration du module
Seulement d'autres arités... is not defined; found F/N, but the entry receives one argument (the argument list) à cette définition
F/1 non exportée<file>:<line>:<col>: entry function M:F/1 is not exported à la définition
Pas de sélection, aucun export main/1no entry point: no module exports main/1; choose the entry with --entry MODULE[:FUNCTION] (an exported FUNCTION/1; FUNCTION defaults to main)
Pas de sélection, plusieursambiguous entry point: main/1 is exported by a, b; choose the entry with ... (même indication)

Pour les cibles de projet, l'indication nomme aussi la clé du manifeste : ... --entry MODULE[:FUNCTION] or with entry = "MODULE[:FUNCTION]" in this target's [[targets]] table of the project manifest ..., par exemple :

[[targets]]
name = "app"
sources = ["src/*.erl"]
entry = "app:start"   # calls app:start/1; plain "app" calls app:main/1

Arguments

Entry(Argv) reçoit une liste propre de chaînes (listes de points de code Unicode), à l'exclusion du nom du programme et des options du runtime en tête, sinon inchangées et dans l'ordre, comme escript.

Options du runtime

Le runtime lit ses options dans la variable d'environnement CLAUSE_FLAGS (mots séparés par des espaces et des tabulations, sans guillemets), puis dans les arguments de ligne de commande en tête, de sorte que la ligne de commande l'emporte. Les deux sont analysés de la même façon ; une valeur se place dans l'argument suivant ou après =.

OptionEffet
--max-atoms NTaille de la table des atomes, de 1 à 2^26 (67 108 864) ; 2^20 (1 048 576) par défaut, comme +t d'OTP
--max-heap BYTESPlafond du bloc de tas, des fragments et des binaries hors tas de chaque processus, au moins le tas minimal (233 mots) ; non plafonné par défaut
--max-stack BYTESPlafond de la pile de cadres de chaque processus ; non plafonné par défaut
--max-memory BYTESPlafond de la mémoire de l'ensemble des processus (tas, binaries hors tas, piles) ; non plafonné par défaut
--schedulers NWorkers de l'ordonnanceur exécutant les processus, de 1 à 1 024 ; un par processeur logique par défaut, comme +S d'OTP (workers)
--args-file FILEFichier d'options comme vm.args d'OTP : réservé, rapporte runtime option --args-file is not implemented
--Termine les options du runtime ; les arguments suivants vont tous à Entry

Sur la ligne de commande, l'analyse s'arrête au premier argument qui n'est pas une option du runtime, donc prog data --max-atoms 9 transmet les trois arguments au programme. Dans CLAUSE_FLAGS, chaque mot doit être une option du runtime. Une valeur invalide, un mot de la variable qui n'est pas une option, ou --args-file arrête le programme avant l'enregistrement de tout module : clau: runtime failure: <reason>, code de sortie 70. Le nombre de processus n'est pas limité et la mémoire n'est pas plafonnée par défaut. Les valeurs en octets sont décimales, sans suffixe, et arrondies à l'inférieur en mots entiers ; un programme qui atteint un plafond échoue avec resource_limit, code de sortie 70 (limite mémoire du runtime).

Code de sortie

RésultatCode
Le point d'entrée retourne (n'importe quelle valeur)0
erlang:halt()0
erlang:halt(N), entier non négatifN (les hôtes POSIX gardent les 8 bits de poids faible)
erlang:halt(Slogan) avec une chaîneSlogan sur stderr, puis 1 (pas de crash dump)
erlang:halt(abort)Abandon natif (sans vidage des tampons)
Toute exception qui s'échappe du point d'entrée, y compris throw et exit(normal)Rapport sur stderr, 1
Processus d'entrée terminé par un signal de sortie (processus)Rapporté comme un exit non capturé, 1 ; raison normal : 0
Échec du démarrage du runtime ou de l'infrastructure (incompatibilité d'ABI, enregistrement, mémoire avant le point d'entrée)Message sur stderr, 70
Mémoire de l'hôte épuisée (croissance du tas, d'un binary hors tas ou de la pile refusée ; aucun plafond mémoire par défaut, épuisement de la mémoire)clau: runtime failure: entry call failed: out_of_memory, 70

Des arguments invalides de halt/1 lèvent badarg chez l'appelant. Lorsque le point d'entrée se termine, le programme se termine : les autres processus sont arrêtés sans poursuivre leur exécution, comme avec halt/1 d'OTP après le retour d'escript. Un halt dans n'importe quel processus termine le programme avec son code, et un échec du runtime dans n'importe quel processus le termine avec 70 ; une exception dans un processus créé par spawn ne termine que ce processus (processus).

halt/0,1, error/1,2,3, exit/1 et throw/1 peuvent être appelées avec ou sans le préfixe erlang: ; une définition locale ou -compile({no_auto_import, ...}) garde le nom non qualifié local, comme dans OTP. halt/2 n'est pas disponible. halt(N) garde les 31 bits de poids faible de tout entier non négatif, comme le fait OTP. Un slogan est une liste propre d'au plus 1 023 points de code Unicode. Un halt déroule le point d'entrée à travers le canal d'erreur vérifié comme une erreur, il n'arrête donc le programme qu'après le nettoyage généré.

Flux de sortie

Objet de démarrage

Compiler avec un point d'entrée explicite (--entry ou entry du manifeste) ajoute un module de démarrage après les modules du lot. Avec --emit, il est publié sous le nom clausev1_start.{obj,o,ll,bc} à côté des artefacts des modules (le nom ne peut pas entrer en collision avec un artefact de module). Il contient un abi::v1::StartupDescriptor constant (startup.hpp) : révision de l'ABI, largeur de terme, chaque descripteur de module dans l'ordre des sources, les noms du module et de la fonction d'entrée et un indicateur escript. Son int main(int, char **) appelle CLAUSE_main_v1 du runtime, qui :

  1. Vérifie la révision de l'ABI et la largeur du descripteur de démarrage et de chaque descripteur de module avant tout enregistrement ; une incompatibilité sort avec le code 70.
  2. Démarre le runtime et enregistre tous les modules ; tout échec s'arrête avant le point d'entrée et abandonne le runtime (code de sortie 70), donc aucun code Erlang ne s'exécute sur un lot partiel.
  3. Crée le processus d'entrée, construit argv et met en file l'appel de M:F/1 comme processus principal, puis l'exécute, ainsi que chaque processus qu'il crée, sur l'exécuteur coopératif (processus) jusqu'à sa fin.
  4. Convertit le résultat en code de sortie ci-dessus, en affichant les rapports après le vidage de stdout, puis libère chaque processus et arrête le runtime sur chaque chemin (sauf halt(abort)).

clau -o lie lui-même ces objets (édition de liens). Édition de liens manuelle (la recette du harnais natif sans source de harnais) :

& $tool --emit obj --entry app --artifact-dir build/app app.erl helper.erl
clang-cl /MT build/app/*.obj build/debug/lib/clause_runtime.lib /Fe:app.exe

Toute édition de liens compatible Clang des objets avec Clause::generated_program fonctionne de la même façon (voir tests/compiler/linking/startup.cmake).

Édition de liens

clau [-O0|-O2|-Os] -o PATH a.erl b.erl ... (ou --project FILE [--target T] -o PATH pour une cible sélectionnée) compile le lot en mémoire, ajoute l'objet de démarrage pour le point d'entrée et lie un exécutable :

clau -O2 -o build/demo examples/compile/answer.erl examples/compile/client.erl
./build/demo          # build/demo.exe on Windows

-Os place en outre chaque fonction et objet de données, générés ou du runtime, dans sa propre section et lie avec --gc-sections (ELF), -dead_strip (Mach-O) ou /OPT:REF /OPT:ICF (MSVC), de sorte que le code qu'aucun chemin depuis le point d'entrée n'atteint est supprimé.

Échec (code de sortie 1)Diagnostic
Pas de Clangcannot find clang++ or clang on PATH; install LLVM/Clang or pass --linker / linker not found: X
Pas de runtimeruntime library not found: P; build the clause_runtime target or pass --runtime-library
Pas une archiveruntime library is not a static library: P: ...
Mauvaise cibleruntime library P contains x86_64 coff objects, but the executable targets T; ...
Erreur d'édition de lienslinking O failed: <clang> exited with status N: suivi de la sortie de l'éditeur de liens (64 Kio au plus)
Destination incorrecteoutput directory does not exist: D, artifact destination is not a regular file: O, artifact destination aliases an input: O

Escripts

Un fichier source dont la première ligne commence par #! est compilé comme un escript, dans n'importe quel mode et quel que soit le nom du fichier (entrées positionnelles ou fichiers .erl de projet). Les règles suivent escript d'OTP 29 pour les scripts sources :

Comparaison avec OTP

Les goldens des fixtures de programmes exécutent le point d'entrée sous OTP avec les mêmes règles (oracle) ; le même oracle génère les cas golden d'exécutables que l'exécuteur de bout en bout lie et exécute sous chaque politique. Différences avec escript pour les modules ordinaires : les exceptions non capturées sortent avec 1 au lieu de 127, et main/1 doit être exportée. Les sources escript gardent les règles d'OTP (voir ci-dessus).