将2个静态库链接为1,用于iOS [英] Linking 2 static libs into 1 for iOS

查看:99
本文介绍了将2个静态库链接为1,用于iOS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have created two separate static libraries in Xcode for usage on iOS, A and B. A uses methods that are defined in B.

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

When creating a new Xcode project where both A and B are needed, I can include them separately. However, for simplicity of integration I prefer to create a Universal Framework that contains both A and B.

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

Is it possible in Xcode to merge 2 static libraries into 1, without merging the code of the 2 libraries in 1 project. In other words. Can I somehow link the compiled static library B into static library A when I am compiling/Linking static library A?

如果可以,我该如何实现?

If this is possible, how can I accomplish this?

推荐答案

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

I've just run some quick tests and it seems to be happening automatically. This is what I did:


  • 我使用 DerivedData 文件夹作为所有3个项目的默认构建位置(这个是我使用的XCode 4.2中的默认值)

  • 我将公共标题文件夹路径更改为 include / ProjectX ,其中X是名称静态库。我只为静态库A和B执行此步骤,而不是实际链接它们的项目。这一步是为了能够导入像< LibX / Header.h> 这样的标题。

  • 我使库B直接依赖库A和链接A对B

  • 我使库直接依赖主项目和链接主项目与A

  • I used DerivedData folder as a default build location for all 3 projects (this is default in XCode 4.2 which I use)
  • I changed Public Headers Folder Path to include/ProjectX where X is the name of the static library. I did this step only for static libraries A and B, not for the project that will actually link them. This step is to be able to import the headers like <LibX/Header.h>.
  • I made library B direct dependency of the library A and linked A against B
  • I made library A direct dependency of the main project and linked main project against A

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

After this basic setup, I imported classes from B to A with something similar to <LibB/Header.h> and wrote some code that actually made use of B. Then, I imported A and B to the main project with <LibA/Header.h> and <LibB/Header.h> and wrote code that made use of A and B. Finally, I went to the DerivedData folder with the terminal and navigated to the location where A is built. I checked if LibA.a contains objects from LibB with:

nm LibA.a

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

And yes, it contains objects from LibB. So, to sum up, with this simple dependency setup you should be able to get what you asked for.

编辑
使B直接依赖A和链接A对B执行此操作:

EDIT To make B direct dependency of A and link A against B do this:

在XCode中打开A,转到Finder并将B项目文件拖放到A.然后,选择A中的根元素,转到Build Phases,展开Target Dependencies,按'+'按钮,选择B并确认。然后展开Link Binary With Libraries,按'+'按钮,选择Ba(或任何产品名称)并确认。

Having A open in the XCode, go to Finder and drag&drop B project file into A. Then, choose the root element in A, go to Build Phases, expand Target Dependencies, press '+' button, choose B and confirm. then expand Link Binary With Libraries, press '+' button, choose B.a (or whatever the product name is) and confirm.

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

Important There is a bug in XCode that prevents you from properly dropping B project file into A workspace. Instead, you are left with B project file in A workspace, but you cannot expand B and do anything with it. To work around this problem, remove the faulty B project file reference from A, close A, close B if you have it open. Then reopen A and use Finder to navigate to B project file, then drag&drop B inside A workspace. If didn't work, repeat.

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

EDIT2 I case you don't have access to the sources of B (and possibly A), making this work is just a matter of copying the required headers in the proper place. Then in you main project, you don't make the A direct dependency, instead you link against static libA.a that you have. If A uses B, then the symbols from B are already in the libA.a. You can check this with nm tool like I do above. So we are down to exposing those symbols to the main application with B headers. There are a couple of ways to do it, I remember that I simply copied the headers to the Copy Headers destination path of the library that is in the middle of the dependency chain. After that, by linking against A and adding A headers to User Header Search Paths I was able to access B directly. What is the best way to do it for you depends on if you have access to the sources of A. If you have, there are two options to consider:


  • 将B标头添加到A(它们将自动复制到A标头目的地)。但我想你不想要这个解决方案。

  • 将自定义运行脚本构建阶段添加到目标,它将获取B头并将它们复制到A头目的地。

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

In both cases, you end up with LibA.a which holds compiled sources of A and B, and the headers folder which holds headers from A and B. You can then link your main project agains LibA.a and add the headers folder path to the User Headers Search Path in you main project, and you should be good to go.

重要

如果在您的图书馆中,您的文件中只包含类别代码,请制作一定要将此库与 -force_load 相关联,否则您的类别符号将无法正确打包。

If, in your libraries, you have files that hold only category code in them, make sure to link this library with -force_load, or your category symbols will not be packed properly.

这篇关于将2个静态库链接为1,用于iOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆