如何链接iOS的静态库

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

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

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

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

然后我想,也许它需要指定dynamic库。 所以我加了-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 。 这是关于什么的?

而且我还有一堆缺less的符号,特别是:

 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是什么意思?


从这里 ,我感觉到,也许ld毕竟不是正确的工具。 在那里,使用简单的ar调用。 这似乎更有意义。 我会检查一下是否有效,然后将其转换成答案。


当玩更多的时候,当build立一个胖的静态库时, ar我发出一些警告。 它给了我暗示,而不是使用libtool 。 这就是我现在正在做的,即libtool -static -o libfoo.a *.o 。 另外我把编译器切换到/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang但不知道是否重要。

现在,在编译链接到这个静态库的一些testing应用程序时,我得到这些警告:

 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如何在_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错误。 这是它第一次实际运行一些代码。

直到我打了另一个关于整数比较奇怪的错误 。 因此,这看起来更像是一个在他们的铛build设中的错误。

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

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

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

而已。 我的问题中的其他问题只是错误的尝试。

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

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