Clause
← Уся документація

Перекладено з англійського оригіналу · 06042fa · 2026-10-09 · Читати англійською

Компіляція

clau компілює модулі Erlang/OTP 29 через LLVM у перевірене IR, біткод або нативні об'єктні файли. -o/--output компонує позиційні вхідні файли (або одну вибрану ціль проєкту), їхній стартовий об'єкт точки входу і runtime у виконуваний файл (компонування); збирання проєктів компонують виконувані цілі в їхні виводи з маніфесту (проєкти). Згенеровані об'єктні файли також можна запускати через обв'язку C++, скомпоновану з runtime (див. приклад нижче).

Прийнята підмножина вихідного коду

Іменовані модулі з експортами та впорядкованими клаузами функцій. Голови та зіставлення в тілі приймають змінні, _, псевдоніми, повторювані імена і зразки над атомами, довільними цілими числами, скінченними числами з рухомою комою, кортежами, списками/рядками, map, bitstring і звичайними кортежними record. Тіла — це послідовності зіставлень, конструкторів, перевірених операторів/guard BIF, erlang:display/1 (друк), halt/0,1 (код завершення), функцій, що викликають винятки, — error/1,2,3, exit/1, throw/1 і erlang:raise/3 (ABI), інших вбудованих функцій мосту (erlang:function_exported/3) і fun вбудованих функцій, case/if, catch Expr, try ... of ... catch Class:Reason:Stack ... after з трасуваннями стека, maybe ... else ... end, comprehension для списків, binary і map (зразки) та прямих локальних або буквальних віддалених викликів у межах пакета, зокрема власної, взаємної та міжмодульної рекурсії на явних фреймах процесу з належними хвостовими викликами (модель виконання); рекурсію в тілі обмежує стек процесу (за замовчуванням необмежений), а не нативний стек. Guard підтримують увесь допущений каталог. Див. зразки, guard і терми.

Функціональні значення fun F/A, fun M:F/A, анонімні та іменовані fun із захопленими змінними, виклики fun і динамічні виклики (M:F(...), apply/2,3) виконуються (fun). З діагностикою відхиляються навіть у невикористаних функціях: receive, fun вбудованих функцій, процеси та обмін повідомленнями. Прийняті атрибути: module, export, file, кортежний і нативний record, export_record, import_record, форми type/spec, doc/moduledoc, author, vsn, copyright, deprecated, -compile з {no_auto_import, ...} або параметрами nowarn_*, що стосуються лише попереджень (наприклад, nowarn_deprecated_catch), і -import guard BIF з erlang. Інші атрибути (on_load, parse transform, інші параметри compile, параметризовані модулі) відхиляються. Вихідні файли, що починаються з #!, дотримуються правил escript (неявний модуль і експорт main/1, -mode приймається). Форми type/spec аналізуються, але ніколи не змінюють згенерований код. Режими лише для синтаксису (--parse-check, --print-ast, --print-source, ...) приймають повну граматику.

Запуск прикладу зі скомпільованими модулями

client:main/1 робить приклад програмою:

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

Ті самі модулі можна запустити й через обв'язку C++. З Developer PowerShell для Windows x64 і зібраним компілятором:

$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

Вона друкує 42, -7, record, map, binary, list, integer, other, по одному на рядок. Обв'язка явно реєструє модулі, створює контекст і декодує результати; це приклад хоста, а не робоча точка входу. В Unix використовуйте build/debug/bin/clau, clang++ і -DGENERATED_DIR="$PWD/build/example-aot" (нативні запуски там ще не перевірено).

Інші дії над тими самими вихідними файлами:

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

Друк вихідного коду

--print-source (дія фронтенду, як --print-ast) друкує кожен розібраний модуль як вихідний код Erlang; --print-types друкує той самий текст з анотаціями типів. Принтер (print_source, expression_source, type_source у printing.hpp; compiler/src/printing/source_*) придатний для повторного використання:

Параметри

ПараметрПоведінка
--emit obj|llvm-ir|llvm-bcПублікує один артефакт на модуль
--artifact-dir DIRКорінь артефактів (потребує --emit)
-o PATH / --output PATHКомпонує виконуваний файл (компонування); конфліктує з --emit
--linker PATH, --runtime-library PATHДрайвер Clang і архів runtime для -o
--entry MODULE[:FUNCTION]Функція точки входу виконуваного файлу з арністю 1; перевіряється в кожному режимі компіляції й додає стартовий артефакт clausev1_start (виконувані файли)
--target-triple TRIPLEЦільова машина; --target — це вибір цілі проєкту
-O0 / -O2 / -OsЗагальний код за замовчуванням + LLVM O0 / обмежена спеціалізація + LLVM O2 / LLVM Os, без спеціалізації, одна секція на символ і вилучення компонувальником коду та даних, на які немає посилань
--no-type-specializationВимикає варіанти незалежно від порядку параметрів
--print-ir / --print-optimized-irПеревірене IR до/після проходів LLVM, з рядками вихідного коду Erlang як коментарями
--print-typesКожен модуль як вихідний код Erlang з анотаціями виведених типів (семантика); зупиняється перед LLVM
--verboseПодії фаз [pp], [parse] і [comp] у stderr
--impldebug n[,n...]Налагоджувальний вивід кроків реалізації в stderr (наприклад, 23: зведення виведення типів)

Бекенд

SDK LLVM

Стабільний LLVM 23.1.x, щонайменше 23.1.1. LLVM — залежність хоста: архітектура, стандартна бібліотека C++ і CRT Windows мають відповідати інструменту компілятора. Код проєкту зберігає винятки/RTTI; жоден виняток не може розкручуватися через LLVM. Runtime ніколи не використовує LLVM.

Еталонне налаштування Windows x64 (2026-09-29): clang-cl 23.1.2 хоста в C:/Program Files/LLVM/bin, SDK thirdparty/clang+llvm-23.1.2-x86_64-pc-windows-msvc, інструменти Visual Studio 18 x64, Windows SDK 10.0.26100.0, Ninja, /MT, _ITERATOR_DEBUG_LEVEL=0. Автоматичний вибір застосовує налаштування /MT та ітераторів; явний LLVM_DIR — ні, і тоді пробне компонування завершується невдачею.

Історичне еталонне налаштування macOS: Homebrew llvm 23.1.1_1 (arm64, спільна libLLVM.23.1.dylib, перевірки assertions вимкнено) з AppleClang 21.

Інші передумови: CMake ≥ 3.28, компілятор C++23, Boost ≥ 1.90, toml++ 3.4.0 та інструменти перевірки якості. OTP потрібен лише для аудитів за бажанням і регенерації фікстур.