我创建了一堆.o
个文件(通过gcc -c $file.c $someotherops -o $file.o
)。现在我想将它们链接到一个静态库。
我不确定我是否应该使用ld
或gcc
。在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构建中的错误。
答案 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
。