2

我们的工作项目依赖于一个名为“LibraryAlpha”的动态库。此外,我们的工作项目依赖于一个名为“LibraryBeta”的动态库。而且,恰好“LibraryBeta”也依赖于“LibraryAlpha”。

我们的项目嵌入了由不同构建的.framework,即从单独的.xcodeproj 嵌入目标。

在以下情况下,以这种或其他方式将“LibraryAlpha”的符号和实现(函数和类)两次嵌入我们项目的包中的机会是多少:

  • “LibraryAlpha”的项目目标嵌入到项目的包中,“LibraryAlpha”的项目目标嵌入到“LibraryBeta”的包中。
  • “LibraryAlpha”的项目目标嵌入到项目的bundle中,“LibraryAlpha”的源代码与“LibraryBeta”的源代码静态链接
  • “LibraryAlpha”的项目目标嵌入到项目的包中,“LibraryBeta”仅链接到,没有嵌入,“LibraryAlpha”

此外,通常期望使用 SPM 生成的 .xcodeproj 将依赖项模块作为项目中的单独目标,这些目标链接并嵌入到主(声明其依赖项的那个)模块的包中。所以问题是,如果在我们的项目中我链接并嵌入“LibraryAlpha”不是作为项目“LibraryAlpha”的目标,而是在“LibraryBeta”项目中为“LibraryAlpha”文件生成的目标,会发生什么?

4

2 回答 2

1

管理 .xcodeprojs 目标的复杂依赖关系的正确方法是,在问题的图中,根本不管理它们

  • 存档->导出->安装“LibraryAlpha”
  • 存档->导出->安装“LibraryBeta”,链接到已安装的“LibraryAlpha”
  • 存档->导出->安装任意数量的其他库,这些库都动态链接到“LibraryAlpha”
  • 嵌入并链接到已安装的“LibraryAlpha”、“LibraryBeta”和朋友。

为了简化 Apple 项目中的依赖管理,强烈建议您使用CarthageCocoaPods等依赖管理器。它们不仅将使部署变得轻而易举,而且还有助于消除将框架全局安装到托管操作系统中的需要。


旧的,错误的答案:

  • 将“LibraryAlpha”作为一个单独的 .xcodeproj 有自己的目标来构建自己
  • 让“LibraryBeta”动态链接到特定的“LibraryAlpha”目标而不嵌入
  • 让我们的项目动态链接到“LibraryBeta”和那个特定的“LibraryAlpha”目标,显然,嵌入两者。

这不是 Swift 包管理器在解决依赖关系和生成 .xcodeproj 时所做的事情。SPM 通常最终会将所有源代码放在一个项目中,并在其中为“LibraryAlpha”创建一个目标。

这样就没有多次包含代码,并且一切都在运行时很好地解决了。

这当然不能回答这个问题,这个问题只是出于兴趣。但要记住这一点很重要。

于 2018-03-03T15:09:04.250 回答
1

问题是错误的。其中呈现的一些案例无法在现实生活中重现。

首先,在“一个框架链接和嵌入另一个框架”的问题中提到的概念甚至不是一个东西——事实上,动态链接的整个概念是为了追求在多个用户之间重用相同的共享对象而提升的,无需多次提供(读取、嵌入)相同的代码。

情况1

记住前面的陈述,第一个案例实际上不可能立即在现实生活中重现,因为案例状态

“LibraryAlpha”的项目目标嵌入到“LibraryBeta”的包中。

“LibraryBeta”可能与“LibraryAlpha”的项目目标相关联,为了在运行时使用“LibraryBeta”,可执行文件需要嵌入“LibraryAlpha”。符号的重复在这里是无法实现的,因为“LibraryAlpha”只会在捆绑中出现一次。

案例2

“LibraryAlpha”的源代码与“LibraryBeta”的源代码静态链接

这种情况会导致重复编译的代码。一旦它将以动态库“LibraryAlpha”的形式存在于捆绑包中,并且一旦静态链接到“LibraryBeta”。

警告:

实际上,在这种情况下,您根本无法编译“LibraryBeta”,假设您的任何源代码文件都在顶部声明import LibraryAlpha。Swift 中的模块不能手动声明,它们的源代码必须位于单独的目标中才能被导入。该案例在与“LibraryBeta”相同的模块中提供源代码,因此编译器将出错并显示No such module LibraryAlpha.

案例3

“LibraryBeta”只链接到,没有嵌入,“LibraryAlpha”

实际工作的解决方案,不会导致任何代码重复。

案例4

...链接并嵌入“LibraryAlpha”不是作为项目“LibraryAlpha”的目标,而是在“LibraryBeta”项目中为“LibraryAlpha”文件生成的目标

在这种情况下不会发生代码重复。

奖金回合:

对于第 4 种情况,除非您不重复使用目标。

通过将“LibraryBeta”链接到一个动态库,但嵌入另一个动态库......有两个结果。假设相同的源代码和相同的配置应该产生相同的动态库,相同的 .framework 文件夹具有相同的目标代码,.swiftmodule's,.swiftdoc's,dSYM's 和一切,即使它是不同项目中的两个不同目标。因此,如果生成的 .framework 恰好是 2 个不同项目中的 2 个不同编译作为 2 个不同的目标,那么您的可执行文件(即我们的项目)应该链接到运行时存在的任何 .framework 就好了!

但是,如果“LibraryAlpha”自身目标的输出与“LibraryBeta”的“LibraryAlpha”目标有些不同,那么……模因……我没有费心去检查这种情况下会发生什么。但逻辑提示,无论“LibraryAlpha”包含哪个,都不会正确链接到对面目标,动态链接会失败。如果有人想自己检查这种行为,请成为我的客人。

于 2018-03-04T10:10:54.223 回答