Стоит ли включать Xcode 26 Compilation Caching? Решение для CI в 2026
📋 Содержание
Симптом: Clean Build или частая смена веток не ускоряют CI, хотя кэширование уже включено.
Быстрое решение: сначала подтвердите реальные попадания Compilation Caching на одном проекте и одинаковом Runner, затем включайте режим только для устойчивых нагрузок и узлов, которые сохраняют рабочее окружение.
Последнее обновление: 3 сентября 2026 года. Версия Xcode 26 и доступность настроек сверены по официальным заметкам о выпуске Xcode 26, требованиям к системе Xcode и справочнику Build Settings.
Эта статья для вас, если вы часто переключаете ветки или запускаете Clean Build и хотите понять пользу кэша компиляции Xcode 26. Она также пригодится DevOps-инженерам, обслуживающим самостоятельные удалённые Mac Runner, и руководителям платформ, отвечающим за общие узлы, воспроизводимость релизов и место на диске.
Xcode 26 Compilation Caching: повторяемость важнее самого факта включения
Xcode 26 Compilation Caching — это опциональная возможность компиляции, а не гарантия ускорения любой сборки. Наибольший смысл она имеет там, где компилятор снова получает те же или близкие входные данные: проект собирается повторно, разработчики переключаются между ветками, а после Clean Build часть исходных условий возвращается.
Решение удобно разделить на три режима:
- Включать в рабочем контуре, если один и тот же проект часто собирается с одинаковыми Scheme, параметрами и версиями зависимостей, а Runner сохраняет кэш между заданиями.
- Отложить, если каждый запуск происходит на новом временном узле, параметры сборки часто меняются или диск уже работает на пределе.
- Запустить серую проверку, если потенциальная польза есть, но пока нет доказательств попаданий и безопасного поведения на релизных заданиях.
Не смешивайте четыре механизма:
- Compilation Caching повторно использует результаты компиляции при совпадении значимых входов.
- DerivedData хранит промежуточные артефакты конкретной рабочей области и конфигурации.
- Кэш зависимостей относится к загруженным пакетам, архивам и менеджерам зависимостей.
- Инкрементальная сборка избегает повторной работы, когда система видит, что входы и зависимости не изменились.
Каталог с файлами не доказывает, что именно Compilation Caching сократил работу компилятора. Для решения нужен наблюдаемый эффект в одинаковом эксперименте.
Подходит ли кэш для Clean Build и многоветочных проектов
Для Clean Build кэш может быть полезен, если очистка удаляет локальные промежуточные результаты, но не уничтожает отдельное хранилище Compilation Caching. Однако итог зависит от того, какие входы проект считает изменившимися. Смена схемы, флагов, SDK, версии компилятора, настроек оптимизации или зависимостей способна превратить ожидаемое попадание в промах.
В многоветочном iOS-проекте сначала определите повторяемость, а не количество веток. Две ветки могут менять общий модуль, заголовки или настройки сборки, поэтому наличие одинакового имени цели ещё не означает совместимость результата. Ветка с частыми изменениями интерфейсов обычно даёт меньше повторно используемых результатов, чем несколько долгоживущих веток с одинаковыми параметрами.
Для удалённого Mac CI особенно важна продолжительность жизни Runner. На постоянном узле кэш имеет шанс накопить полезные результаты. На одноразовом Runner он может быть создан, но уничтожен сразу после задания. В таком случае включённая настройка добавляет сложность, не создавая устойчивого преимущества.
Как отличить попадание кэша от случайно быстрой сборки
Одна быстрая задача ничего не доказывает: измениться могли состояние DerivedData, скорость загрузки зависимостей, очередь заданий или содержимое рабочего каталога. Нужна серия запусков на одном проекте и с фиксированными условиями.
Что проверять через xcodebuild в журнале CI
Вызов xcodebuild должен быть одинаковым в сравниваемых заданиях. Зафиксируйте:
- commit или другой однозначный идентификатор исходного состояния;
- Scheme и цель сборки;
- конфигурацию, SDK и параметры подписи;
- переменные окружения;
- состояние рабочего каталога и способ получения зависимостей;
- тип и состояние удалённого Mac Runner.
Затем сохраните подробный журнал каждой задачи. В настройках диагностики используйте только параметры, которые документированы для вашей версии Xcode, и ищите сообщения, связанные с участием Compilation Caching. Название настройки нельзя переносить из обсуждения для другой версии: сверяйте его с актуальным Build Settings Reference.
По xcodebuild в CI нужно подтвердить не просто наличие каталога, а повторное использование результата. Если журнал не показывает достаточного уровня детализации, включите поддерживаемую диагностику для тестового запуска, не меняя остальные параметры. После этого уберите чрезмерно подробный режим из постоянного контура, если он увеличивает размер логов или раскрывает лишние сведения.
Три контрольных запуска вместо одного среднего времени
Сравните три сценария:
- Первичная сборка после подготовки состояния. Она показывает стоимость заполнения кэша.
- Повторная сборка с тем же входом. Это главный тест потенциального попадания.
- Возврат к исторической ветке или commit. Он показывает, может ли кэш помогать реальному процессу переключения, а не только немедленному повтору.
Для каждого запуска запишите отдельно время компиляции, линковки, тестов, подписи, скриптов и загрузки зависимостей. В Xcode доступен Build Timing Summary; используйте его, чтобы не маскировать компиляцию общей длительностью задания. Методика Apple по измерению времени инкрементальных сборок полезна именно потому, что заставляет разделять этапы, а не сравнивать один итоговый показатель.
Внимание: если повторный запуск быстрее, но компиляционный этап почти не изменился, не называйте это эффектом Compilation Caching. Сначала исключите DerivedData, кэш зависимостей и пропущенные скрипты.
Одинаковое время сборки не означает одинаковую экономию
Оценивайте два уровня результата:
- время этапа компиляции;
- время всей цепочки CI от подготовки рабочего каталога до завершения задания.
Если подпись, тесты, генерация файлов, загрузка зависимостей или пользовательские скрипты занимают большую часть процесса, даже подтверждённое попадание в кэш может почти не изменить итог. Это не делает кэш бесполезным, но меняет экономический расчёт: вы платите за хранение и обслуживание, а выигрываете только на одном сегменте конвейера.
Четвёртый шаг: зафиксируйте эксперимент до включения
Создайте два сопоставимых набора:
- набор A — Compilation Caching выключен;
- набор B — Compilation Caching включён.
Не меняйте проект между наборами. Для каждого режима выполните первичный запуск, повтор с тем же commit и возврат к ранее использовавшемуся состоянию. Если вы параллельно обновляете зависимости, чистите рабочую область или меняете Runner, эксперимент перестаёт отвечать на вопрос о кэше.
Измеряйте не только среднее значение. Отдельно отметьте:
- компиляционное время;
- полное время задания;
- число подтверждённых попаданий и промахов;
- время подготовки и очистки;
- состояние диска до и после серии;
- результат после перезапуска узла.
Сводите результаты по одной и той же процедуре. Не приписывайте Compilation Caching процентное ускорение без опубликованного измерения или собственной записи теста. В этой статье нет данных о конкретной конфигурации MacDate и нет авторизованного теста одного проекта, поэтому точные значения времени, прироста и размера кэша не приводятся.
Для независимой проверки нагрузки применяйте рекомендации Apple по написанию и запуску тестов производительности. Они не обещают эффект Compilation Caching, но помогают не смешивать измерение производительности с субъективным ощущением «сборка стала быстрее».
Постоянный Runner против одноразового: где сохраняется ценность
У постоянного удалённого Mac есть очевидное операционное преимущество: после задания рабочее окружение не исчезает автоматически. Это создаёт условия для повторного использования кэша, но одновременно требует дисциплины. Нужно знать, кто владеет каталогом, какие задачи имеют к нему доступ и когда он очищается.
Одноразовый Runner проще изолировать. После завершения задания старое состояние удаляется, поэтому риск загрязнения ниже. Но Compilation Caching становится малополезным, если между задачами не существует внешнего или постоянного хранилища. Перенос кэша в отдельное хранилище тоже не бесплатен: появляются задержка передачи, управление ключами, совместимость версий и риск восстановления неполного набора артефактов.
Общий узел для нескольких команд требует ещё более строгой политики:
- разделяйте рабочие каталоги и права пользователей;
- не разрешайте одной задаче читать произвольный кэш другой команды;
- привязывайте ключи к проекту, Scheme, настройкам и версии инструментов;
- задайте верхний предел хранения;
- документируйте, что происходит после перезапуска и аварийной очистки.
Остаётся ли кэш после перезапуска самостоятельного Mac Runner
Сам факт перезапуска не даёт универсального ответа. Состояние сохранится только при одновременном выполнении нескольких условий: каталог размещён на постоянном диске, его не удаляет агент подготовки, права доступа не меняются, а процесс очистки не запускается при старте. Если Runner разворачивается заново из чистого образа, прежний кэш обычно не следует считать доступным, пока это не подтверждено журналом и проверкой содержимого.
Проверьте это отдельным сценарием:
- выполните сборку и зафиксируйте признаки заполненного кэша;
- корректно остановите и снова запустите Runner;
- проверьте рабочий каталог и права доступа;
- повторите сборку с тем же входом;
- сравните признаки попадания и Build Timing Summary;
- после этого выполните тот же тест после полного пересоздания среды.
Не путайте перезапуск агента с перезагрузкой операционной системы и с пересозданием диска. Для каждого события нужен отдельный результат.
Как очищать Compilation Caching без разрушения эксперимента
Сначала определите, какой именно кэш вы очищаете. Без этого команда удаления может затронуть DerivedData, пакеты или артефакты, которые нужны другому этапу. Используйте документированный механизм Xcode для версии 26 и внутреннюю процедуру вашей CI-системы. Не удаляйте неизвестные каталоги по маске только потому, что в их имени встречается слово «cache».
Безопасная последовательность выглядит так:
- остановите новые задания на узле;
- дождитесь завершения или отмените активные задачи;
- сохраните журнал и состояние диска;
- проверьте владельца каталога и область действия очистки;
- удалите только подтверждённые устаревшие записи;
- запустите контрольную сборку без кэша;
- повторите сборку с тем же входом и проверьте, что кэш формируется заново.
Если место заканчивается, приоритетом должна быть предсказуемость очистки, а не максимальное заполнение диска. Для общих узлов полезнее небольшая документированная политика удаления, чем неограниченное хранение результатов разных проектов.
Серая эксплуатация: когда разрешать, а когда останавливать
Перед расширением на общий CI пройдите список решений:
- [ ] Зафиксированы commit, Scheme, SDK, параметры сборки и окружение Runner.
- [ ] Для режима с кэшем и без него выполнены первичная и повторная сборки.
- [ ] В журнале есть подтверждение участия Compilation Caching, а не только наличие файлов.
- [ ] Build Timing Summary разделяет компиляцию и остальные этапы.
- [ ] Проверены смена ветки и возврат к прежнему commit.
- [ ] Проверено состояние после перезапуска Runner.
- [ ] Отдельно измерено влияние загрузки зависимостей, тестов, подписи и скриптов.
- [ ] Выполнены чистая сборка и сборка из нового клона.
- [ ] Архив релиза проходит с кэшем и после его отключения.
- [ ] Описаны владелец кэша, права доступа, лимит хранения и процедура очистки.
- [ ] Для аварийного случая есть повтор без кэша на том же проекте.
Оценка должна быть не бинарной. Используйте три оценки:
- Высокая пригодность — входы повторяются, попадания подтверждены, узел сохраняет состояние, диск контролируется, релизный контур имеет независимую проверку.
- Средняя пригодность — ускорение видно только на части веток или повторов; оставьте режим в серой группе и не включайте его для публикации.
- Низкая пригодность — Runner уничтожается после каждого задания, параметры постоянно меняются, кэш не подтверждён или очистка непредсказуема. Оставьте функцию выключенной.
Для релизной сборки сохраните независимый базовый сценарий. Кэш не должен скрывать ошибку скрипта, неявную зависимость или различие между рабочей и чистой средой. Если архив с включённым кэшем успешен, это ещё не доказывает воспроизводимость. Повторите его на новом клоне и без кэша, а затем сравните артефакты и журналы.
Какой узел выбрать после проверки: решение по условиям
Если тест показал подтверждённые попадания, но одноразовая среда уничтожает состояние, сначала рассмотрите постоянный узел, а не бездумное увеличение числа Runner. Для оценки инфраструктуры полезно сравнить физический macOS-узел и виртуализацию macOS: вопрос здесь не только в скорости, но и в сохранении рабочего каталога, правах и предсказуемости перезапуска.
Если нагрузка нестабильна, используйте серый контур с ограниченным числом проектов. Не переносите кэширование на общий узел до проверки изоляции и очистки. Если вам нужно спланировать аренду постоянной среды, сопоставьте условия с тарифами на bare-metal macOS, но не подставляйте цену в расчёт, пока не зафиксированы фактический срок аренды, режим перезапуска и объём хранения.
Текущая схема на Linux или одноразовых CI-исполнителях может быть рациональной для коротких задач, но у неё есть три недостатка именно для Xcode: macOS-специфичная компиляция всё равно требует Mac, одноразовое окружение теряет накопленный кэш, а различия между чистым и сохранённым состоянием усложняют разбор нестабильных сборок. Постоянный физический удалённый Mac не устраняет необходимость контроля, зато лучше подходит, когда вам нужны сохраняемый рабочий каталог, SSH-доступ и повторяемая среда. В таком случае аренда Mac через MacDate может оказаться практичнее покупки отдельного устройства — особенно для временного CI-контура, пилота или проекта с меняющейся нагрузкой. Условия доступной аренды можно проверить на странице удалённых вычислительных узлов MacDate.
Финальное правило простое: не включайте Xcode 26 Compilation Caching только потому, что функция новая. Проведите парный тест на вашем проекте, подтвердите попадания, проверьте сохранение после перезапуска и отдельно примите решение для разработки и релиза. Если текущий Runner каждый раз уничтожает окружение, изучите вариант постоянного удалённого Mac-узла и проведите его приёмку по той же процедуре, прежде чем менять весь CI.