2012-03-02 42 views
3

我已经创建了两个单独的静态库在Xcode为使用在iOS,A和B A使用在B.链接2个静态库到1为iOS

中定义当创建一个新的Xcode项目,其中这两种方法A和B是必要的,我可以单独包含它们。然而,为了简化集成,我更喜欢创建一个同时包含A和B的通用框架。

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

如果这是可能的,我该如何做到这一点?

+0

涉及消除了http://stackoverflow.com/questions/8170450/combine-static-libraries – Bruce 2014-01-22 06:37:00

+0

还涉及到http://stackoverflow.com/questions/19442593/including-third-party-librariesexample-afnetworking-in-static-library – xverges 2014-01-29 18:33:05

回答

3

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

  • 我用DerivedData文件夹中的所有3个项目默认生成位置(这是的XCode 4.2,我用默认值)
  • 我改变公共头文件夹路径include/ProjectX其中X是静态库的名称。我只为静态库A和B做了这一步,而不是实际链接它们的项目。这一步是要能够导入像<LibX/Header.h>这样的头文件。
  • 我做出的库A的文库B的直接依赖和链接一个针对B
  • 我做图书馆主体工程的直接依赖,链接的是一个

主体工程这些基本设置后,我进口从B到A的类与<LibB/Header.h>类似,并编写了一些实际使用B的代码。然后,我将A和B导入到主项目<LibA/Header.h><LibB/Header.h>中,并编写了使用A和B的代码。最后,我与终端一起前往DerivedData文件夹,并导航至A所在的位置。我查了一下,如果LibA.a包含LibB使用对象:

nm LibA.a 

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

编辑 为了使A和B直接依赖和抗B链路A做此:

有开在Xcode,去Finder和拖动&降B类项目文件到A.然后,选择A中的根元素,进入构建阶段,展开Target Dependencies,按下'+'按钮,选择B并确认。然后展开Link Binary With Libraries,按下'+'按钮,选择B.a(或任何产品名称)并确认。

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

EDIT2 我如果你没有获得B(以及可能的)的来源,使这项工作仅仅是在正确的位置复制所需的报头的问题。然后在你的主项目中,你不需要创建一个直接的依赖关系,而是链接到你拥有的静态libA.a。如果A使用B,那么来自B的符号已经在libA.a中。你可以用nm这个工具来检查它,就像我上面做的那样。所以我们将这些符号暴露给具有B标题的主应用程序。有几种方法可以做到这一点,我记得我只是将头文件复制到位于依赖关系链中间的库的目标路径。之后,通过链接到A并添加A标题到用户标题搜索路径我能够直接访问B.什么是你做它取决于如果你有机会到A的来源如果你拥有最好的方式,有两个问题需要考虑:

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

在这两种情况下,你最终LibA.a持有A和B的编译的源代码,并拥有A和B.你头则可以将自己的主要项目agains LibA.a头文件夹,将头文件夹路径添加到您主项目中的用户头部搜索路径,您应该很好。

重要

,如果你在图书馆,你持有只在他们的类别代码文件,确保该库-force_load链接,或您的类别符号不会被妥善包装。

+0

Lawicko,谢谢你的回应。我留下的一个问题是,如何在编写“我使库A直接依赖库A和链接A对B”时创建依赖项? – 2012-03-02 14:12:11

+0

查看已更新的答案。 – lawicko 2012-03-02 14:40:59

+0

Lawicko,在我关闭了所有项目后,它可以工作:-)但是,我对解决方案并不完全满意,因为当我将B项目文件拖放到A项目中时,B的源代码暴露给项目A (我可以在左边展开项目B并在那里看到所有的项目代码,我不确定是否可以以某种方式解决这个问题(我宁愿将静态库B拖放到项目中,强制Xcode将B合并为静态lib A当我编译答:我会接受的答案,但我已经了解了一些关于xcode的新东西感谢你:-) – 2012-03-02 15:15:24

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}