crti.o文件丢失
我正在使用一个GNU工具链build立一个项目,一切工作正常,直到我连接它,连接器抱怨它缺less/找不到crti.o
这不是我的目标文件之一,它似乎与libc有关,但我不明白为什么它需要这个crti.o
,它不会使用库文件,例如libc.a
?
我正在为arm平台交叉编译。 我有工具链中的文件,但我如何让链接器包含它?
crti.o
是在“图书馆”的searchpath之一,但它应该寻找库path上的.o
文件?
gcc
和ld
的searchpath是否相同?
crti.o
是bootstrap库,通常很小。 它通常静态链接到你的二进制文件。 它应该在/usr/lib
。
如果你正在运行一个二进制发行版,他们往往把所有的开发人员的东西放到-dev包(例如libc6-dev)中,因为它不需要运行已编译的程序,只是为了构build它们。
你不是交叉编译的吗?
如果您正在交叉编译,那么通常gcc的searchpath与您的crti.o所在的位置不匹配。 它应该build立在工具链时。 首先要检查的是gcc -print-search-dirs
,看看crti.o是否在任何path中。
链接实际上是由ld完成的,但它的path由gcc传递给它。 可能最快的方法是findhelloworld.c程序,并查看传递给ld的内容,看看发生了什么。
strace -v -o log -f -e trace=open,fork,execve gcc hello.c -o test
打开日志文件并searchcrti.o,你可以看到我的非交叉编译器:
10616 execve("/usr/bin/ld", ["/usr/bin/ld", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=both", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o" , "test", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-g nu/"..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., "-L/lib/../lib", "-L/usr/lib/../lib", "-L/usr/lib/gcc/x86_64-linux-gnu /"..., "/tmp/cc4rFJWD.o", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "/usr/lib/gcc/x86_ 64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."...], "COLLECT_GCC=gcc", "COLLECT_GCC_OPTIONS=\'-o\' \'test\' "..., "COMPILER_PATH=/usr/lib/gcc/x86_6"..., "LIBRARY_PATH=/usr/lib/gcc/x86_64"..., "CO LLECT_NO_DEMANGLE="]) = 0 10616 open("/etc/ld.so.cache", O_RDONLY) = 3 10616 open("/usr/lib/libbfd-2.18.0.20080103.so", O_RDONLY) = 3 10616 open("/lib/libc.so.6", O_RDONLY) = 3 10616 open("test", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3 10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crt1.o", O_RDONLY) = 4 10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crti.o", O_RDONLY) = 5 10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/crtbegin.o", O_RDONLY) = 6 10616 open("/tmp/cc4rFJWD.o", O_RDONLY) = 7
如果你看到一堆尝试open(...crti.o) = -1 ENOENT
, ld
变得困惑,你想看看它打开的path来自哪里…
好的,我不得不重新安装工具链,以便包含丢失的文件。 这似乎很奇怪,因为它应该在gccpath上find它。 我猜想的主要问题是我的电脑上有15个左右的crti.o文件,并没有指向正确的。 仍然不能使,因为它现在工作:-)感谢您的帮助:-)
我有一个类似的问题与糟糕的设置交叉编译器。 我像这样绕过它:
/home/rob/compiler/usr/bin/arm-linux-gcc --sysroot=/home/rob/compiler hello.c
假定/ lib,/ usr / include等存在于sysroot选项所指向的位置。 这可能不是应该怎么做的,但是当我需要编译一个简单的C文件的时候,它让我摆脱了麻烦。
在交叉编译时,我遇到了同样的问题。 crti.o在< sysroot > / usr / lib64中,但链接器不会find它。
原来,创build一个空目录<sysroot> / usr / lib解决了这个问题。 看起来链接器会首先search一个path<sysroot> / usr / lib ,并且只有存在的话甚至会考虑<sysroot> / usr / lib64 。
这是链接器中的错误吗? 或者这种行为logging在某个地方?
在我的情况下Linux Mint 18.0/Ubuntu 16.04
,我根本没有crti.o
:
$ find /usr/ -name crti*
我找不到任何东西,所以我安装开发包:
sudo apt-get install libc6-dev
如果你发现一些库在这里阅读
我在默认的Ubuntu 8.04安装上遇到同样的问题。 我必须手动获取libc开发人员头文件才能工作。
这解决了我(交叉编译ARM的pjsip):
export LDFLAGS='--sysroot=/home/me/<path-to-my-sysroot-parent>/sysroot'