Когда сборка тяжелее компьютера: Bazel и BuildBuddy
На этой странице
Большой проект можно редактировать на компьютере, которому тяжело его собирать. Проблема появляется при первой полной компиляции: процессор занят, память заканчивается, диск непрерывно читает и пишет, а браузер и редактор начинают конкурировать со сборкой.
Рабочая схема для такого случая — оставить рядом с собой исходники и управление задачей, а тяжёлую обработку перенести на отдельный runner. В Codex Patched для этого используется связка Bazel и BuildBuddy. Она задаёт границы сборочных компонентов, отправляет работу в облако и позволяет получить проверяемый артефакт. Ниже — устройство этого контура и ограничения, которые стоит учитывать перед похожим переносом.
На что сборка тратит ресурсы
Компиляция нагружает CPU, но одним процессором дело не ограничивается. Несколько параллельных компиляторов держат в памяти собственные структуры данных. Если свободной памяти не хватает, растёт давление на swap и ввод-вывод. Добавление параллельных задач в этот момент способно увеличить время ожидания.
У большого проекта есть и подготовительная работа: получение зависимостей, запуск правил, анализ целей и построение графа действий. Затем появляются промежуточные файлы, которые нужно записать, прочитать и передать следующему шагу. В конце линковка может потребовать значительный объём памяти. Профиль с LTO добавляет свою стоимость оптимизации.
Поэтому перенос оценивают по всей цепочке. Полезно отдельно видеть время подготовки окружения, анализа, исполнения, очереди и доставки результата. Иначе ускорение компилятора легко потерять на другом этапе.
Что делает Bazel
Bazel описывает сборку через цели и действия. Действие связывает объявленные входы, команду и выходные файлы. Граф определяет зависимости и то, какие независимые части можно выполнять параллельно.
Такое описание даёт основу для повторного использования результатов. Когда значимые входы действия совпадают, результат можно получить из кэша. Изменение компилятора, флагов, платформы или зависимостей способно изменить идентичность действия и потребовать нового выполнения.
Удалённый кэш хранит результаты и данные о них. Удалённое исполнение запускает действия на исполнителях. Облачный runner добавляет ещё один уровень: на нём работает сам Bazel, включая анализ графа. Для компьютера с ограниченными ресурсами этот уровень важен, потому что локально запущенный Bazel тоже выполняет работу и использует память.
Как устроен контур Codex Patched
В опубликованной схеме проекта локальная сторона подготавливает исходники и отправляет задание через BuildBuddy Run API. Сам Bazel, анализ, компиляция и линковка выполняются на облачной стороне. При недоступности runner сборка останавливается; автоматического перехода к полной локальной сборке нет.
Последовательность выглядит так:
- Зафиксировать версию публичного upstream и проверенный патч к ней.
- Подготовить ограниченный набор исходников дополнительных компонентов.
- Передать задание облачному runner и сохранить ссылку на запуск.
- На runner получить закреплённый upstream, применить патч и выбранные исходники, затем собрать нужную цель.
- Дождаться успешного завершения и появления архива артефакта с контрольной суммой.
- Скачать выбранный результат, проверить его и только затем переходить к упаковке и установке.
В проекте для этих этапов предусмотрены отдельные команды:
tools/build-codex-release
tools/build-native-bazel statusline
tools/cloud-build-status <invocation-id>
tools/fetch-cloud-artifacts <invocation-id> core
Это примеры из репозитория, требующие его подготовленного окружения и настроенного доступа. Первые две команды запускают облачную работу, третья читает состояние, четвёртая импортирует готовый результат. Ответ API о принятом задании ещё не даёт файла, пригодного для установки.
Пересобирать выбранный компонент
Крупную сборку полезно сокращать ещё до выбора машины. В Codex Patched изменяемый CLI, native host, менеджер и отдельные библиотеки возможностей имеют собственные сборочные границы. Совместимая правка одной библиотеки может собираться как отдельная цель.
Эта граница зависит от интерфейса. Если изменение требует новой операции со стороны Core или меняет ABI, потребуется пересборка затронутого хоста. Само наличие .so не означает, что любое изменение можно доставить отдельно.
Неизменённые code mode host, exec server и ресурсы в текущем контуре берутся из закреплённого официального пакета OpenAI. Происхождение пакета и хеши проверяются. Такой подход сокращает объём собственной сборки и сохраняет связь с конкретным upstream-релизом.
Утверждение «модульная правка не пересобирает CLI» проверяют на двух уровнях: по зависимостям целей и по журналу реального повторного запуска. Одно изучение графа не устанавливает длительность сборки и не показывает фактические попадания в кэш.
Холодный и повторный запуск
При холодном запуске нужны окружение, зависимости и результаты действий, которых ещё нет в доступных кэшах. Повторный запуск может использовать прогретое рабочее пространство и сохранённые результаты. Размер выигрыша зависит от того, что именно изменилось и что удалось сохранить между запусками.
В проекте разделены быстрый профиль для итераций и оптимизированный профиль с LTO. У них разные параметры и кэш-идентичности. Сравнивать время нужно внутри одного профиля, фиксируя изменение исходников и состояние кэша.
Полезный эксперимент — изменить один выбранный компонент и посмотреть второй журнал исполнения. Видно ли только ожидаемые действия? Сохранились ли результаты остальных компонентов? Сколько заняли очередь и передача файлов? Без такого эксперимента обещание конкретного ускорения остаётся предположением.
Воспроизводимость и доставка
Удалённая среда быстро обнаруживает скрытые зависимости: инструмент из случайного PATH, библиотеку, установленную вручную, файл за пределами объявленных входов. Версии инструментов, платформа и необходимые файлы должны быть описаны так, чтобы отдельное действие могло выполняться в своём окружении.
Секреты доступа также требуют отдельного канала. В сборочном контуре они не входят в публичный патч и передаются runner через предусмотренный механизм секретов. Обычные параметры окружения и команды могут попадать в метаданные и журналы, поэтому копировать туда токены неудобно и опасно для последующей публикации логов.
Завершённую сборку сопровождают происхождение исходников, журнал, манифест и контрольные суммы. Импорт выбранной генерации проверяет архив и его содержимое; успешное скачивание само по себе не активирует новую версию. Это сохраняет отдельное решение о том, какой проверенный результат устанавливать.
Что остаётся дорогим
Облако добавляет очередь, передачу исходников, получение зависимостей и скачивание артефактов. Медленная сеть или частое изменение общих входов могут съесть выгоду прогретого кэша. Один большой последовательный шаг ограничивает пользу дополнительных исполнителей.
Есть и стоимость облачных ресурсов. Её стоит оценивать вместе со временем ожидания и объёмом передаваемых данных. Увеличивать ресурсы имеет смысл после понимания узкого места; сам переход на Bazel не обещает ни бесплатной сборки, ни ускорения каждого проекта.
Практическая цель такого контура — предсказуемо получать нужный бинарник, сохраняя рабочий компьютер доступным для редактирования и проверки результата. Это решение зависит от границ компонентов и воспроизводимости не меньше, чем от мощности runner.
Частые вопросы
Достаточно ли подключить удалённый кэш?
Кэш помогает повторно использовать результаты. Если Bazel остаётся на рабочем компьютере, его подготовка и анализ тоже остаются там. В описанном контуре весь запуск Bazel перенесён на облачный runner.
Можно ли собирать только изменённый модуль?
Да, когда цель отделена от остальных компонентов и её изменение совместимо с действующим интерфейсом. Изменение контракта требует пересмотреть набор пересобираемых компонентов.
Почему повторная сборка снова стала долгой?
Проверьте профиль, версии инструментов, платформу и изменившиеся входы. Затем разделите время ожидания runner, исполнения и передачи данных. Новый запуск мог получить другую кэш-идентичность или холодное окружение.
Когда результат можно считать готовым?
Когда выбранный запуск завершён успешно, ожидаемые артефакты опубликованы и скачанный результат прошёл проверку происхождения и контрольных сумм. Установка и активация остаются следующими отдельными действиями.
Официальные материалы для деталей реализации: удалённое исполнение Bazel, удалённый кэш Bazel, требования к правилам Bazel, облачный runner BuildBuddy и удалённое исполнение BuildBuddy.