На 6 октября 2026 года в официальных примечаниях к выпускам Xcode указаны Xcode 27 Beta 6 и Xcode 26.6. Это не означает, что Xcode 27 Beta уже стал стабильной версией; статус выпуска проверяйте по документации Apple.
Симптом → быстрое действие: если сборка сообщает о несовместимости XCFramework, сначала проверьте наличие варианта для целевой платформы, затем — нужного архитектурного среза. После этого установите, какой файл действительно попал в линковку, и сравните результаты локальной и удалённой сборок. Не начинайте с запуска Xcode через Rosetta или объединения бинарников: это может скрыть причину, но не добавить отсутствующий платформенный вариант.
Эта инструкция для сопровождающих SDK и бинарные зависимости, которым нужно выпускать XCFramework для нескольких платформ. Она также пригодится инженерам CI, если локальная сборка проходит, а удалённый Mac выдаёт ошибку компоновки. Разработчикам Apple-платформ она поможет отличить проблему пакета от ошибки выбора цели или различий среды.
Диагностика ошибки архитектуры XCFramework в Xcode 27 Beta
Важен не только текст ошибки, но и этап, на котором она появляется. Сообщение компилятора, ошибка линковщика и сбой запуска приложения указывают на разные уровни проблемы. Запишите имя упавшего Target, схему, конфигурацию, destination и полный вывод сборки: обрезанная строка из интерфейса часто не показывает имя файла или архитектуру, которые нужны для проверки.
Сначала воспроизведите сбой на том же коммите и с тем же destination, что использует CI. Если локально выбран симулятор, а удалённый агент собирает приложение для устройства, сравнение не изолирует среду: различие может быть вызвано целями, а не Xcode. Аналогично, успешная сборка другой схемы не доказывает, что проблемный Target использует тот же пакет.
Как локализовать сообщение о несовпадении архитектуры в Xcode 27 Beta? Разделите проверку на три вопроса: соответствует ли пакет платформе, есть ли нужная архитектура в соответствующем варианте и тот ли бинарник выбрал линковщик. Если ответ на первый вопрос отрицательный, проверка архитектур не исправит несовместимость платформы. Если платформенный вариант есть, но нужного среза нет, искать ошибку в пути файла уже недостаточно.
Затем определите фазу отказа. Ошибка No such module чаще требует проверки разрешения зависимости и доступности модуля для конкретного Target. Сообщения о неподдерживаемой платформе или варианте указывают на выбор платформы. Ошибка линковки, называющая архитектуру или объектный файл, требует исследования конкретного бинарника. Не классифицируйте все эти сообщения как «поломку Xcode 27 Beta» до получения воспроизводимого сравнения.
Соответствие платформенного варианта цели
XCFramework может содержать варианты для разных платформ и назначений. iOS-устройство, iOS Simulator, macOS и Mac Catalyst — не взаимозаменяемые цели, даже если в сообщении встречается одна и та же архитектура процессора. Официальное руководство Apple по созданию многоплатформенного бинарного framework bundle описывает сборку и объединение вариантов для соответствующих платформ. При диагностике сверяйте фактическую цель с декларацией пакета, а не выводите совместимость только из имени архитектуры.
Откройте Info.plist внутри XCFramework и проверьте записи AvailableLibraries, включая значения SupportedPlatform, SupportedPlatformVariant, SupportedArchitectures и путь к библиотеке. Для симулятора запись может обозначать платформу и вариант симулятора отдельно; сопоставляйте оба поля с destination. Важно просмотреть все записи, а не первую попавшуюся: пакет может содержать корректный вариант для устройства, но не содержать варианта для симулятора.
Могут ли симулятор iOS и устройство iOS использовать один и тот же бинарный файл XCFramework? Не считайте их взаимозаменяемыми только потому, что архитектуры похожи или совпадают. У пакета должны быть платформенные варианты, соответствующие целям, которые вы действительно собираете. Сверьте объявленные платформу и вариант с выбранным destination, а затем отдельно проверьте архитектуру внутри подходящего бинарника. Такое разделение предотвращает распространённую ошибку: пытаться исправить отсутствие варианта для Simulator добавлением среза устройства.
Если используется Mac Catalyst, проверьте, что пакет собран и поставляется именно для нужной платформы, а не только для macOS или iOS. Если зависимость получена через менеджер пакетов, выясните, какой артефакт разрешился для этой конфигурации: факт присутствия XCFramework в каталоге проекта сам по себе не доказывает, что нужный вариант входит в него.
Проверка архитектурного среза
После подтверждения платформы переходите к бинарнику, указанному в соответствующей записи XCFramework. Сначала получите точный путь из Info.plist, затем проверьте сам файл командой file и список архитектур командой lipo -archs. Для framework сначала найдите исполняемый файл внутри каталога framework; не запускайте проверку только над оболочкой-каталогом. Для библиотеки указывайте файл библиотеки, выбранный в пакете.
Сопоставьте результат с destination и фактическими параметрами сборки. При необходимости выведите настройки конкретной схемы с xcodebuild -showBuildSettings и проверьте ARCHS, EXCLUDED_ARCHS, SUPPORTED_PLATFORMS и другие настройки, влияющие на компиляцию. Их значение зависит от проекта и конфигурации; не копируйте случайное значение из чужого проекта как универсальный фикс. Описание назначения параметров доступно в справочнике настроек сборки Xcode.
Как убедиться, что XCFramework содержит платформу и архитектуру для сборки? Сначала проверьте запись подходящего платформенного варианта в Info.plist, затем разрешите её путь относительно каталога XCFramework и исследуйте именно этот бинарный файл. Наличие нужной архитектуры в другом варианте — например, для устройства вместо симулятора — не удовлетворяет проверку. Сохраните вывод команд вместе с destination: так вы сможете повторить диагностику после обновления зависимости.
Для Apple Silicon Simulator не применяйте запуск Xcode через Rosetta как универсальный способ устранить ошибку. Он не создаст отсутствующий вариант платформы и не добавит архитектуру, которой нет в библиотеке. В технической заметке Apple TN3117 рассматриваются ошибки сборки, связанные с Apple silicon и архитектурой; используйте её для выбора корректного направления исправления, а не как основание исключать arm64 без проверки влияния на остальные цели.
Если необходимого среза действительно нет, исправление должно происходить в поставке зависимости: получите от поставщика сборку с требуемым вариантом, пересоберите её из исходников либо временно удерживайте обновление. Не объединяйте бинарники разных платформ командойЕсли сообщение исчезает после смены destination или способа запуска Xcode, это ещё не подтверждает исправление. Запишите, какой вариант XCFramework был выбран до и после изменения, иначе временный обход может оставить часть целевых сборок без проверки.
lipo, пытаясь получить один «универсальный» артефакт: архитектурная совместимость внутри одного платформенного варианта не превращает этот вариант в другой.
Проверка декларации и фактически связанного файла
В XCFramework есть декларация вариантов и реальные файлы, на которые она ссылается. Эти части должны соответствовать друг другу. Проверьте, что путь из записи AvailableLibraries существует, ведёт к ожидаемому framework или library и относится к версии зависимости, которую вы намеревались собрать. Ищите старую копию пакета, переиспользованный каталог артефактов, ошибочную ссылку на прошлый выпуск и ситуацию, когда опубликованная версия не содержит один из целевых вариантов.
Сверьте журнал линковки с путём из пакета. При необходимости включите подробный вывод сборки и найдите полную команду линковщика и входящие в неё файлы. Проверка каталога исходной зависимости не заменяет эту сверку: проект может хранить одну копию XCFramework, а настройки, скрипт или кэш направлять сборку к другой. Если в логе путь неочевиден, исследуйте настройки Search Paths и сценарии, которые копируют или подменяют артефакты.
Учитывайте формат поставки. Структура и точка входа для framework отличаются от отдельных файлов статической библиотеки; сравнивайте их с тем, как пакет объявляет конкретный вариант. Руководство Apple по созданию многоплатформенного XCFramework используйте как основу для проверки структуры, но окончательное решение принимайте по содержимому и журналу именно вашего артефакта.
При обновлении или скачивании артефакта отдельно подтвердите происхождение и целостность зависимости. В документации Apple о проверке происхождения XCFramework описан подход к проверке источника пакета. Такая проверка не гарантирует наличие нужного платформенного варианта, зато помогает исключить подмену ожидаемой версии другой сборкой.
Сравнение локальной и удалённой сборки
Если локальный Mac собирает проект успешно, а удалённый Mac CI — нет, зафиксируйте одинаковый коммит и одинаковую цель, прежде чем менять окружение. Сравните выбранную версию Xcode, конфигурацию сборки, destination, настройки схемы, источник зависимости и версию бинарного артефакта. Для Swift Package Manager сохраните Package.resolved; для других менеджеров — соответствующие lock-файлы и данные о фактическом разрешении зависимостей.
Сопоставляйте не только номер версии зависимости, но и фактический файл, который был получен и связан. Один и тот же номер релиза не гарантирует идентичное содержимое, если артефакт обновлялся или источник разрешения различается. Зафиксируйте контрольную сумму, если её предоставляет ваш процесс поставки, и сопоставьте её с журналом получения зависимости. Не публикуйте в диагностическом отчёте токены, закрытые ключи и приватные URL; достаточно обезличенных путей, версий, checksum и релевантных строк журнала.
Что делать, если локальная сборка проходит, а удалённый Mac CI не линкует XCFramework? Сначала исключите различие цели: повторите сборку на обеих машинах с одним destination. Затем сравните Xcode, lock-файл и фактически выбранный бинарник. Если расхождение только в содержимом или пути зависимости, исправляйте получение и кэширование артефакта; если набор входных файлов совпадает, исследуйте версии Xcode и настройки сборки. Одного успешного повтора после очистки кэша недостаточно, чтобы считать причину устранённой.
Не делайте вывод о дефекте удалённого Mac по единичному сбою. Повторите сборку из чистого состояния и сохраните команды, конфигурацию, идентификатор коммита и сведения о зависимости. Если ошибка воспроизводится только на CI, соберите обезличенные журналы обеих сред и сравните их построчно вокруг разрешения пакета и вызова линковщика. Такой набор пригодится и для обращения к владельцу библиотеки.
Пошаговое исправление и повторная приёмка
Действуйте в фиксированном порядке, чтобы изменение одного слоя не замаскировало неисправность в другом.
Шаг первый — зафиксируйте исходный сбой. Сохраните полный вывод, коммит, схему, конфигурацию, destination и выбранную версию Xcode. Не меняйте одновременно пакет, параметры архитектуры и окружение: после этого будет трудно установить причину результата.
Шаг второй — подтвердите цель сборки. Разберите, строится ли приложение для iOS-устройства, iOS Simulator, macOS или Mac Catalyst. Сверьте это с настройками Xcode и параметрами команды CI; название job не является доказательством реальной цели.
Шаг третий — проверьте платформенный вариант. Изучите записи XCFramework в Info.plist и найдите вариант, подходящий именно этой платформе и её назначению. Если соответствующей записи нет, запросите совместимый пакет или пересоберите зависимость из доступного исходного кода.
Шаг четвёртый — исследуйте архитектуру реального файла. Для найденного варианта получите путь к бинарнику и проверьте его через file и lipo -archs. Сопоставьте результат с destination, не перенося архитектуру из соседнего платформенного варианта.
Шаг пятый — проверьте фактическую линковку. По подробному журналу установите полный путь файла, переданного линковщику, и убедитесь, что это ожидаемая версия. Проверьте кэш, Search Paths, копирование артефактов и источники зависимостей.
Шаг шестой — сравните локальную и удалённую среду. Запустите один коммит с одной схемой и одним destination, затем сопоставьте выбранный Xcode, настройки и разрешённые зависимости. Изменяйте среду только после того, как подтверждено совпадение артефактов.
Шаг седьмой — повторите все поддерживаемые сборки. Отдельно соберите реальные цели устройства и симулятора, которые поддерживает проект; для macOS или Catalyst добавьте соответствующие проверки, если эти платформы входят в область выпуска. По журналу убедитесь, что каждая сборка выбрала ожидаемый вариант XCFramework. Сохраните версии зависимостей и журналы как исходный уровень для следующей проверки.
Если сторонняя библиотека не содержит нужного варианта или среза, заведите решение по одному из трёх путей: запросить обновление у поставщика, собрать зависимость из исходников либо отложить обновление библиотеки. Не маркируйте проблему как решённую на основании успешной сборки только одной цели. Если поставщик подтверждает совместимость, запросите артефакт и его сведения о платформе и архитектуре, затем повторите приёмку на тех же целях.
| Наблюдение | Что проверить первым | Следующее действие | Диагностическая ценность |
|---|---|---|---|
| Нет записи для платформы или Simulator | SupportedPlatform и SupportedPlatformVariant | Получить или собрать вариант для цели | Высокая: указывает на несовпадение платформы |
| Вариант есть, но нужной архитектуры нет | Архитектуру файла, на который указывает запись | Обновить бинарник или пересобрать зависимость | Высокая: выявляет отсутствующий срез |
| Вариант и архитектура подходят, но линковка падает | Полный путь файла в журнале и настройки поиска | Устранить старый путь или неверный артефакт | Высокая: обнаруживает расхождение декларации и входа |
| Локально проходит, в CI — нет | Destination, Xcode, lock-файл и checksum зависимости | Повторить сопоставимую сборку и выровнять входные данные | Высокая: отделяет окружение от содержимого пакета |
| После запуска Xcode через Rosetta ошибка исчезла | Реальный выбранный вариант и остальные цели | Не считать обход исправлением без повторной приёмки | Низкая: результат не подтверждает полноту пакета |
| Цель приёмки | Подтверждение варианта | Подтверждение архитектуры | Сохранить как базовый результат |
|---|---|---|---|
| iOS Simulator на Apple Silicon | В Info.plist найден вариант Simulator | Фактический бинарник содержит архитектуру, требуемую целью | Destination, версия пакета и журнал линковки |
| iOS-устройство | Найден вариант для устройства, а не только для симулятора | Проверен бинарник именно этого варианта | Коммит, настройки схемы и результат сборки |
| macOS или Mac Catalyst | Найдена запись для нужной платформы | Проверен путь и архитектура связанного файла | Цель сборки, версия артефакта и журнал |
| Удалённый Mac CI | Совпадают цель и разрешённая версия зависимости | CI использует ожидаемый файл и срез | Обезличенное сравнение локальной и CI-сборки |