2026-05-09 Пути хранилища компиляторного индекса Xcode (INDEX_DATA_STORE_PATH / INDEX_STORE_PATH), изоляция параллельных CI-полос и щадящая к NVMe практика на арендованном облачном Mac Apple Silicon (HK / JP / KR / SG / US)
Параллельные полосы xcodebuild усиливают всё — в том числе шарды компиляторного индекса, тихо нагружающие арендованные NVMe при пересечении каталогов. Xcode держит индекс рядом с DerivedData; Apple описывает связь в документе «Сборка приложения в Xcode». Операционные команды сочетают это с изоляцией DerivedData/TMPDIR, квотами параллелизма и читаемыми логами + xcresult, чтобы красные сборки оставались объяснимыми при высокой нагрузке на метаданные APFS. Материал 2026-05-09 фиксирует шаблоны путей, удержание и случаи для COMPILER_INDEX_STORE_ENABLE=NO.
Почему раздельные корни индекса всё ещё важны в пайплайнах Xcode 2026
Инкрементальная компиляция выигрывает от прогретых индексов, но CI-флоты редко повторяют уютные однопользовательские допущения настольных машин. Арендованные хосты одновременно мультиплексируют PR; столкновения дают непрозрачные зависания сканера зависимостей Clang или дубли карт модулей. Изолируйте хранилища индекса рядом с DerivedData — не как заплатку после отладки загадочных случаев «чистая сборка проходит, грязная падает».
Анатомия конфликтов хранилища индекса на общих билдерах
- Устаревшие читатели — полоса B читает частично записанные шарды полосы A, когда родительские POSIX-пути общие.
- Усиление copy-on-write — метаданные APFS «штормят», когда очистители одновременно удаляют тысячи атомарно созданных крошечных шардов.
- Сюрпризы симлинков — инженеры переносят DerivedData на более быстрые тома, но забывают про сопутствующие каталоги индекса.
Следите за iostat во время длительных параллельных прогонов; дрожание указывает на горячие точки индекса раньше, чем сдвинутся графики настенного времени.
Канонический шаблон путей в связке с документацией DerivedData
Следуйте базовой линии разделения DerivedData из руководства по изоляции, затем добавляйте поддеревья вроде Index.noindex/DataStore — или явный INDEX_DATA_STORE_PATH, если скриптуете сырые вызовы xcodebuild вне умолчаний IDE. Пример именования:
BASE="${TMPDIR%/}/job-${JOB_UID}"
DERIVED="$BASE/dd"
IDX="$BASE/clang-index"
export DERIVED_DATA_DIR="$DERIVED"
export INDEX_DATA_STORE_PATH="$IDX"
Держать оба под одним родителем TMP упрощает политики выселения и работу с инструментами xcrun.
Флаги: INDEX_DATA_STORE_PATH, INDEX_STORE_PATH, COMPILER_INDEX_STORE_ENABLE
Современные процессы считают INDEX_DATA_STORE_PATH авторитетным корнем, который Xcode передаёт Clang. Задавайте INDEX_STORE_PATH идентично там, где старые Xcode в тонких обёртках всё ещё ждут зеркальную переменную окружения.
COMPILER_INDEX_STORE_ENABLE=NO: эфемерные задачи «скомпилировал и выбросил» — статический экспорт метаданных или скриптовая проверка ассетов — если замерите, что выигрыш по IO перекрывает потерю инкрементального кэша при повторном запуске.
Сочетайте явные флаги с детерминированным xcodebuild -derivedDataPath, чтобы логи xcbeautify при анализе причин указывали на реальные каталоги.
Бюджет параллельных полос на аренде Mac mini M4
В регионах Гонконг, Токио, Сеул, Сингапур, США распределяйте одновременные полосы с учётом объединённой памяти SoC — не только CPU. Каждая дополнительная полоса нелинейно увеличивает разветвление индекса из‑за хеш-каталогов; смягчайте параллелизм, когда растут индикаторы фрагментации APFS.
Инварианты
- Никогда не направляйте два одновременных билда на один и тот же базовый каталог DerivedData.
- После архивации пакетов xcresult убирайте холодные индексы с диска.
- Согласуйте число полос с закреплённой мажорной версией Xcode в каждом пуле.
Графики удержания и запись на NVMe через призму APFS
Каталоги индекса захламляются быстрее объектников: многие шарды остаются после обрывов. Ночные задания, сметающие INDEX_DATA_STORE_PATH старше порога SLA, надёжнее аварийных rm -rf. Сжимайте архивы только после проверки, что компрессоры выдерживают миллионы мелких файлов — часто лучше работают продвижения жёстких ссылок в стиле rsync.
Чеклист запуска за девять шагов
- Инвентаризируйте пересечения DerivedData и индекса по регионам.
- Определите уникальные токены пути из оркестрации.
- Впрысните экспорт переменных в обёртки (GitLab shell, агент Jenkins, shim GitHub Actions).
- Включите структурированные логи по образцу руководства xcbeautify.
- Проведите длительную параллельную репетицию с прокси фрагментации APFS.
- Задокументируйте полосы-оптауты с COMPILER_INDEX_STORE_ENABLE=NO.
- Подключите алерты на превышение недельного бюджета по наклону диска.
- Обучите дежурных анатомии каталогов индекса.
- Выкатите infra PR с tarball отката plist и скриптов обёрток.
Таблица SLO: гигиена компиляторного индекса
| Сигнал | Порог | Действие |
|---|---|---|
| Обнаружен общий родитель индекса | Любая параллельная задача | Быстрый отказ; расширить токены пути |
| Минуты повышенной записи на NVMe | индексация занимает > 12% настенного времени | Выборочно NO + перебалансировать полосы |
| Восстановление после падения | > 30 мин ручной уборки в месяц | Автоматизировать TTL-проходы |
FAQ
| Вопрос | Практический ответ (2026-05-09) |
|---|---|
| Актуально ли для удалённого Xcode Cloud? | Явные корни побеждают неявные значения по умолчанию везде, где воркеры мультиплексируют PR. |
| Идеально чистые хосты на каждый билд? | Даже эфемерным образам нужны уникальные пути индекса на RAM-дисках, чтобы избежать гонок при параллельных смоук-тестах. |
Почему Mac mini M4 на голом железе держит шум индекса предсказуемым
Unified Memory уменьшает скачки PCIe по сравнению с ВМ на переподписанных гипервизорах — писатели индекса Clang дольше остаются горячими в кэше. Масштаб флота согласуйте через региональные тарифы, а зависшие фазы компиляции отлаживайте с опорой на руководства по SSH-доступу.
Бронируйте билдеров, пока шарды не съели квоты NVMe
HK / JP / KR / SG / US · SSH / опционально VNC