【发布时间】:2017-04-13 07:06:32
【问题描述】:
TL;DR
是否可以从父项目继承自定义配置?不,不是询问是否继承某些目标设置。
配置和预处理器宏/标志
Xcode 中的每个项目都使用两个标准配置 进行初始化,称为Debug 和Release。在构建设置中使用显示名称Preprocessor Macros 下的设置为目标设置DEBUG 标志是一种非常常见的模式(在.pbxproj 中,这称为GCC_PREPROCESSOR_DEFINITIONS),可以从Objective-C 读取像这样的代码。
#ifdef DEBUG
print("DEBUG flag set")
#else
print("No debug flag!")
#endif
这也适用于 Swift,但是我们必须使用 OTHER_SWIFT_FLAGS 并像这样声明它:-D DEBUG
并像我们在上面的 Objective C 代码中那样读取变量值。
许多项目 => xcconfig 文件
我的应用由一个 xcworkspace 和一个主项目和几个作为依赖项的项目组成。我们将我的应用所依赖的项目称为 框架。由于我有几个框架,我不想多次设置构建设置。
因此我使用xcconfig 文件。我有一个主配置,即主项目的配置文件,我们称之为Main.xcconfig。我有另一个名为Framework.xcconfig 的配置文件,它以#include "Main.xcconfig" 行开头,因此继承了Main 的设置。当然,我设置了每个 框架 以使用上述 Framework.xcconfig 文件。
当我们有这些配置文件时,声明DEBUG标志非常方便,我们在Main.xcconfig中添加:
OTHER_SWIFT_FLAGS[config=Debug] = -D DEBUG
GCC_PREPROCESSOR_DEFINITIONS[config=Debug] = DEBUG
因此为主项目和框架项目的配置 Debug 声明DEBUG 标志(因为Framework.xcconfig 继承自Main.xcconfig...)。
自定义配置
如果我们希望能够分析应用但设置了DEBUG 标志怎么办?分析应该使用与Release 相同的优化标志。但我们绝对不想为Release 构建设置DEBUG 标志。
为什么不创建一个新的配置,我们称之为Profiling。 问题来了!当然我们应该为主项目创建这个新的配置。然后我们编辑我们的方案并为 Profile 和下
构建配置我们选择了新的配置Profiling。
现在我们可以在Main.xcconfig 文件中为Profiling 设置DEBUG 标志。
OTHER_SWIFT_FLAGS[config=Debug] = -D DEBUG // we keep this
GCC_PREPROCESSOR_DEFINITIONS[config=Debug] = DEBUG // we keep this
OTHER_SWIFT_FLAGS[config=Profiling] = -D DEBUG
GCC_PREPROCESSOR_DEFINITIONS[config=Profiling] = DEBUG
我们尝试运行模拟器,我们看到“没有调试标志!”,这是预期的,因为运行时我们使用Debug 配置,因此没有声明DEBUG 标志。
所以我们尝试分析并开始一些仪器测量和open the console。在那里我们看到消息“DEBUG flag set”
很好用,太棒了!
配置不是从父项目继承的
我们刚刚检查了 Main 项目中的 DEBUG 标志。如果我们在某些框架中想要检查我们的标志会发生什么。所以我们在一些框架中尝试#ifdef DEBUG。这行得通,因为所有框架都有配置 Debug,因为它是所有项目的默认配置(连同Release)。
然后我们在我们的一个框架项目中尝试#ifdef DEBUG 并再次开始使用 Instruments 进行分析。现在我们看到消息“没有调试标志!”
哦不!
它不工作!为什么不?!好吧,我不知道,但唯一合理的结论必须是我们作为依赖项添加的项目 - 我们的框架 - 不继承 Profiling 配置 来自主项目。
对我来说,这太不可思议了……感觉就像 Xcode 中的一个缺陷。
糟糕的解决方案
除了将相同的配置 Profiling 添加到所有框架项目(至少对于我知道我想检查该标志的框架)之外,我不知道任何其他解决方案。 但这感觉就像一个丑陋的解决方案!。我至少有 10 个框架,而且必须为每个框架添加特定的配置,感觉真的很丑。
替代(糟糕!)解决方案
是的,当然另一种解决方案是使用Release 配置 进行分析,并在Main.xcconfig 中声明DEBUG 标志,如下所示:
OTHER_SWIFT_FLAGS[config=Release] = -D DEBUG
GCC_PREPROCESSOR_DEFINITIONS[config=Release] = DEBUG
但由于我们希望能够在框架中检查DEBUG 标志,我们需要将上面的两行声明标志添加到Frameworks.xcconfig。
当然也可以使用Release 配置 作为方案的构建配置。
然后我们可以将一个名为AppStore 的新配置 添加到我们的主项目中,并且只添加主项目并将其用于归档应用程序。到目前为止这么好?
IT'S A TRAP!
不,这不是一个好主意!因为我刚才说配置是不在项目和父项目之间继承的。因此我们的框架不会继承这个新的AppStore配置,所以当框架被构建/归档时,我看到它们“回退”到Release配置(不是确定您是否可以在某处选择“默认”/“后备”配置?也许它会回退到您用作新配置基础的那个?)。
但由于我们刚刚为 configuration 添加了 DEBUG 标志的声明,因此为 Main 项目和我们所有的框架添加了 Release,它是 Release configuration em> 在我们归档应用程序时用于我们所有的框架 => 我们的生产应用程序将包含调试代码!。这是非常不受欢迎且具有潜在危险的。
好的解决方案?
我不知道...你呢?如果 configurations 可以从父项目继承,那不是很好吗?那将解决一切!苹果...漂亮吗?
【问题讨论】:
-
您可以使用特殊变量
$(inherited)从父级继承配置。你试过这个吗? -
@macmoonshine 你没有在这里混淆吗?我相信你会想到继承的目标设置,对于某个键,例如
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG。我没有直接使用目标设置。我正在使用xcconfig文件,因此将转换为GCC_PREPROCESSOR_DEFINITIONS[Profiling] = $(inherited) DEBUG。问题是 configurationProfiling不适用于我们的框架。这是一个陷阱 22。这是我所追求的配置的继承!不是继承某个目标构建设置(如GCC_PREPROCESSOR_DEFINITIONS)。 -
<SOME_SETTING>[config=<MY_CONFIGURATION>] = <SOME_VALUE>in.xcconfig文件或等效<SOME_SETTING>= <SOME_VALUE>行MY_CONFIGURATIONinTarget Settings不可能如果MY_CONFIGURATION不存在说目标(项目)。Target Settings的情况(即不使用.xcconfig文件时)是不言自明的,因为MY_CONFIGURATION没有行!而在.xcconfig文件中, [config=] 只是失败了,因为它不存在。 再一次,如何确保从父项目继承 MY_CONFIGURATION? -
@Sajjon 你找到解决方案或解决方法了吗?
-
这证明苹果不在乎
标签: ios objective-c swift xcode xcconfig