Как добавить значения в переменные xcconfig?
Я использую файлы Xcode и.xcconfig. Я пытаюсь добавить некоторые значения в определения препроцессора, но просто не могу заставить его работать.
Я попробовал следующее (а также многие варианты этого), но пока не повезло:
GCC_PREPROCESSOR_DEFINITIONS = '$(GCC_PREPROCESSOR_DEFINITIONS) NEW_VALUE'
NEW_VALUE
Символ просто никогда не добавляется в определения препроцессора.
У кого-нибудь был успех при добавлении новых значений к переменным в файлах xcconfig?
8 ответов
По причинам, изложенным в других ответах на этот вопрос, вы не можете легко наследовать значения.
Я рекомендую определить ваши настройки в каскаде. Давайте предположим, что APP - это префикс вашего проекта, и сделаем это просто, определив только несколько CFLAGS
platform.xcconfig:
APP_PLATFORM_CFLAGS = -DMAS=1
project.xcconfig:
#include "platform.xcconfig"
APP_PROJECT_CFLAGS = -DBETA=1
таргет-one.xcconfig:
#include "project.xcconfig"
APP_TARGET_CFLAGS = -DSUPER_COOL=1
#include "merge.xcconfig"
таргет-two.xcconfig:
#include "project.xcconfig"
APP_TARGET_CFLAGS = -DULTRA_COOL=1
#include "merge.xcconfig"
merge.xcconfig:
OTHER_CFLAGS = $(inherited) $(APP_PLATFORM_CFLAGS) $(APP_PROJECT_CFLAGS) $(APP_TARGET_CFLAGS)
Затем вы будете основывать каждую из ваших целевых конфигураций сборки на target-xxx.xcconfig
, Реальный проект будет использовать более сложные настройки, используя файл конфигурации для проекта и другой файл для цели, но вы поймете идею.
Кроме того, помните, что $(inherited)
относится к более высокому уровню в иерархии, а не раньше. Например, он наследуется от уровня проекта на целевом уровне. Не уверен, относится ли это к Xcode 4 тоже.
Это упрощение GTM, иди туда, чтобы узнать больше.
Как указано в других ответах, до Xcode 10 файлы xcconfig не могли просто наследовать и расширять значения друг друга. Но,
Начиная с Xcode 10, xcconfig теперь работает так, как можно было бы ожидать: $(inherited)
на самом деле расширить до ранее определенного значения переменной.
Если файл.xcconfig содержит несколько назначений одного и того же параметра сборки, более поздние назначения используют
$(inherited)
или же$(<setting_name>)
будет наследовать от более ранних назначений в.xcconfig. Устаревшая система сборки вызвала каждое использование$(inherited)
или же$(<setting_name>)
пропустить любые другие значения, определенные в.xcconfig. Чтобы определить, влияет ли это улучшение на.xcconfig, запуститеdefaults write com.apple.dt.XCBuild EnableCompatibilityWarningsForXCBuildTransition -bool YES
в терминале заставит Xcode генерировать предупреждение об этой ситуации.
(Примечания к выпуску Xcode 10 beta 1)
Так, например, даны два простых файла.xcconfig:
// Generic.xcconfig
OTHER_SWIFT_FLAGS = $(inherited) -DMY_GENERIC_FLAG
// Debug.xcconfig
#include "Generic.xcconfig"
OTHER_SWIFT_FLAGS = $(inherited) -DMY_DEBUG_FLAG
Предполагая, что ваш проект использует Debug.xcconfig для своей конфигурации Debug, вы получите ожидаемое значение -DMY_GENERIC_FLAG -DMY_DEBUG_FLAG
за OTHER_SWIFT_FLAGS
,
(вместо просто -DMY_DEBUG_FLAG
в Xcode 9 и более ранних выпусках)
Новое поведение довольно просто: $(inherited)
просто заменяется ранее определенным значением переменной, если оно есть.
Так что в предыдущем примере, если мы расширим #include
оператор, мы получим следующий файл xcconfig:
// Merged xcconfig files after resolving #include
OTHER_SWIFT_FLAGS = -DMY_GENERIC_FLAG
OTHER_SWIFT_FLAGS = $(inherited) -DMY_DEBUG_FLAG
- На первой линии
OTHER_SWIFT_FLAGS
значение-DMY_GENERIC_FLAG
($(inherited)
расширяется до нуля, потому что это первое определениеOTHER_SWIFT_FLAGS
мы сталкиваемся с1). - На второй линии
OTHER_SWIFT_FLAGS
если перезаписано, и его значение сейчас-DMY_GENERIC_FLAG -DMY_DEBUG_FLAG
(его предыдущее значение + вновь добавленный флаг).
На более сложной установке xcconfig все может выглядеть так:
// First.xcconfig
OTHER_SWIFT_FLAGS = $(inherited) -DMY_FIRST_FLAG
// Second.xcconfig
OTHER_SWIFT_FLAGS = $(inherited) -DMY_SECOND_FLAG
// Last.xcconfig
#include "Generic.xcconfig"
OTHER_SWIFT_FLAGS = $(inherited) -DMY_LAST_FLAG
// Merge.xcconfig
#include "First.xcconfig"
#include "Second.xcconfig"
OTHER_SWIFT_FLAGS = $(inherited) -DMY_INTERMEDIATE_FLAG
#include "Last.xcconfig"
Предположим, на этот раз мы используем Merge.xcconfig в нашей конфигурации.
Разрешенное значение для OTHER_SWIFT_FLAGS
будет тогда -DMY_FIRST_FLAG -DMY_SECOND_FLAG -DMY_INTERMEDIATE_FLAG -DMY_LAST_FLAG
,
Поначалу это может удивлять, но на самом деле это имеет смысл: как только #include
решены, мы в конечном итоге с этим xcconfig:
OTHER_SWIFT_FLAGS = $(inherited) -DMY_FIRST_FLAG
OTHER_SWIFT_FLAGS = $(inherited) -DMY_SECOND_FLAG
OTHER_SWIFT_FLAGS = $(inherited) -DMY_INTERMEDIATE_FLAG
OTHER_SWIFT_FLAGS = $(inherited) -DMY_LAST_FLAG
Окончательное разрешенное значение - это значение, определенное в последней строке, которое -DMY_LAST_FLAG
плюс значение, унаследованное от предыдущей строки -DMY_INTERMEDIATE_FLAG
и т. д.
Обратите внимание, что, естественно, если вы забудете $(inherited)
в одном из определений вы разорвете цепочку наследования и получите значения только из нижних определений, до определения без $(inherited)
,
1 Можно ожидать, что файл xcconfig унаследует предыдущие значения, определенные на уровне проекта, но, похоже, это не так
Начиная с Xcode 10 beta 1, кажется, что редактор настроек сборки неправильно разрешает правильное значение для переменных, определенных в файлах xcconfig, и отображает значения, как если бы они были разрешены с использованием старого поведения до Xcode 10. Я подал rdar://40873121 относительно этого ( https://openradar.appspot.com/radar?id=4925869923500032).
Согласно Руководству по системе Xcode Build:
Когда модуль конфигурации содержит больше чем одно определение для определенного параметра сборки, XCode использует последнее определение в модуле. Имейте в виду, что файлы конфигурации не имеют доступа к определениям параметров сборки, сделанным в файлах конфигурации, которые они включают. То есть вы не можете изменить определение, сделанное во включенном файле конфигурации; Вы можете только заменить его.
Итак, я думаю, это означает, что невозможно добавить значения к данной переменной.
Это работает:
xcodebuild GCC_PREPROCESSOR_DEFINITIONS='$(value) NEW_VALUE'
Есть еще один вопрос с ответом, который может помочь с этой конкретной проблемой. В нем описывается методика, при которой каждый слой составляет подмножество определений, а затем объединяет их все вместе на уровне листа xcconfig.
Я думаю, что наткнулся на немного лучший подход, пытаясь интегрировать файлы Cocoapods xcconfig в свои собственные. Мне нравится устанавливать следующее в моих проектах
GCC_PREPROCESSOR_DEFINITIONS = CONFIGURATION_$(CONFIGURATION)
К сожалению, это противоречит определениям, которые входят в Pods.xcconfig. Как указано в другом месте $(наследуется) не работает, как ожидалось. Что работает, это следующее
GCC_PREPROCESSOR_DEFINITIONS[config=*] = CONFIGURATION_$(CONFIGURATION) $(inherited)
ОБНОВИТЬ:
Если вам нужно переопределить настройку для конкретной конфигурации, вы бы захотели написать что-то вроде
GCC_PREPROCESSOR_DEFINITIONS[config=*] = CONFIGURATION_$(CONFIGURATION) $(inherited)
GCC_PREPROCESSOR_DEFINITIONS[config=Debug] = DEBUG=1 CONFIGURATION_$(CONFIGURATION) $(inherited)
К сожалению, это не сработает, НО, если поместить второе объявление в файл, который загружается только с помощью конфигурации Debug, корректно переопределит настройку.
Это работает для меня в Xcode 2.4.1:
GCC_PREPROCESSOR_DEFINITIONS = "$ (GCC_PREPROCESSOR_DEFINITIONS) NEW_VALUE"
Иногда вам нужно подождать несколько секунд между редактированием файла конфигурации и изменением, отображаемым в информации о сборке цели.
Вы хотите использовать заполнитель $(наследуемый) для представления значения, унаследованного от более низких уровней, например
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited) NEW_VALUE"