我在Xcode中创建了两个独立的静态库,用于iOS,A和B.A使用B中定义的方法。
在创建需要A和B的新Xcode项目时,我可以单独包含它们。但是,为了简化集成,我更喜欢创建一个包含A和B的通用框架。
Xcode中是否可以将2个静态库合并为1,而无需合并1个项目中2个库的代码。换一种说法。在编译/链接静态库A时,我可以以某种方式将已编译的静态库B链接到静态库A中吗?
如果可以,我该如何做到这一点?
答案 0 :(得分:3)
我刚刚进行了一些快速测试,似乎是自动发生的。这就是我所做的:
<LibX/Header.h>
。在这个基本设置之后,我将类从B导入到类似于<LibB/Header.h>
的类,并编写了一些实际使用了B的代码。然后,我用{{1将A和B导入到主项目中并编写了使用A和B的代码。最后,我使用终端转到 DerivedData 文件夹并导航到构建A的位置。我检查了LibA.a是否包含来自LibB的对象:
<LibA/Header.h>
是的,它包含来自LibB的对象。总而言之,通过这种简单的依赖设置,您应该能够得到您所要求的内容。
修改强> 为了使B与A的直接相关性和对B的链接A做到这一点:
在XCode中打开,转到Finder并将B项目文件拖放到A.然后,选择A中的根元素,转到Build Phases,展开Target Dependencies,按'+'按钮,选择B和确认。然后展开Link Binary With Libraries,按'+'按钮,选择B.a(或任何产品名称)并确认。
重要强> XCode中存在一个错误,阻止您将B项目文件正确地放入A工作区。相反,您在A工作区中留下B项目文件,但您无法扩展B并对其执行任何操作。要解决此问题,请从A中删除有故障的B项目文件引用,关闭A,如果已打开则关闭B.然后重新打开A并使用Finder导航到B项目文件,然后将B拖放到A工作区内。如果不起作用,请重复。
<强> EDIT2 强> 我的情况是你无法访问B的源(可能还有A),这使得这项工作只需要在适当的位置复制所需的标题。然后在你的主项目中,你没有直接依赖,而是链接到你拥有的静态libA.a。如果A使用B,那么B中的符号已经在libA.a中。你可以像我上面的 nm 工具一样检查这个。因此,我们将使用B头将这些符号暴露给主应用程序。有几种方法可以做到这一点,我记得我只是将标题复制到依赖链中间的库的复制标题目标路径。之后,通过链接A并将A标题添加到用户标题搜索路径,我可以直接访问B.为您做这件事的最佳方式取决于您是否可以访问A的来源。如果有,有两种选择:
在这两种情况下,最终都会得到包含A和B编译源的LibA.a,以及包含A和B标题的headers文件夹。然后,您可以再次链接主项目LibA.a并添加标题您的主项目中用户标题搜索路径的文件夹路径,您应该很高兴。
重要强>
如果您的图书馆中包含仅包含类别代码的文件,请务必使用 -force_load 链接此库,否则您的类别符号将无法正确打包。
答案 1 :(得分:2)
我已经使用libtool完成了它,根据this answer。
为此,在Xcode 5.0.2中,我向A(Editor -> Add Build Phase -> Add Run Script Build Phase
)添加了一个脚本
计算出正在构建A的架构:
LIPO_ARCH=$(lipo -info ${BUILT_PRODUCTS_DIR}/${EXECUTABLE_NAME} | awk 'END{ print $NF }')
创建B的精简版本,只构建正在构建的架构
lipo -thin ${LIPO_ARCH} ${FULLPATH_OF_B} -output ${FULLPATH_OF_THIN_B}
将A和B加入新的A
mv ${BUILT_PRODUCTS_DIR}/${EXECUTABLE_NAME} ${FULLPATH_OF_THIN_A}
libtool -static -o ${BUILT_PRODUCTS_DIR}/${EXECUTABLE_NAME} ${FULLPATH_OF_THIN_A} ${FULLPATH_OF_THIN_B}
删除临时文件
rm ${FULLPATH_OF_THIN_A}
rm ${FULLPATH_OF_THIN_B}