如何链接iOS的静态库

时间:2012-06-16 15:58:57

标签: ios gcc build static-libraries ld

我创建了一堆.o个文件(通过gcc -c $file.c $someotherops -o $file.o)。现在我想将它们链接到一个静态库。

我不确定我是否应该使用ldgcc。在ld手册中,据说我不应该直接使用它。但是,我无法弄清楚创建静态库的gcc参数。

我试过了ld *.o -static -o libfoo.a,但它抱怨了很多丢失的符号(我认为都是来自libc)。我不明白它为什么抱怨,因为它应该是一个静态库。一旦我将静态库链接到其他东西,我认为它会检查符号。

另一件事:我在这里使用/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld(我的目标是iOS)。它抱怨警告ld: warning: using ld_classic。这是关于什么的?

然后我想,也许它需要指定动态库。所以我添加了-lc来链接libc。但它抱怨can't locate file for: -lc。我添加了-L/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/lib并且有一个libc.dylib

有什么想法吗?


关于-lc错误:我在指定-arch armv6后离开了。然后它抱怨错误libcache.dylib(必须从libc.dylib链接,我猜是因为它没有指定它)。添加-L.../usr/lib/system有帮助。

现在,对于每个.o个文件,我收到警告ld: warning: CPU_SUBTYPE_ARM_ALL subtype is deprecated。这是关于什么的?

我还有一堆缺少的符号,特别是:

Undefined symbols for architecture armv6:
  "start", referenced from:
     -u command line option
     (maybe you meant: _PyThread_start_new_thread)
  "___udivsi3", referenced from:
      _get_len_of_range in bltinmodule.o
      _quorem in dtoa.o
      _array_resize in arraymodule.o
      _newarrayobject in arraymodule.o
      _array_fromfile in arraymodule.o
      _get_len_of_range in rangeobject.o
      _inplace_divrem1 in longobject.o
      ...
  "___unorddf2", referenced from:
      _builtin_round in bltinmodule.o
  ...

我查了一些符号,例如___udivsi3中的get_len_of_range。此函数仅使用C算术,无需外部调用。所以这似乎被翻译为使用一些外部函数,如___udivsi3。但这是什么库?


-lgcc_s.1修复了大部分___udivsi3及相关缺失符号。 start符号仍然缺失。 -u command line option是什么意思?


here开始,我觉得可能ld毕竟不是正确的工具。在那里,使用了对ar的简单调用。而这似乎更有意义。我将检查这是否有效并将其转换为答案。


在玩更多游戏时,ar在构建胖静态库时会向我发出一些警告。它给了我提示使用libtool代替。这就是我现在正在做的事情,即libtool -static -o libfoo.a *.o。我还将编译器切换到/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang但不确定是否重要。

现在,在编译一些链接到这个静态库的测试应用程序时,我收到了以下警告:

ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in __PyBuiltin_Init from /Users/az/Programmierung/python-embedded/libpython.a(bltinmodule.o). To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
ld: warning: 32-bit absolute address out of range (0x1001B70C4 max is 4GB): from _usedpools + 0x00000004 (0x001B70CC) to 0x1001B70C4
ld: warning: 32-bit absolute address out of range (0x1001B70C4 max is 4GB): from _usedpools + 0x00000000 (0x001B70CC) to 0x1001B70C4

它们是关于什么的?我不使用-mdynamic-no-pic。我也没有在_PyBuiltin_Init中看到我如何在那里使用绝对寻址。

另外,这些绝对地址超出范围的是什么? 编辑:这些是非常庞大的分配。我刚刚删除了这段代码(这是WITH_PYMALLOC,如果有人对这些特定的Python内部感兴趣的话。)

当我在iPhone上启动它时,我得到了中止:

dyld: vm_protect(0x00001000, 0x00173000, false, 0x07) failed, result=2 for segment __TEXT in /var/mobile/Applications/C15D9525-E7DC-4463-B05B-D39C9CA24319/...

当我使用-no_pie进行链接时,它甚至没有链接。它失败了:

Illegal text-relocation to ___stderrp in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib/libSystem.dylib from _read_object in /Users/az/Programmierung/python-embedded/libpython.a(marshal.o) for architecture armv7


我解决了PIE禁用,绝对寻址错误。我的命令行Clang中有一个-static。一旦我删除了它,警告就会消失,以及dyld / vm_protect错误。这是第一次实际运行一些代码。

直到我点击another strange error about integer comparison。因此,这看起来更像是他们的Clang构建中的错误。

2 个答案:

答案 0 :(得分:12)

现在一切正常。基本上,答案是:

  • 只需像往常一样将每个*.c文件编译为*.o个文件。唯一真正的区别是不同的GCC / Clang,-arch armv7,不同的SDK /包括dirs。

  • 使用libtool -static -o libfoo.a *.o构建静态库。

就是这样。我的问题中的其他问题只是错误的尝试。

答案 1 :(得分:1)

如果有人通过搜索dyld: vm_protect(...)运行时错误但是您正在使用XCode来到这里,那么OP中提到的-static标志可能就是问题。

通过在LLVM编译器语言设置中将“启用与共享库的链接”切换为“是”(默认值)来摆脱它。 (这会从项目文件中删除GCC_LINK_WITH_DYNAMIC_LIBRARIES = NO