Как я могу условно включить файл, основанный на конфигурации сборки в XCode?

У меня есть проект Xcode с большим количеством целей, в который я хотел бы включить комплект настроек для приложений, созданных в конфигурациях Ad-hoc и Debug, но не в конфигурации Release.

Фазы сборки, по-видимому, не позволяют сделать себя зависимыми от конфигурации (очевидно, они могут зависеть от цели, но удвоение количества целей в проекте сделает его полностью непригодным для использования).

Это оставляет написание пользовательского правила сборки. Мой план состоит в том, чтобы исключить файл Settings.bundle из всех целей и создать правило сборки, которое условно копирует его в пакет продукта, но найти подходящие примеры действительно сложно.

Правило сборки, которое я запустил, имеет параметр Process, установленный на "Исходные файлы с совпадающими именами" и Settings.bundle в качестве имени. Параметр использования - "Пользовательский сценарий:".

Мой пользовательский сценарий выглядит следующим образом (с учетом того, что мой сценарий bash находится на уровне культового груза):

if [${CONFIGURATION} = 'Debug'] then
    cp -r ${INPUT_FILE_PATH} ${DERIVED_FILES_DIR}/.
fi

Наконец у меня есть ${DERIVED_FILES_DIR}/Settings.bundle указан как выходной файл.

Поскольку я здесь, должно быть очевидно, что это не работает. Мой первый вопрос: есть ли где-нибудь, где я могу просмотреть вывод правил сборки как execute, чтобы убедиться, что 1) он действительно выполняется и 2) у меня где-то нет глупой синтаксической ошибки.

Кроме того, каково правильное местоположение (в форме переменной окружения), в которое нужно скопировать вывод?

6 ответов

Решение

Я наконец-то понял.

Для каждой цели, для которой вы хотите условно включить пакет настроек, выберите его Проект из списка источников, выберите цель и перейдите на вкладку "Фазы сборки".

Нажмите кнопку "Добавить этап сборки" и выберите "Добавить сценарий запуска".

Затем введите следующее для сценария:

if [ "${CONFIGURATION}" == "Debug" ]; then
    cp -r "${PROJECT_DIR}/Settings.bundle" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app"
fi

Я знаю, что на этот вопрос уже был дан ответ, и этот ответ был очень полезен для меня, но я также хотел добавить свое собственное модифицированное решение.

Мое требование состояло в том, чтобы иметь разные пакеты настроек для разных конфигураций сборки, а не просто не включать их в релиз. Предполагая упрощенный подход только к конфигурациям Debug и Release, вот как это сделать:

Начните с добавления двух пакетов настроек в проект с именем Settings-debug.bundle а также Settings-release.bundle а затем удалите эти файлы из фазы сборки Копировать комплект ресурсов. Затем добавьте пользовательский параметр сборки под названием SETTINGS_BUNDLE, который имеет разные значения для каждой конфигурации:

Debug        ${PROJECT_DIR}/relative/path/to/Settings-debug.bundle
Release      ${PROJECT_DIR}/relative/path/to/Settings-release.bundle

Затем добавьте фазу сборки сценария выполнения (после ресурсов Копировать комплект) с именем Копировать комплект настроек с измененной версией скрипта в решении Фрэнка.

cp -r "${SETTINGS_BUNDLE}/" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Settings.bundle"

Разница здесь в том, что скопированный пакет всегда называется Settings.bundle независимо от имени источника.

Затем вам нужно добавить еще один сценарий фазы сборки, чтобы предотвратить ошибки подписывания кода, когда единственные изменения находятся в комплектах настроек. Это заставляет шаг подписи кода происходить при каждой сборке. Это должно быть выполнено до фазы компиляции исходных файлов. Я назвал мой Force Codesign.

touch "${PROJECT_DIR}/relative/path/to/main.m"

Для согласованных источников существует плохо задокументированный пользовательский параметр сборки, который можно добавить. Файлы могут быть как исключены, так и включены из компиляции

Перейдите в настройки сборки вашей цели> Нажмите кнопку +> Добавить пользовательские настройки

Ключ либо INCLUDED_SOURCE_FILE_NAMES или же EXCLUDED_SOURCE_FILE_NAMES

Значение представляет собой разделенный пробелами список путей к файлам

См. Ссылку: http://lists.apple.com/archives/xcode-users/2009/Jun/msg00153.html

(Протестировано с Xcode 9.3)

Я не могу найти, когда Xcode включил эту функцию, но EXCLUDED_SOURCE_FILE_NAMES теперь доступен напрямую в Build Settings > Build Options > Excluded Source File Names,

Таким образом, вам больше не нужно создавать User-Defined Setting,

Увидеть ниже:

Он автоматически добавит эту строку в ваш .pbxproj,

Settings.bundle всегда копируется в область назначения независимо от того, была ли выбрана конфигурация Release или Debug. Итак, может быть, вам нужен следующий код:

if [ ${CONFIGURATION} == "Release" ]; then
    rm -rf ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Settings.bundle
fi

Я не эксперт по сценариям оболочки, но думаю, вам нужно пространство между квадратными скобками и условием. Кроме того, цитирование переменных может помочь:

if [ "${CONFIGURATION}" = "Debug" ] then
    cp -r "${INPUT_FILE_PATH}" "${DERIVED_FILES_DIR}"/.
fi

Что касается местоположения, я использую "$BUILT_PRODUCTS_DIR"/"$FULL_PRODUCT_NAME" для корня моего пакета приложений OS X.

Другие вопросы по тегам