Как добавить значения в переменные 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"
Другие вопросы по тегам