Як я можу умовно включити файл на основі конфігурації збірки в Xcode?


78

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

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

Це залишає написання власного правила побудови. Я планую виключити Set.bundle з усіх цілей і створити правило збірки, яке умовно копіює його в пакет продуктів, але прикладні приклади дійсно важко знайти.

У створеному мною правилі побудови встановлено параметр Process на "Source files with names matching:" та Settings.bundle як назву. Параметр Використання - "Спеціальний сценарій:".

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

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

Нарешті, я вказав ${DERIVED_FILES_DIR}/Settings.bundleяк вихідний файл.

Оскільки я тут, повинно бути очевидно, що це не працює. Моє перше запитання - чи є десь, що я можу переглядати висновок правил збірки як виконання, щоб переконатися, що 1) воно насправді виконується, і що 2) У мене десь не виникла дурна синтаксична помилка.

Крім того, яке правильне розташування (у вигляді змінної середовища) для копіювання виводу?

Відповіді:


83

Я нарешті зрозумів це.

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

Натисніть кнопку "Додати фазу збірки" та виберіть "Додати сценарій запуску".

Потім введіть для сценарію таке:

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

2
Дякую, я звик підходити до управління файлами plist проекту firebase для різних конфігурацій.
iCoder

45

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

Моєю вимогою було мати різні пакети налаштувань для різних конфігурацій збірки, а не просто не включати їх при випуску. Припускаючи спрощений підхід лише конфігурацій налагодження та випуску , ось як це зробити:

Почніть з додаванням 2 настройки зв'язки в проект, названої Settings-debug.bundleі Settings-release.bundleпотім видалити ці файли з копіюванням Bundle ресурси фази збірки. Далі додайте визначений користувачем параметр збірки SETTINGS_BUNDLE, який має різні значення для кожної конфігурації:

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

Потім додайте етап побудови сценарію запуску (після ресурсів Copy Bundle Resources ) з назвою Copy Settings Bundle із модифікованою версією сценарію у рішенні Франка.

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

Різниця тут полягає в тому, що скопійований пакет завжди називається Settings.bundle незалежно від імені джерела.

Потім вам потрібно додати ще один сценарій фази збірки, щоб запобігти помилкам підписання коду, коли єдині зміни відбуваються в наборах налаштувань. Це змушує крок підписання коду відбуватися при кожній побудові. Це повинно працювати , перш ніж на Compile Source Files етапі складання. Я зателефонував до мого Кодексу дизайну .

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

1
Відмінне рішення для панелі налаштувань програми лише для налагодження у вбудованій програмі налаштувань, саме цього я й шукав. Дуже дякую!
benvolioT

4
Ви також можете написати: cp -r "$ {PROJECT_DIR} / settings_bundle / Settings - $ {CONFIGURATION} .bundle /" "$ {BUILT_PRODUCTS_DIR} / $ {PRODUCT_NAME} .app / Settings.bundle" Це дозволить вам уникати додавання будь-яких користувацький запис збірки і використовуватиме файли 'settings_bundle / Settings-Debug.bundle', 'settings_bundle / Settings-Release.bundle' тощо
Kashif Hisam

Як змінних SETTINGS_BUNDLE я використовував $ {PROJECT_DIR} / $ {PROJECT_NAME} /Resources/Settings.bundle
Йохан

1
І замість того, щоб шукати файли у фазі збірки ресурсів копіювання набору для їх видалення, просто видаліть будь-яке цільове членство для файлів набору в інспекторі файлів. Швидше.
Йохан

27

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

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

Ключ - INCLUDED_SOURCE_FILE_NAMESабоEXCLUDED_SOURCE_FILE_NAMES

Значенням є розділений пробілом список шляхів до файлів

Див. Посилання: http://lists.apple.com/archives/xcode-users/2009/Jun/msg00153.html


1
Я можу підтвердити, що додавання EXCLUDED_SOURCE_FILE_NAMES все ще працює (і все ще недокументоване) в Xcode 8.2..x
Елі Берк,

9

(Перевірено за допомогою Xcode 9.3 )

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

Тому вам більше не потрібно створювати файл User-Defined Setting.

Дивись нижче: введіть тут опис зображення

Він автоматично додасть цей рядок у ваш .pbxproj. введіть тут опис зображення


8

Settings.bundle завжди копіюється в область призначення незалежно від того, чи є ця версія випуску чи налаштування налагоджена. Тож, можливо, вам потрібен такий код:

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

4

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

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

Що стосується розташування, я використовую "$BUILT_PRODUCTS_DIR"/"$FULL_PRODUCT_NAME"для кореневої частини мого набору додатків OS X.


Це створює синтаксичні помилки під час побудови. Рішення Франка, скопійоване та вставлене, працювало ідеально.
Lance

1
Щоб бути цілком справедливим, відповідь цього хлопця була розміщена трьома місяцями раніше.
Щеня,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.