为 iOS 将 2 个静态库链接到 1 个

Ale*_*sas 5 xcode ios

我在 Xcode 中创建了两个单独的静态库,用于 iOS,A 和 B。A 使用在 B 中定义的方法。

在创建需要 A 和 B 的新 Xcode 项目时,我可以分别包含它们。然而,为了简化集成,我更喜欢创建一个包含 A 和 B 的通用框架。

是否可以在 Xcode 中将 2 个静态库合并为 1 个,而不将 2 个库的代码合并到 1 个项目中。换句话说。当我编译/链接静态库 A 时,我可以以某种方式将编译的静态库 B 链接到静态库 A 中吗?

如果这是可能的,我怎样才能做到这一点?

law*_*cko 5

我刚刚运行了一些快速测试,它似乎是自动发生的。这就是我所做的:

  • 我使用DerivedData文件夹作为所有 3 个项目的默认构建位置(这是我使用的 XCode 4.2 中的默认位置)
  • 我将公共标头文件夹路径更改为include/ProjectX,其中 X 是静态库的名称。我仅对静态库 A 和 B 执行此步骤,而不是对实际链接它们的项目执行此步骤。这一步是为了能够导入像<LibX/Header.h>.
  • 我使库 B 直接依赖于库 A 并将 A 链接到 B
  • 我使库 A 直接依赖于主项目,并将主项目链接到 A

经过这个基本设置后,我使用类似的方法将类从 B 导入到 A <LibB/Header.h>,并编写了一些实际使用 B 的代码。然后,我使用 和 将 A 和 B 导入到主项目中,并<LibA/Header.h>编写<LibB/Header.h>了使用 A 和 B 的代码最后,我用终端进入DerivedData文件夹,导航到构建 A 的位置。我检查 LibA.a 是否包含来自 LibB 的对象:

nm LibA.a
Run Code Online (Sandbox Code Playgroud)

是的,它包含来自 LibB 的对象。因此,总而言之,通过这个简单的依赖设置,您应该能够获得您所要求的内容。

编辑 要使 B 直接依赖 A 并将 A 链接到 B,请执行以下操作:

在 XCode 中打开 A,转到 Finder 并将 B 项目文件拖放到 A 中。然后,选择 A 中的根元素,转到“构建阶段”,展开“目标依赖项”,按“+”按钮,选择 B 并确认。然后展开 Link Binary With Libraries,按“+”按钮,选择 Ba(或任何产品名称)并确认。

重要 XCode 中存在一个错误,它会阻止您将 B 项目文件正确放入 A 工作区。相反,您在 A 工作区中留下 B 项目文件,但您无法扩展 B 并对其执行任何操作。要解决此问题,请从 A 中删除有问题的 B 项目文件引用,关闭 A,然后关闭 B(如果已打开)。然后重新打开 A 并使用 Finder 导航到 B 项目文件,然后将 B 拖放到 A 工作区中。如果不起作用,请重复。

EDIT2 我的情况是您无权访问 B (也可能是 A)的源代码,使这项工作只需将所需的标头复制到适当的位置即可。然后在您的主项目中,您不会创建 A 直接依赖项,而是链接到您拥有的静态 libA.a 。如果 A 使用 B,则 B 中的符号已在 libA.a 中。你可以像我上面那样用nm工具检查这一点。因此,我们将通过 B 标头将这些符号公开给主应用程序。有几种方法可以做到这一点,我记得我只是将标头复制到位于依赖关系链中间的库的复制标头目标路径。之后,通过链接 A 并将 A 标头添加到用户标头搜索路径,我可以直接访问 B。为您做到这一点的最佳方法是什么取决于您是否有权访问 A 的来源。如果可以,则有两个选项可供考虑:

  • 将 B 标头添加到 A(它们将自动复制到 A 标头目标)。但我猜你不想要这个解决方案。
  • 将自定义运行脚本构建阶段添加到 A 目标,这将抓取 B 标头并将它们复制到 A 标头目标。

在这两种情况下,您最终都会得到 LibA.a,其中包含 A 和 B 的编译源,以及 headers 文件夹,其中包含 A 和 B 的标头。然后,您可以再次链接您的主项目 LibA.a 并将标头文件夹路径添加到主项目中的用户标题搜索路径,您应该可以开始了。

重要的

如果在您的库中,您的文件中仅包含类别代码,请确保使用-force_load链接该库,否则您的类别符号将无法正确打包。