Xcode有时会自动找到依赖项。当我是定义关系的人并且懒惰时,我认为可以。
但是我比以往更经常地面对一个有多个目标的现有(中型至大型)项目。由于该项目是由其他人完成的,因此我发现很难理解哪些目标取决于什么,因为并非所有关系都是明确的。
Xcode用于查找此类关系的规则是什么? (我希望我能理解这个逻辑,所以请在我脑海中运行它,也许将来可以节省我一些时间)或是什么使一个目标有资格隐式地依赖于另一个目标?
资料来源:iOS Developer Library → Xcode Concepts → Xcode Target
这个答案适用于Xcode 8.x,我认为适用于Xcode 9.0。
首先,您需要确保要尝试构建的Scheme的Build面板中启用了“Find Implicit Dependencies”。
可以通过两种方式使目标“A”“隐式”依赖于目标“B”:
目标A的构建阶段为“链接库的二进制文件”,该库的列表中包含一个与B产品的名称相同的与相同的库。此产品可以位于工作区中的同一项目中,也可以位于另一个项目中。请注意,我说的是“相同的名字”。仅仅因为您从目标A中选择了libA.a并不意味着如果您在另一个目标中有另一个libA.a产品,则隐式依赖关系将建立它。有关详情,请参见下文。 目标A具有“复制文件阶段”,该文件复制具有基本名称且与B的乘积匹配的文件。通常,“复制文件”构建阶段不能引用与其项目不在同一项目中的文件目标,但是如果您为要复制的“复制文件”阶段创建一个虚拟文件而创建了一个与B产品同名的虚拟文件,则可以在项目之间建立依赖关系。例如,如果您有一个包含两个项目的工作区ProjectA和ProjectB。 ProjectA具有创建libA.a的TargetA,而ProjectB具有创建libB.a的TargetB。 TargetA可以通过将恰好名为libB.a的“假”零字节文件作为TargetA的一部分来使TargetB生成libB.a,即使已引用libB.a,这也足以获得libB.a。在“复制文件”阶段中,与TargetB构建的产品输出完全不同的文件。如果选中“仅在安装时复制”框,则Xcode实际上不会执行复制,但仍会解决依赖关系。实际上,您可以从专门创建的驱动器上删除伪造文件,以便将其放入“复制文件”阶段(但必须将其保留在项目中)。
那么,为什么会有人想做一个“2”的恐怖呢?我可以提出几个原因。
TargetA需要一些由TargetB复制/生成的文件,但是TargetB不会生成要链接的库。您可以通过让TargetB生成一个小的虚拟库来解决此问题,但是由于其他原因,这可能会很痛苦。 假设我有projectA,targetA和libA.a(以及项目B,C和D的等效项),而libA.a依赖于libB.a和libC.a,这两个都需要首先构建libD.a(可能是一些) header 和/或生成的源)。您可以使用“与库链接”阶段(也称为解决方案#1)来完成所有操作,但在这种情况下,最终会得到libA最终链接版本中libD中.o文件的两个副本。如果您做得足够深(例如,一个工作空间中有40个项目,它们之间的依赖程度各不相同),您很快就会得到巨大的库文件,其中包含几个相同的.o文件,链接时间将变得很恐怖。
如果您认为这些是人为的情况,那么我目前正在将两者都击中,将一些遗留代码从一系列显式依赖项移至隐式依赖项。为什么要转向隐式依赖项?因为Xcode中的显式依赖项需要项目嵌套,并且一旦获得足够的显式依赖项,项目浏览器就会变得非常慢,并且您会在Xcode内看到很多随机事件。
如果您在同一个工作空间中碰巧有两个目标生成的产品具有相同的名称并依赖于第三个目标的依赖,会发生什么?隐式依赖项将选择一个。它似乎根据产品的基本名称进行匹配(因此foo/bar.a和baz/bar.a相同),并将选择找到的第一个。