Найти в Дзене
Цифровая Переплавка

Система сборки — это не Makefile. Это модель мышления

Мы привыкли воспринимать систему сборки как набор скриптов, которые «что-то компилируют». Make, CMake, Bazel, Cargo — инструменты меняются, а ощущение остаётся прежним: нажал кнопку, получил бинарник. Статья Jyn аккуратно и без пафоса делает куда более важную вещь — раскладывает сборку как вычислительную систему, со своей теорией, ограничениями и фундаментальными свойствами. И внезапно выясняется, что система сборки (build system) — это не про компиляцию. Это про инкрементальные вычисления над графом зависимостей. Сборка как преобразование данных В самом базовом виде любая система сборки — это механизм, который: 🧩 принимает входные данные 🔄 применяет к ним набор преобразований 💾 кеширует результаты 🔁 пересчитывает только то, что действительно изменилось Компиляция, линковка, генерация кода, сборка Docker-образа — всё это частные случаи одного и того же паттерна. Отличие лишь в том, насколько точно система понимает свои зависимости. Инкрементальность — это не «быстро», а «корректно
Оглавление

Мы привыкли воспринимать систему сборки как набор скриптов, которые «что-то компилируют». Make, CMake, Bazel, Cargo — инструменты меняются, а ощущение остаётся прежним: нажал кнопку, получил бинарник. Статья Jyn аккуратно и без пафоса делает куда более важную вещь — раскладывает сборку как вычислительную систему, со своей теорией, ограничениями и фундаментальными свойствами.

И внезапно выясняется, что система сборки (build system) — это не про компиляцию. Это про инкрементальные вычисления над графом зависимостей.

Сборка как преобразование данных

В самом базовом виде любая система сборки — это механизм, который:

  • 🧩 принимает входные данные
  • 🔄 применяет к ним набор преобразований
  • 💾 кеширует результаты
  • 🔁 пересчитывает только то, что действительно изменилось

Компиляция, линковка, генерация кода, сборка Docker-образа — всё это частные случаи одного и того же паттерна. Отличие лишь в том, насколько точно система понимает свои зависимости.

Инкрементальность — это не «быстро», а «корректно»

Часто инкрементальную сборку понимают как оптимизацию. На самом деле это вопрос корректности.

Хорошая система сборки обязана гарантировать:

  • 🧠 любой инкрементальный билд эквивалентен чистому
  • 🔍 ни одно изменение не останется незамеченным
  • ♻️ ни одно правило не выполнится зря

Именно здесь появляются строгие термины:

корректность сборки (soundness), минимальность сборки (minimality), раннее прекращение пересборки (early cutoff). Это не академическая мишура — это формализация того, почему “иногда надо сделать очистку сборки” вообще считается багом.

Графы зависимостей: аппликативные и монадные

Один из самых сильных моментов статьи — разделение build-систем по типу графа зависимостей.

Если все входы и правила известны заранее — граф статический. Это аппликативная модель. Она проста, анализируема и отлично кешируется. Make и Bazel любят именно её.

Но реальный мир редко бывает таким аккуратным. Когда зависимости появляются во время выполнения — например, через build scripts или кодогенерацию — система становится монадной. Граф строится на лету.

Это компромисс:

  • 📐 статичность даёт предсказуемость
  • 🧪 динамика даёт выразительность
  • ⚠️ но усложняет корректность и кеширование

Cargo, rustc, Shake — все они живут в этом «сером» пространстве между теорией и практикой.

Герметичность, песочницы и детерминизм — разные оси

Отдельно важно, что статья чётко разводит понятия, которые часто путают:

  • 🧱 герметичность — все зависимости описаны явно
  • 🏗️ песочница — процесс изолирован от внешнего мира
  • 🎯 детерминизм — одинаковый вход даёт одинаковый выход

Docker обеспечивает изоляцию процессов (sandboxing), но не герметичный. Nix — герметичен, но не всегда изолирован. А без детерминизма удалённый кеш превращается в лотерею.

Эти свойства независимы, и осознанный выбор между ними — признак зрелой инфраструктуры.

Сборка — это не только про компиляторы

Самый неожиданный, но логичный вывод: системы сборки повсюду.

Если есть:

  • 📊 Excel с формулами
  • ⚛️ React с зависимостями компонентов
  • 🔄 rustc query system
  • 📦 GitHub Actions

…значит где-то рядом уже есть система сборки. Просто под другим именем.

Моё мнение: статья, которая экономит годы

Главная ценность текста Jyn — не в том, что он объясняет Make или Bazel. Он даёт универсальный словарь, с помощью которого можно:

  • осмысленно сравнивать инструменты
  • проектировать свои системы
  • понимать, почему «быстро, но иногда ломается» — это архитектурный провал

Если вы работаете с большими кодовыми базами, компиляторами, CI/CD или сложными пайплайнами — это тот редкий материал, который не устареет через год.

Источники и ссылки

🔗 Основная статья Jyn:
https://jyn.dev/what-is-a-build-system-anyway/

🔗 Упомянутая работа Build Systems à la Carte:
https://www.microsoft.com/en-us/research/publication/build-systems-a-la-carte/

🔗 Rust compiler: incremental compilation & queries:
https://rustc-dev-guide.rust-lang.org/

🔗 Bazel: hermeticity и persistent workers:
https://bazel.build/