Подтвердить что ты не робот

Как добавить значения в переменные xcconfig?

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

Я попробовал следующее (как и многие варианты этого), но пока не повезло:

GCC_PREPROCESSOR_DEFINITIONS = '$(GCC_PREPROCESSOR_DEFINITIONS) NEW_VALUE'

Символ NEW_VALUE просто не добавляется к определениям препроцессора.

Кто-нибудь успел добавить новые значения в переменные в файлах xcconfig?

4b9b3361

Ответ 1

По причинам, изложенным в других ответах на этот вопрос, вы не можете легко наследовать ценности.

Я рекомендую определить ваши настройки в каскаде. Предположим, что 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, идите туда, чтобы узнать больше.

Ответ 2

В соответствии с Системным руководством по построению Xcode:

Когда блок конфигурации содержит более одного определения для конкретная настройка сборки, Xcode использует последнее определение в блоке. Держать в виду, что файлы конфигурации не иметь доступа к настройке сборки определения, сделанные в конфигурации файлы, которые они включают. Это ты не может изменить определение, сделанное в включенный файл конфигурации; вы может только заменить его.

Итак, я думаю, это означает, что невозможно добавить значения к данной переменной.

Ответ 3

Это работает:

xcodebuild GCC_PREPROCESSOR_DEFINITIONS='$(value) NEW_VALUE'

Ответ 4

Существует другой вопрос с ответом, который может помочь в этой конкретной проблеме. Он описывает технику, в которой каждый слой составляет подмножество определений, а затем объединяет их все вместе на xcconfig на уровне листа.

Ответ 5

Я думаю, что я наткнулся на немного лучший подход, пытаясь интегрировать файлы xcconfig Cocoapods в свои собственные. Мне нравится указывать в моих проектах следующее:

GCC_PREPROCESSOR_DEFINITIONS = CONFIGURATION_$(CONFIGURATION)

К сожалению, это противоречит определениям, которые поставляются с Pods.xcconfig. Как сказано в другом месте, $(унаследованный) работает не так, как ожидалось. Что делает следующая работа

GCC_PREPROCESSOR_DEFINITIONS[config=*] = CONFIGURATION_$(CONFIGURATION) $(inherited)

UPDATE:

Если вам нужно переопределить параметр для конкретной конфигурации, тогда у вас возникнет соблазн написать что-то вроде

GCC_PREPROCESSOR_DEFINITIONS[config=*] = CONFIGURATION_$(CONFIGURATION) $(inherited)
GCC_PREPROCESSOR_DEFINITIONS[config=Debug] = DEBUG=1 CONFIGURATION_$(CONFIGURATION) $(inherited)

К сожалению, это не сработает, но добавление второго объявления в файл, загружаемый только конфигурацией Debug, будет правильно отменять настройку.

Ответ 6

Как указано в других ответах, до 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 оператор #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).

Ответ 7

Это работает для меня в Xcode 2.4.1:

GCC_PREPROCESSOR_DEFINITIONS = "$(GCC_PREPROCESSOR_DEFINITIONS) NEW_VALUE"

Вам нужно иногда разрешать несколько секунд между редактированием файла конфигурации и изменением в целевой информации о сборке.

Ответ 8

Вы хотите использовать заполнитель $(унаследованный) для представления значения, унаследованного от более низких уровней, например

GCC_PREPROCESSOR_DEFINITIONS = "$(inherited) NEW_VALUE"