Xcode:从父项目继承“配置”-不可能吗?

16

简而言之

是否可以从父项目继承自定义配置?不,不是在询问如何继承某些目标设置。

配置和预处理器宏/标志

Xcode中的每个项目都初始化了两个名为DebugRelease的标准配置。使用目标(在.pbxproj中称为GCC_PREPROCESSOR_DEFINITIONS)下的显示名称为Preprocessor Macros的设置来设置一个DEBUG标志是一种常见的模式,这可以从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下选择Build Configuration中的新配置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

我们尝试运行模拟器,然后看到了"No debug flag!"的提示,这是预期的,因为我们正在使用Debug配置来运行,因此没有声明DEBUG标志。

所以我们尝试进行分析,并启动一些Instruments测量和打开控制台。在那里,我们看到了消息"DEBUG flag set"

它有效了,太棒了!

配置不会从父项目继承

我们刚刚针对主项目检查了DEBUG标志。如果我们想在某个框架中检查自己的标志会发生什么情况。因此,我们在某个框架中尝试使用#ifdef DEBUG。 这可以工作,因为所有框架都具有配置Debug,因为它是所有项目的默认配置(与Release一起)。

然后我们在一个框架项目中尝试#ifdef DEBUG,并再次使用Instruments进行分析。现在我们看到了消息"No debug flag!"

哦不!它不工作了!为什么?我不知道,但唯一合理的结论就是我们添加为依赖项的项目 - 我们的框架 - 没有从主项目继承 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 的新的 配置,并仅在主项目中使用该配置来归档应用程序。到目前为止还好吗?

这是个陷阱!

不,这不是一个好主意!因为我刚才说过,项目和父项目之间不会继承配置。因此,我们的框架将不会继承这个新的AppStore配置,所以当框架被构建/归档时,我看到它们会“回退”到Release配置(不确定是否可以在某个地方选择“默认”/“回退”配置?也许它会回退到您用作新配置基础的那个配置?)。
但是,由于我们刚刚为主项目和所有框架添加了Release配置DEBUG标志声明,并且在归档应用程序时使用的是Release配置,而所有框架都使用Release配置,因此我们的生产应用程序将包含调试代码!这是非常不希望的,潜在风险很大。

好的解决方案?

我不知道...你知道吗?如果配置可以从父项目继承,那不是很好吗?苹果...拜托了。


你可以使用特殊变量 $(inherited) 从父级继承配置。你试过了吗? - clemens
@macmoonshine,你是否有些混淆了?我认为你是在考虑继承目标设置,例如对于某个键,GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG。我没有直接使用目标设置。我使用的是 xcconfig 文件,因此这将转换为 GCC_PREPROCESSOR_DEFINITIONS[Profiling] = $(inherited) DEBUG。问题在于我们的框架中没有可用的 配置 Profiling。这是一个进退两难的局面。我追求的是配置的继承!而不是某个目标构建设置(如 GCC_PREPROCESSOR_DEFINITIONS)的继承。 - Sajjon
.xcconfig文件中,如果针对所述目标(项目)不存在MY_CONFIGURATION,则无法使用<SOME_SETTING>[config=<MY_CONFIGURATION>] = <SOME_VALUE>或等效的Target Settings行中的<SOME_SETTING>= <SOME_VALUE>。对于Target Settings情况(即不使用.xcconfig文件时),这是自我解释的,因为没有MY_CONFIGURATION行!而在.xcconfig文件中,[config=<MY_CONFIGURATION>]会失败,因为它不存在。再次强调,如何确保从父项目继承MY_CONFIGURATION - Sajjon
@Sajjon 你自那时以来找到了解决方案或变通方法吗? - Mosbah
@Mosbah 不好意思,我没有。 - Sajjon
1
这证明了苹果不关心。 - aleclarson
1个回答

1
作为解决方法:为每个项目和全局创建xconfig文件。在项目的xconfig文件中通过以下方式包含全局文件:

#include "path/to/File.xcconfig"

希望这可以帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接