ninja
Минималистичная система сборки, ориентированная на максимальную скорость выполнения. В отличие от высокоуровневых систем (CMake, Meson, Autotools), Ninja не предназначена для написания правил сборки вручную — она выступает в роли низкоуровневого бэкенда, который получает на вход готовый граф зависимостей и выполняет только необходимые команды с максимально возможной параллелизацией.
Особенности
- экстремально высокая скорость инкрементальной и полной сборки;
- простой декларативный формат файлов сборки (
.ninja); - автоматическая параллелизация задач по доступным ядрам процессора;
- минимальные накладные расходы при запуске и чтении правил;
- интеграция с генераторами сборки (CMake, Meson, GN, Premake и др.).
Основные компоненты
Ninja состоит из одного исполняемого файла, который интерпретирует файлы описания сборки и выполняет команды. Вся мощь системы раскрывается через генерируемые файлы .ninja и вспомогательные утилиты (подробнее с документацией можно ознакомиться здесь).
Файлы сборки (.ninja)
Основой Ninja являются текстовые файлы с правилами, переменными и целями. Формат прост и не содержит условных конструкций или циклов — вся логика должна быть реализована на этапе генерации.
Ключевые элементы файла:
- Переменные:
cflags = -Wall,builddir = out; - Правила: определяют команды и опции для обработки файлов;
- Сборки: связывают входные файлы с выходными через правило;
- По умолчанию: цель, которая будет собрана при запуске без аргументов.
Генераторы сборки
Ninja не предназначен для написания правил вручную. Вместо этого используются генераторы, которые анализируют проект и создают оптимальный .ninja файл.
Популярные генераторы:
- CMake:
-G Ninjaгенерирует правила для компиляции на любой платформе; - Meson: использует Ninya как встроенный бэкенд по умолчанию;
- GN: генератор, разработанный для Chromium, создаёт высокооптимизированные файлы Ninja;
- Python: библиотека
ninja_syntax.pyпозволяет генерировать.ninjaскрипты программно.
Правила и команды
Правила в Ninja определяют, как преобразовывать одни файлы в другие. Они содержат командную строку, переменные окружения и описание.
Основные атрибуты правил:
command— команда для выполнения (с поддержкой переменных);description— краткое описание (выводится при сборке);depfile— файл зависимостей, сгенерированный компилятором;generator— флаг, указывающий, что правило создаёт файлы, используемые другими правилами.
Граф зависимостей
Ninja строит граф зависимостей на основе объявленных входов и выходов. Это позволяет выполнять только минимально необходимые действия при изменении исходных файлов.
Особенности графа:
- явное указание зависимостей через
inиout; - поддержка неявных зависимостей (через depfile);
- порядок сборки определяется топологической сортировкой;
- возможность задавать «теневые» зависимости (order-only).
Производительность и параллелизм
Ninja изначально спроектирован для высокой производительности. Он минимизирует операции ввода-вывода, не выполняет лишних проверок и максимально загружает все доступные ядра.
Ключевые оптимизации:
- запуск команд в нескольких потоках (по умолчанию число ядер);
- компактное двоичное представление графа в памяти;
- использование
stat()только для изменённых файлов; - кэширование результатов проверки времени модификации.