xcode - ¿Cómo agregar valores en variables xcconfig?
(8)
Como se indica en otras respuestas, antes de Xcode 10, los archivos xcconfig no podían simplemente heredar y ampliar los valores de los demás. Pero,
Ya que Xcode 10 beta 1 xcconfig ahora funciona como uno podría esperar, y $(inherited)
realidad se expande al valor definido previamente de la variable.
Cuando un archivo .xcconfig contiene múltiples asignaciones de la misma configuración de compilación, las asignaciones posteriores que usan
$(inherited)
o$(<setting_name>)
heredarán de las asignaciones anteriores en .xcconfig. El sistema de compilación heredado causaba que cada uso de$(inherited)
o$(<setting_name>)
cualquier otro valor definido dentro de .xcconfig. Para detectar si su .xcconfig se ve afectado por esta mejora, ejecute losdefaults write com.apple.dt.XCBuild EnableCompatibilityWarningsForXCBuildTransition -bool YES
en Terminal hará que Xcode genere una advertencia sobre esta situación.
(Notas de la versión Xcode 10 beta 1)
Entonces, por ejemplo, dado dos simples archivos .xcconfig:
// Generic.xcconfig
OTHER_SWIFT_FLAGS = $(inherited) -DMY_GENERIC_FLAG
// Debug.xcconfig
#include "Generic.xcconfig"
OTHER_SWIFT_FLAGS = $(inherited) -DMY_DEBUG_FLAG
Suponiendo que su proyecto utiliza Debug.xcconfig para su configuración de depuración, obtendrá el valor esperado -DMY_GENERIC_FLAG -DMY_DEBUG_FLAG
para OTHER_SWIFT_FLAGS
.
(en lugar de solo -DMY_DEBUG_FLAG
en Xcode 9 y versiones anteriores)
El nuevo comportamiento es bastante sencillo: $(inherited)
simplemente se reemplaza por el valor previamente definido de la variable, si corresponde.
Entonces, en el ejemplo anterior, si expandimos la instrucción #include
, obtendremos el siguiente archivo xcconfig:
// Merged xcconfig files after resolving #include
OTHER_SWIFT_FLAGS = -DMY_GENERIC_FLAG
OTHER_SWIFT_FLAGS = $(inherited) -DMY_DEBUG_FLAG
- En la primera línea, el valor de
OTHER_SWIFT_FLAGS
es-DMY_GENERIC_FLAG
($(inherited)
expande a nada, porque esta es la primera definición deOTHER_SWIFT_FLAGS
que encontramos 1 ). - En la segunda línea
OTHER_SWIFT_FLAGS
si se sobrescribe, y su valor ahora es-DMY_GENERIC_FLAG -DMY_DEBUG_FLAG
(su valor anterior + el indicador recién agregado).
En una configuración xcconfig más compleja, las cosas podrían verse así:
// 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"
Supondremos que esta vez estamos usando Merge.xcconfig en nuestra configuración.
El valor resuelto para OTHER_SWIFT_FLAGS
será -DMY_FIRST_FLAG -DMY_SECOND_FLAG -DMY_INTERMEDIATE_FLAG -DMY_LAST_FLAG
.
Esto puede ser sorprendente al principio, pero en realidad tiene sentido: una vez que se resuelve el #include
, terminamos con este 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
El valor final resuelto es el definido en la última línea, que es -DMY_LAST_FLAG
más el valor heredado de la línea anterior -DMY_INTERMEDIATE_FLAG
etc.
Tenga en cuenta que, naturalmente, si olvida $(inherited)
en una de las definiciones, romperá la cadena de herencia y solo obtendrá los valores de las definiciones inferiores, hasta la definición sin $(inherited)
.
1 Se puede esperar que el archivo xcconfig herede valores previos definidos en el nivel del Proyecto, pero no parece ser el caso
📡 A partir de Xcode 10 beta 1, parece que el editor de configuración de compilación no resuelve correctamente el valor correcto para las variables definidas en los archivos xcconfig, y muestra los valores como si se resolvieran con el antiguo comportamiento anterior a Xcode 10. Archivé rdar: // 40873121 con respecto a esto ( https://openradar.appspot.com/radar?id=4925869923500032 ).
Estoy usando archivos Xcode y .xcconfig. Estoy intentando agregar algunos valores en las definiciones del preprocesador, pero simplemente no puedo hacer que funcione.
Intenté lo siguiente (así como muchas variaciones de esto), pero hasta ahora no tuve suerte:
GCC_PREPROCESSOR_DEFINITIONS = ''$(GCC_PREPROCESSOR_DEFINITIONS) NEW_VALUE''
El símbolo NEW_VALUE
simplemente nunca se agrega a las definiciones del preprocesador.
¿Alguien tuvo éxito al agregar nuevos valores a las variables en los archivos xcconfig?
Creo que he tropezado con un enfoque un poco mejor al tratar de integrar los archivos Cocoapods xcconfig en los míos. Me gusta establecer lo siguiente en mis proyectos
GCC_PREPROCESSOR_DEFINITIONS = CONFIGURATION_$(CONFIGURATION)
Lamentablemente, esto entra en conflicto con las definiciones que vienen con Pods.xcconfig. Como se indica en otra parte, $ (heredado) no funciona como se esperaba. Lo que funciona es lo siguiente
GCC_PREPROCESSOR_DEFINITIONS[config=*] = CONFIGURATION_$(CONFIGURATION) $(inherited)
ACTUALIZAR:
Si necesita anular una configuración para una configuración en particular, estaría tentado de escribir algo como
GCC_PREPROCESSOR_DEFINITIONS[config=*] = CONFIGURATION_$(CONFIGURATION) $(inherited)
GCC_PREPROCESSOR_DEFINITIONS[config=Debug] = DEBUG=1 CONFIGURATION_$(CONFIGURATION) $(inherited)
Lamentablemente, esto no funcionará, pero al colocar la segunda declaración en un archivo que solo se carga por la configuración de depuración anulará correctamente la configuración.
De acuerdo con la Guía del sistema Xcode Build:
Cuando una unidad de configuración contiene más de una definición para una configuración de construcción particular, Xcode usa la última definición en la unidad. Tenga en cuenta que los archivos de configuración no tienen acceso a las definiciones de configuración de compilación realizadas en los archivos de configuración que incluyen. Es decir, no puede modificar la definición hecha en un archivo de configuración incluido; solo puedes reemplazarlo.
Entonces, supongo que esto significa que no es posible agregar valores a una variable dada.
Desea utilizar el marcador de posición $ (heredado) para representar el valor heredado de los niveles inferiores, por ejemplo
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited) NEW_VALUE"
Esto funciona para mí en Xcode 2.4.1:
GCC_PREPROCESSOR_DEFINITIONS = "$(GCC_PREPROCESSOR_DEFINITIONS) NEW_VALUE"
En ocasiones, debe esperar unos segundos entre la edición de un archivo de configuración y el cambio que aparece en la Información de compilación de un objetivo.
Esto funciona:
xcodebuild GCC_PREPROCESSOR_DEFINITIONS=''$(value) NEW_VALUE''
Hay otra pregunta con una respuesta que podría ayudar con este problema en particular. Describe una técnica que hace que cada capa componga un subconjunto de definiciones, luego júntelas todas en el nivel de hoja xcconfig.
Por las razones expuestas en otras respuestas a esta pregunta, no puede heredar valores fácilmente.
Recomiendo definir tu configuración en cascada. Supongamos que APP es el prefijo de tu proyecto y haz que esto simple defina solo algunos CFLAGS:
platform.xcconfig:
APP_PLATFORM_CFLAGS = -DMAS=1
project.xcconfig:
#include "platform.xcconfig"
APP_PROJECT_CFLAGS = -DBETA=1
target-one.xcconfig:
#include "project.xcconfig"
APP_TARGET_CFLAGS = -DSUPER_COOL=1
#include "merge.xcconfig"
target-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)
Luego, basará cada una de las configuraciones de generación de sus objetivos en target-xxx.xcconfig
. Un proyecto real utilizará configuraciones más complejas, utilizando un archivo de configuración para el proyecto y otro diferente para el objetivo, pero se entiende la idea.
Además, recuerde que $(inherited)
refiere a un nivel más alto en la jerarquía, no antes . Por ejemplo, hereda del nivel de Proyecto en el nivel de Destino. No estoy seguro de si esto se aplica a Xcode 4 también.
Esta es una simplificación de GTM , vaya allí para obtener más información.