【问题标题】:Compile several static libraries into a single iOS Framework将几个静态库编译成一个 iOS 框架
【发布时间】:2014-02-01 16:45:28
【问题描述】:

我有一个很大的静态库,我想打包成一个 iOS 静态框架以方便使用。该库实际上是几个.a 文件,每个库的逻辑模块一个。

我为设备编译了 .a 文件(带有armv7armv7sarm64 的胖文件)和模拟器(带有i386x86_64 的胖文件)。

现在,AFAIK,我需要将所有这些文件合并到一个大文件中,以便构建一个合适的框架。

使用此处描述的技术 (Combine static libraries),我可以做到:

libtool -static -o new.a old1.a old2.a

但显然old1.aold2.a 都包含相同的符号。因此,当链接到我的框架时,我收到链接器错误(出于正当原因)duplicate symbols

一种更正确的方法(从而避免重复符号)似乎是解压缩 .o 文件,并将它们组合成一个大的 .a 文件 (How to pack multiple library archives (.a) into one archive file?)

ar x old1.a
ar x old2.a
ar rcs new.a *.o

现在,请记住,old1.aold2.a 是胖文件,所以我需要根据架构将其分开。

这就是我要做的:

lipo old1.a -thin armv7 -output armv7/old1.a
cd armv7; ar x old1.a; cd ..
...
lipo old1.a -thin x86_64 -output x86_64/old1.a
cd x86_64; ar x old1.a; cd ..

// Same goes for old2.a ...

// Then, 
libtool -static -o new.a armv7/*.o armv7s/*.o arm64/*.o // ... etc

但由于某种原因,当链接到这样创建的框架时,链接器找不到任何符号(即使nm 显示了所有符号)。

知道如何构建该静态框架吗?

【问题讨论】:

  • 你不能只从源代码编译库吗?除非你想用符号来做巫术,否则这可能是最简单的。
  • 好吧,我需要以某种方式将所有代码编译到一个静态库中,这需要对 3rd 方代码的构建系统进行大量修改

标签: ios iphone c static-libraries libtool-xcode


【解决方案1】:

您可以将静态库对象预链接到一个中,也可以将其他静态库预链接到一个中。它实际上会将对象与链接器链接(几乎就像在动态库中一样)。

  1. 在您的单一库(主要库)中,转到构建设置并在链接部分中找到执行单一对象预链接。将其切换为是
  2. 在 Prelink 库中,您可以指定要包含的其他库。在那里,您不仅需要输入名称,还需要输入完整的文件名。如果其他库也来自您的项目,那么您可以使用 $(CONFIGURATION_BUILD_DIR) 变量。所以如果你有库 foo,那么它将是 $(CONFIGURATION_BUILD_DIR)/libfoo.a
  3. 您可以在单对象预链接标志中添加其他标志
  4. 如果要去除本地符号,请确保将部署后处理设置为“是”,因为默认情况下不会去除静态库。

如果你的库有重复的符号,那么你的模块结构有问题。

【讨论】:

  • 你可以hyde,但你不能jekyll! (对不起,不得不)
【解决方案2】:

libtool 真的是在创建胖库吗?我们做一些类似的事情,但直接使用“lipo -create”

ar -r armv7.a a/armv7/*.o b/armv7/*.o c/armv7/*.o d/armv7/*.o e/armv7/*.o
ar -r armv7s.a a/armv7s/*.o b/armv7s/*.o c/armv7s/*.o d/armv7s/*.o e/armv7s/*.o
ar -r i386.a a/i386/*.o b/i386/*.o c/i386/*.o d/i386/*.o e/i386/*.o


$LIPO \
        -create \
        -arch armv7 "objs/armv7.a" \
        -arch i386  "objs/i386.a" \
        -o "$FRAMEWORK_INSTALL_NAME" \
    || abort "Lipo $1 failed"

我们还遇到了一个问题,即 isv 对我们的框架做同样的事情,以制作他们的框架,所以即使 a/foo.o 和 b/foo.a 可以进入我们的 armv7.o 也很好。当他们提取 "ar -x" 时,ar 不会保留路径,因此只会写入一个 foo.o。

我们通过重命名每个 .o 并为其添加前缀 a_foo.o 来修复它,然后再创建 target.a。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    相关资源
    最近更新 更多