Проєкти TOML
Маніфест проєкту вибирає впорядковані групи вихідних файлів Erlang і незалежно налаштовує кожну ціль. Усі дії CLI приймають проєкти. Див. робочий приклад.
Маніфест (схема 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"
- Обов'язкові
schema_version = 1і непорожній масивtargets. Невідомі ключі, неправильні типи, дублікати назв цілей і порожні рядки відхиляються; неявного перетворення типів немає. Перевіряється весь маніфест, зокрема невибрані цілі. - Назви цілей: чутливі до регістру ASCII
[A-Za-z0-9_][A-Za-z0-9_.-]*, унікальні. Назва — це ціль збирання, а не триплет LLVM. sources(файли та шаблони з підстановочними знаками) іsource_dirs(рекурсивний пошук.erlі.abstr) необов'язкові, але цілі потрібен принаймні один запис. Явно задані файли мають закінчуватися на.erlабо.abstrдля форм в абстрактному форматі (перетворення); заголовки — це залежності, а не вхідні дані.- Групи
[[targets.asn1]]компілюють специфікації ASN.1 (sources,options,outdir) у модулі, що входять до цілі (ASN.1). parse_transforms(імена модулів) іtransform_paths(каталоги або шаблони попередньо скомпільованих файлів.beam) вoptionsзастосовують parse transforms до модулів цілі (перетворення).ignore_dirs(шляхи) іignore_modules(імена модулів), обидва з підстановочними знаками, вoptionsвиключають вихідні файли зі збирання (ігноровані вихідні файли).keep_exports = trueвoptionsзалишає кожен експорт виконуваного файлу цілі доступним для виклику, як--keep-exportsробить для кожної вибраної цілі (живучість експортів). Має бути булевим значенням.shell = trueвoptionsкомпонує інтерактивну оболонку з виконуваним файлом цілі, як--shell(інтерактивна оболонка). Має бути булевим значенням.cache_inference_in_dirs(шаблони каталогів) вoptionsдодає каталоги, модулі яких зберігають результати виведення типів у кеші збирання (кеш виведення).- Поля
options— необов'язкові типізовані параметри фронтенду.definesвикористовуютьNAME(=true) абоNAME=ERLANG_LITERAL_TERM; дублікати є помилками. Можливість не може бути в обох списках можливостей. entry(необов'язково) вибирає точку входу виконуваного файлуMODULE[:FUNCTION[/ARITY]]; див. виконувані файли.--entryз CLI перевизначає його для однієї вибраної цілі.build_dir(необов'язково) — каталог збирання цілі, типово<manifest-dir>/build.output— місце призначення виконуваного файлу, типово<manifest-dir>/build/<target>(.exeу Windows). Ціль зoutputабоentryє виконуваною ціллю (виконувані файли);--emitі режими перевірки/друку ігнорують вивід обох ключів.- Не підтримується: кореневі типові значення, успадкування, залежності між цілями, імпорти, профілі, пакети, стеження, паралельні збирання. Поля додаються лише разом із їхньою поведінкою.
CLI і вибір цілей
clau [options] <source.erl>...
clau [options] --project <path> [--target <name>]...
clau --new-project <filename>
- Позиційні вихідні файли та
--projectвзаємовиключні. Один--project, будь-яка кількість--target, у будь-якому порядку. - Без
--target: усі цілі в порядку маніфесту. Селектори зберігають свій порядок і перше входження. Невідомі назви дають помилку до будь-якої роботи фронтенду і перелічують доступні назви. --project test1завантажуєtest1.toml, колиtest1не існує.- Параметри фронтенду з CLI застосовуються до кожної вибраної цілі. Шляхи з CLI зберігають значення відносно каталогу виклику; шляхи маніфесту задаються відносно маніфесту.
- Без
--emitабо дії перевірки/друку виконувані цілі компонуються у свої виводи (виконувані файли); інші цілі компілюються в пам'яті. -o/--outputкомпонує ціль у вказаний шлях замість їїoutput(компонування); потребує рівно однієї вибраної цілі.--verboseтрасує файли/включення[pp]і вихідні файли[parse]у stderr.--print-inputsвиконує кожну вибрану ціль до компіляції: препроцесує й розбирає вихідні файли після пошуку, потім додає модулі, які вони називають, з бібліотеки таsource_search_paths, як це робить збирання. Друкує вихідні файли цілі (абсолютні шляхи), по одному на рядок, потім кожен доданий вихідний файл як<path> (referenced at <file>:<line>)— найраніше місце в модулі, що посилається, яке його називає; додані вихідні файли по черзі теж переглядаються. Нічого не компілюється. Для кількох цілей кожен список іде після рядка[target <name>]. Позиційні вхідні файли друкуються як задано. Діагностика йде в stderr; помилка розбору зупиняє додавання модулів, на які є посилання, і завершується з кодом 1. Замінює інші дії перевірки/друку і, як вони, конфліктує з-o,--entryі перемикачами компіляції.--print-envдрукує весь виклик як TOML: одну таблицю[[targets]]на кожну вибрану ціль з її розв'язаними вихідними файлами, каталогами пошуку/включення та ефективними параметрами (звіт про середовище).- Код виходу 2: помилки використання і невідомі цілі. Код виходу 1: невдачі маніфесту, пошуку файлів, фронтенду або створення. Код виходу 0: успіх (попередження дозволені).
Кожна вибрана ціль — це окремий пакет компіляції з власними сесіями
препроцесування. Планування (декодування, вибір, пошук файлів, перевірка
колізій виводу) завершується до обробки будь-якого вихідного файлу; потім
виконання обробляє цілі/файли по порядку і фіксує невдачі. Корисний вивід іде в
stdout у порядку цілей/файлів без заголовків (крім рядків цілей
--print-inputs); контекст і діагностика йдуть у stderr. Ціль із
діагностикою називається один раз, у рядку <manifest> [target <name>]:
перед першим її повідомленням; самі повідомлення
(error: file:line:col: message) не мають префікса інструмента чи цілі.
./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
Виконувані файли
clau --project FILE [--target T]... (без --emit, без дії перевірки/друку)
компонує кожну вибрану ціль, що має ключ output або entry або до якої
звертаються -o/--entry з CLI, в один виконуваний файл на ціль:
- Місце призначення:
-oз CLI (відносно каталогу виклику), інакшеoutput(відносно маніфесту), інакше<manifest-dir>/build/<target>. Для цілей Windows до імені без розширення додається.exe. Відсутні каталоги виводів маніфесту створюються; каталог явного-oмає існувати. - Точка входу:
--entryз CLI,entryз маніфесту, інакше автоматичне визначення (вибір точки входу). - Цілі без
output,entry,-oі--entry— це бібліотеки: вони компілюються в пам'яті й нічого не записують, навіть якщо модуль експортуєmain/1. - Планування відхиляє вибрані цілі з однаковим місцем призначення; виводи, що
збігаються лише після додавання
.exe, відхиляються до публікації. Вивід не повинен збігатися з вибраним вихідним файлом або маніфестом. - Кожна ціль компілюється й компонується у власний проміжний каталог. Виводи замінюються лише після успіху всіх вибраних цілей, у порядку цілей; будь-яка невдача лишає всі наявні виводи без змін. Невдача під час заміни пізнішого виводу може залишити раніші вже заміненими.
--linkerі--runtime-libraryзастосовуються до кожної цілі, що компонується (компонування).
./build/debug/bin/clau --project tests/fixtures/linking/project/project.toml
Створення проєкту
--new-project <filename> записує один анотований маніфест і нічого більше.
- Додає
.toml, якщо ім'я ще не закінчується на.toml(без урахування регістру ASCII):demo→demo.toml,demo.config→demo.config.toml. - Відхиляє порожні імена або імена, схожі на каталоги, повторення і будь-яке
поєднання з вихідними файлами,
--project,--target,-o, режимами перевірки/друку або параметрами фронтенду. - Батьківський каталог має існувати. Ніколи не перезаписує (виключне створення); прибирає власний частково записаний файл у разі невдачі запису. У разі успіху друкує шлях створеного файлу.
- Вміст — детермінований UTF-8/LF з коментарями: одна ціль
app,sources = [],source_dirs = ["src"], порожні списки параметрів і типовий для платформи вивід. Він одразу декодується; користувач додає вихідні файли вsrc.
Каталог збирання
Кожна ціль проєкту має каталог збирання, де Clause тримає власні тимчасові
файли та свої кеші: build_dir цілі, відносно маніфесту, типово
<manifest-dir>/build. --build-dir DIR (відносно каталогу виклику) замінює
його для кожної вибраної цілі. Позиційні вхідні файли не отримують жодного,
якщо не задано --build-dir.
- Тимчасові файли розміщуються в
<build_dir>/tmp: робочі простори завантажувача parse transforms (перетворення). Кожен запуск видаляє власні; порожнійtmpможе лишитися. Без каталогу збирання вони йдуть у тимчасовий каталог системи. - Проміжні файли компонування (
.clause-link-*) лишаються поруч із виконуваним файлом, бо остаточне перейменування має відбуватися на томі виводу (компонування). - Режими перевірки та друку (
--parse-check,--print-ast, ...) нічого не записують поза каталогом збирання; позиційні перевірки без--build-dirвзагалі не записують файлів. --print-envдрукуєbuild_dirкожної цілі ("", коли його немає).
Кеші збирання
Результати, які варто зберігати між запусками, лежать у <build_dir>/cache;
--no-cache їх не читає й не записує. Це відповіді завантажувача parse
transforms і список sticky-модулів OTP хоста, тож тепле збирання не запускає
erl хоста для модулів, вхідні дані перетворень яких не змінилися,
результат компіляції кожного пакета і
результати виведення модулів у налаштованих каталогах.
- Інтерфейс. Викликачі використовують одне внутрішнє для проєкту сховище
(
compiler/src/cache/ store.hpp):get/putза вхідним каталогом, ім'ям файлу, видом результату та ключем, а такожinvalidateіprune; шляхів вони ніколи не бачать. Значення — це версія формату викликача і список іменованих частин (запуск перетворення:replyіoutput; результат компіляції:failed, коженdiagnostic, а з виводами —triple,extensionі по одній частині на об'єктний файл модуля), тож жодному викликачу не потрібен власний кодек.getз іншою версією формату — промах. Кожна операція безпечна з кількох потоків одночасно. - Розміщення.
cache/v2/cache.db— база даних SQLite 3.54: таблицяentries(вхідний каталог, файл, вид, ключ, формат, останнє використання; унікальна за адресою) і таблицяparts(запис, порядок, ім'я, розмір, контрольна сума xxh3-64 і або байти, або ім'я blob-файлу). Частини, більші за 256 KB, лежать уcache/v2/blobs/<xxh3-128 of the bytes>, тож однакові частини (ідентичні об'єктні файли пакета, зібраного з двома наборами параметрів) зберігаються один раз; 256 KB — це межа, на якій, за вимірюваннями, читання перестають бути вигіднішими з базою даних, а записи стають вигіднішими з файлами (cache_store benchуtests/compiler/cache). Blob-файл записується як тимчасовий і перейменовується до фіксації рядка, що його називає, тож рядок ніколи не називає неповний файл; збій між цими кроками лишає лише файл-сироту. - Ключі. Ключ — це 128-бітний хеш вмісту всього, від чого залежить
результат, ніколи не позначка часу: версія та виконуваний файл
clau(шлях, розмір, час зміни, тож перезібранийclauдає промах), вид результату, а для запуску перетворення — запит, надісланий доerl(препроцесовані форми модуля та його параметри компіляції: каталоги включення, визначення, можливості), випуск OTP хоста (erlі файлиreleases/*/OTP_VERSIONпоруч із ним), кожен вихідний файл перетворення проєкту, скомпільований для запуску, разом із файлами, які він включає, і кожен.beamу шляхах коду перетворень. Версія формату сховища — це каталогv<format>; власна версія формату значення зберігається в його рядку. Оскільки ключ охоплює препроцесовані форми, змінений заголовок, визначення чи можливість або новий заголовок, що затіняє включений, дає промах саме для тих модулів, чиї форми чи параметри змінюються; визначення й можливості — це параметри компіляції, які бачить кожне перетворення, тож вони дають промах для кожного перетвореного модуля; змінений.beamдає промах для кожного модуля, перетворення якого виконуються з цим шляхом коду. - Паралельність. База даних працює в режимі журналу попереднього запису
(write-ahead log) з
synchronous=NORMAL: читачі працюють поруч із записувачем, а записувачі (одна транзакція наput) чекають одне одного до 30 с. Кілька процесівclau, що спільно використовують каталог збирання, зберігають кожен запис. Усередині одного процесу м'ютекс серіалізує потоки, що спільно використовують сховище. - Пошкодження. Частини мають розміри й контрольні суми, а blob-файли
перевіряються за своїми іменами: пошкоджена частина або відсутній
blob-файл — промах (
damaged entry), і його запис відкидається. Сміттєвий, обрізаний чи чужийcache.db(SQLite повідомляє, що він пошкоджений або не є базою даних, або його ідентифікатор застосунку чи версія схеми відрізняються) перейменовується наcache.db.damagedі створюється заново; коли це неможливо, запуск продовжується без кешу. Ніщо з цього не є помилкою, а--verboseвідзначає це як[cache] .... - Мережеві файлові системи. Журнал попереднього запису потребує спільної
пам'яті між процесами, якої мережеві файлові системи не надають. Коли
SQLite не може увійти в режим WAL, сховище використовує свій журнал відкату
(тоді читачі чекають на записувача), і
--verboseповідомляє про це один раз; коли жоден режим журналу не працює, запуск продовжується без кешу. - Очищення. Наприкінці запуску, що записував у сховище, записи, не
використані 30 днів, видаляються, потім blob-файли, яких не називає жоден
запис (якщо вони старші за 10 хвилин, тож новий файл паралельного
записувача виживає), а звільнені сторінки повертаються файловій системі
(інкрементальний vacuum). Кожен запуск видаляє залишене дерево
cache/v1колишнього файлового бекенду. - Спостережуваність.
--print-stage-timesпозначає повторно використані етапи ([time] transform src/a.erl: 7.254 ms (cached));--verboseдрукує[cache] hit|miss <kind> <file>з причиною промаху (no entry,inputs changed,damaged entry). Діагностика та вивід перетворень однакові з влученням і без нього: вони зберігаються разом із записом. - Не кешуються: препроцесування і розбір (завантаження кешованого
результату через абстрактні форми,
transforms/import, за вимірюваннями повільніше, ніж повторний розбір), а також сканування каталогів: у плануванні переважає відкриття та ідентифікація кожного вихідного файлу, чого кеш сканування не може пропустити.
Кеш виведення
Бібліотечні модулі (вихідні файли stdlib, kernel, compiler і
syntax_tools з OTP, знайдені через source_search_paths, власна
бібліотека Clause) змінюються рідко, тож модулі в налаштованих
каталогах зберігають результати виведення типів у кеші збирання, для кожного
модуля окремо, а пізніші компіляції використовують їх повторно, замість того
щоб виводити знову.
- Каталоги: неявні шаблони застосунків OTP
*/stdlib,*/stdlib-*,*/kernel,*/kernel-*,*/compiler,*/compiler-*,*/syntax_toolsі*/syntax_tools-*, потімcache_inference_in_dirsцілі, потім кожен--cache-inference-in-dirs PATTERN(можна повторювати; також для позиційних вхідних файлів). Шаблони використовують підстановочні знакиsources; роздільники Windows приймаються. - Модуль охоплено, коли каталог, що містить його вихідний файл, відповідає
шаблону. Відносний шаблон відповідає кінцевим каталогам будь-якого шляху, а
не шляхам під каталогом маніфесту:
*/stdlibохоплює/usr/lib/erlang/lib/stdlib/src/lists.erlіreferences/otp/lib/stdlib/src/lists.erl, тоді як встановленому.../lib/stdlib-7.0/src/lists.erlпотрібен*/stdlib-*. Абсолютний шаблон відповідає всьому шляху каталогу (C:/Program Files/Erlang OTP/lib/*). Зіставлення лексичне й чутливе до регістру. Неявні шаблони охоплюють також власний каталог проєкту з такою назвою (apps/compiler), що лише зберігає більше записів: повторне використання коректне для кожного модуля. --print-envдрукує ефективний список якcache_inference_in_dirs, неявні шаблони першими. Непідтримувана конструкція ([,{,!) — помилка маніфесту або помилка використання (код виходу 2) у командному рядку.- Повторне використання потребує каталогу збирання (кожна ціль проєкту;
позиційні вхідні файли з
--build-dir) і вимкнене з--no-cache. Воно працює для кожної дії, що виконує аналіз (компіляція, виконувані файли,--print-types, перегляд IR), також коли кеш компіляції пакета дає промах. - Ключ: ідентичність
clau, відбиток модуля і відбитки кожного модуля пакета, які називають його атоми, транзитивно (віддалені виклики,fun M:F/A,apply, будь-який атом, що є ім'ям модуля); див. семантика: кеш виведення, чому лише від цього залежать усі його факти. Тож редагування модуля користувача зберігає влучення для бібліотеки, якщо бібліотечний модуль його не називає; редагування бібліотечного модуля дає промах для нього і для кожного охопленого модуля, що його досягає. - Записи зберігаються для кожного каталогу вихідних файлів, файлу та цілі
проєкту (вид
inference@<target>,inference@positional); значення — одна частинаresults(semantic/types/inference_store: вузли графа, підсумки та локальні вхідні дані за функціями, факти виразів за синтаксичною позицією). Результати, збережені компіляцією з більшою кількістю живих функцій (наприклад,--print-types), обслуговують виконуваний файл, що зберігає менше. --verboseдрукує[cache] hit|miss inference <file>для кожного охопленого модуля (причини промаху:no entry,inputs changed,damaged entry,results do not fitдля збережених результатів, яким бракує функції, живої зараз);--print-stage-timesдрукує фазиinference-cache(зN of M covered modules reused) іinference-store.
Шляхи та пошук файлів
- Шлях проєкту розв'язується відносно каталогу виклику; лексичний батьківський
каталог маніфесту є базою для всіх шляхів маніфесту (навіть через символьне
посилання). Абсолютні шляхи лишаються абсолютними;
..дозволено. Без розгортання оболонки, змінних середовища чи тильди. Для шляхів Windows використовуйте/або буквальні рядки TOML. - Буквальні відносні вихідні файли спершу шукаються в базі, потім у
source_search_pathsпо порядку. Наявний, але нечитабельний кандидат є помилкою. Шляхи пошуку не перелічують модулі й не впливають на включення. - Коли вихідні файли цілі називають модуль, який жоден із них не визначає
(віддалений виклик,
fun M:F/A,applyз літеральним модулем,-behaviourабо-import), спершу шукаєтьсяModule.erlу бібліотеці Clause, потім у шляхах пошуку по порядку (встановлений OTP ніколи не замінює модуль Clause, а модуль, який Clause позначає як відсутній, ніколи не береться зі шляху пошуку: розв'язання); знайдений файл приєднується до цілі як перелічений вихідний файл, а його власні посилання розв'язуються так само. Перелічений вихідний файл з іменем модуля Clause замінює його з попередженням. - Підстановочні знаки:
*і?у межах компонента,**як цілий компонент. Квадратні та фігурні дужки, заперечення та екранування відхиляються. Зіставлення чутливе до регістру;?— це одне скалярне значення Unicode дійсного імені UTF-8. - Приховані записи включаються; знайдені символьні посилання на каталоги пропускаються (явні корені можуть бути символьними посиланнями); символьні посилання на файли розкриваються.
- Порядок: записи
sourcesпо порядку, збіги кожного шаблону відсортовано за байтами шляху UTF-8, потім кожне розгортанняsource_dirs, відсортоване так само. Відсутні буквальні файли, шаблони без збігів і порожні цілі є помилками. - Усунення дублікатів у межах цілі використовує ідентичність у файловій системі (символьні посилання, жорсткі посилання, псевдоніми за регістром), зберігаючи перше написання. Той самий файл у двох цілях компілюється двічі, бо параметри можуть відрізнятися.
- Лише вибрані цілі звертаються до файлової системи.
Індекс каталогів
Пошук за іменем не перевіряє кожен каталог-кандидат. Один індекс на виклик
clau, спільний для всіх цілей, зберігає імена записів кожного каталогу, де
виконується пошук: каталог перелічується один раз, нерекурсивно, коли пошук
уперше його потребує, або записується рекурсивними обходами, що розгортають
** у sources, source_dirs, source_search_paths, include_dirs і
transform_paths, тож жоден каталог не перелічується двічі. Він відповідає
на промахи пошуку модулів (бібліотека, потім source_search_paths),
вихідних файлів перетворень, буквальних sources, знайдених через
source_search_paths, і розв'язання включень (каталог файлу, що включає,
робочий каталог, каталоги включення по порядку, потім застосунки
include_lib); кандидат, який містить індекс, усе одно відкривається або
перевіряється, як і раніше, тож пріоритет, ignore_dirs і звіти про помилки
не змінюються. Імена включень із частинами каталогів (sub/x.hrl)
шукаються в каталозі, який вони називають; імена з кроками .., абсолютні
імена, відносні каталоги та переліки, що не вдалися, перевіряються, як і
раніше.
- Ключі імен файлів згортають регістр ASCII у Windows і macOS, томи яких
типово ігнорують регістр, тож
Foo.hrlусе одно знаходитьfoo.hrl; деінде ключі точні. Імена, які згортання не може точно зіставити (там — імена не з ASCII, а у Windows — імена, що закінчуються на.чи пробіл або містять~, які можуть бути короткими іменами 8.3), перевіряються напряму. - Індекс — це знімок одного виклику: файли, що з'являються під час роботи
clau(проміжні файли компонування, виводи), ніколи не є вхідними даними пошуку. --verboseзавершується рядком[index] listed=N walked=N lookups=N misses=N probes=N(каталоги, перелічені на вимогу, переліки, записані обходами, пошуки, на які відповів індекс, і промахи серед них, пошуки, залишені прямій перевірці).
Ігноровані вихідні файли
ignore_dirs і ignore_modules виключають вихідні файли з цілі, не
видаляючи їх із дерева, наприклад вбудовані тести сторонніх залежностей,
застарілий код або модулі, що мають значення лише під OTP. Ігнорований
вихідний файл мовчки пропускається: його ніколи не читають, не розбирають,
не компілюють і не компонують, тож він може навіть містити синтаксичні
помилки.
ignore_dirs: шляхи відносно маніфесту (або абсолютні) з підстановочними знакамиsources. Вихідний файл ігнорується, коли його шлях або каталог, що його містить, відповідає шаблону:src/legacy,deps/*/test,**/test(будь-який каталогtest),src/*_SUITE.erl. Зіставлення лексичне; шаблон не мусить ні з чим збігатися.ignore_modules: імена модулів або шаблони імен з*і?, що зіставляються з усім ім'ям (*_SUITE,legacy_*,prim_???). Вихідний файл з іменем<Module>.erl(або.abstr) ігнорується, коли запис відповідає<Module>, а модуль, на який є посилання і який відповідає шаблону, ніколи не шукається. Це стосується й бібліотечних модулів Clause.- Вихідний файл, який
sourcesперелічує буквально (без підстановочного знака), ніколи не ігнорується: правила на нього не діють, а збирання попереджаєlisted in sources but matched by ignore_modules or ignore_dirs; ignoring it has no effect. Збіги підстановочних знаків іsource_dirsігноруються, як описано. - Обидва застосовуються до
sources,source_dirs, буквальних вихідних файлів, знайдених черезsource_search_paths, пошуку модулів уsource_search_pathsі бібліотеці та пошуку вихідних файлів parse transforms. Пошук минає ігнорованийModule.erlі продовжує шукати в пізніших каталогах. - Модуль ігнорується, коли його називає
ignore_modulesабо коли жоден вихідний файл пакета його не визначає, а єдині знайдені його вихідні файли були проігноровані (під час пошуку або пропущені з вихідних файлів цілі за іменем файлу). Модуль, визначений скомпільованим вихідним файлом, ніколи не ігнорується. - Посилання на ігнорований модуль (
M:F(...),-import,fun M:F/A,apply(M, F, [...])з літеральними іменами) ведуть до згенерованого модуля-заглушкиM, що експортує кожну функцію, названу таким чином; кожна з них повертає{module_ignored, M}замість виконання. Функція, яку пакет ніколи не називає літерально, лишаєтьсяundefдля динамічних викликів. Тип ігнорованого модуля, названий у специфікації чи типі (helper:result()), дає попередженняattempt to import a type from a module ignored in project settings: helper:resultі вважаєтьсяterm().-behaviour(M)з ігнорованимMдає попередженняbehaviour M undefined. --print-inputsперелічує кожен ігнорований модуль, на який є посилання, після доданих вихідних файлів якignored module <name> (referenced at <file>:<line>);--print-envдрукує обидва ключі.
[targets.options]
source_search_paths = ["deps/**"]
ignore_dirs = ["deps/*/test", "src/legacy"]
ignore_modules = ["telemetry", "*_SUITE"]
Ефективні параметри
| Налаштування | Поєднання маніфесту і CLI |
|---|---|
include_dirs | Порядок маніфесту, після -I з CLI (останній -I з CLI шукається першим); запис із підстановочними знаками (deps/*/include, apps/**/include) розгортається на місці в наявні каталоги, яким він відповідає, відсортовані за байтами шляху UTF-8 (** також відповідає жодному, символьні посилання на каталоги пропускаються); шаблон без збігів — помилка |
source_search_paths | Резервні корені для буквальних вихідних файлів і модулів, які ціль називає, але не перелічує; шаблони розгортаються як include_dirs (без збігів: unmatched source search path pattern) |
defines | Спочатку маніфест, потім CLI; дублікати між ними є помилками |
applications | Map маніфесту; записи CLI замінюють однойменні |
| Списки можливостей | Налаштування маніфесту, потім упорядковані зміни з CLI; CLI має перевагу |
output | Для кожної цілі, лише для виконуваних цілей; -o з CLI перевизначає для однієї вибраної цілі |
entry | Для кожної цілі; --entry з CLI перевизначає для однієї вибраної цілі |
cache_inference_in_dirs | Неявні шаблони OTP, потім шаблони маніфесту, потім --cache-inference-in-dirs з CLI (кеш виведення) |
Залежність збирання
Приватний для компілятора toml++ 3.4.0 (MIT), лише заголовки, з винятками,
невипущений синтаксис вимкнено. SHA-256 архіву
8517f65938a4faae9ccf8ebb36631a38c1cadfb5efa85d9a72e15b9e97d25155.
- macOS: виявляється
brew install tomlplusplus(формула 3.4.0). - Windows: CMake завантажує і перевіряє випуск у
thirdparty/. - Деінде: встановіть його, розпакуйте в
thirdparty/tomlplusplus-3.4.0або передайте-DCLAUSE_TOML_ROOT=<path>(має пріоритет, вимикає завантаження). - Збирання лише runtime його не шукають.
Кеш збирання використовує амальгамацію SQLite 3.54.0
(суспільне надбання), скомпільовану лише в бібліотеку кешу компілятора
(clause_sqlite, без прапорців попереджень проєкту). CMake завантажує
https://www.sqlite.org/2026/sqlite-amalgamation-3540000.zip у
thirdparty/ на кожному хості та перевіряє його SHA-256
68e913b0fe8ec6b4e5f391c594a28872884e80d6cd042a1e50c957be46b5aa4d;
-DCLAUSE_SQLITE_ROOT=<directory with sqlite3.c and sqlite3.h> має
пріоритет і вимикає завантаження.
Обмеження
Розмір маніфесту 1 MiB; щонайбільше 1 024 цілі та 100 000 вузлів TOML. Кожне розгортання вихідних файлів допускає 100 000 відвіданих записів, 128 рівнів каталогів і 16 000 000 переходів підстановочних знаків. Вичерпання є явною помилкою; це межі роботи, а не граничні терміни вводу-виводу.
Clause