crti.o 文件丢失

发布于 2024-09-10 22:58:46 字数 343 浏览 5 评论 0原文

我正在使用 GNU 工具链构建一个项目,一切正常,直到我开始链接它,链接器抱怨它丢失/找不到 crti.o。这不是我的目标文件之一,它似乎与 libc 有关,但我不明白为什么它需要这个 crti.o,它不会使用库文件,例如 libc.a

我正在针对arm平台进行交叉编译。我在工具链中有该文件,但如何让链接器包含它?

crti.o 位于“库”搜索路径之一,但它是否应该在库路径上查找 .o 文件?

gccld 的搜索路径是否相同?

I'm building a project using a GNU tool chain and everything works fine until I get to linking it, where the linker complains that it is missing/can't find crti.o. This is not one of my object files, it seems to be related to libc but I can't understand why it would need this crti.o, wouldn't it use a library file, e.g. libc.a?

I'm cross compiling for the arm platform. I have the file in the toolchain, but how do I get the linker to include it?

crti.o is on one of the 'libraries' search path, but should it look for .o file on the library path?

Is the search path the same for gcc and ld?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

梦亿 2024-09-17 22:58:46

crti.o 是引导程序库,通常很小。它通常静态链接到您的二进制文件中。它应该可以在 /usr/lib 中找到。

如果您正在运行二进制发行版,他们倾向于将所有开发人员的东西放入 -dev 包中(例如 libc6-dev),因为不需要运行已编译的程序,只需构建它们即可。

你不会交叉编译吧?

如果您进行交叉编译,通常是 gcc 的搜索路径与您的 crti.o 所在的位置不匹配的问题。它应该在工具链出现时就已经构建好了。首先要检查的是 gcc -print-search-dirs 并查看 crti.o 是否位于其中任何路径中。

链接实际上是由 ld 完成的,但它的路径是由 gcc 传递给它的。找出正在发生的情况的最快方法可能是编译一个 helloworld.c 程序并跟踪它以查看传递给 ld 的内容并查看发生了什么。

strace -v -o log -f -e trace=open,fork,execve gcc hello.c -o test

打开日志文件并搜索 crti.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 ENOENTld 变得很困惑,你想看看它打开的路径来自哪里......

crti.o is the bootstrap library, generally quite small. It's usually statically linked into your binary. It should be found in /usr/lib.

If you're running a binary distribution they tend to put all the developer stuff into -dev packages (e.g. libc6-dev) as it's not needed to run compiled programs, just to build them.

You're not cross-compiling are you?

If you're cross-compiling it's usually a problem with gcc's search path not matching where your crti.o is. It should have been built when the toolchain was. The first thing to check is gcc -print-search-dirs and see if crti.o is in any of those paths.

The linking is actually done by ld but it has its paths passed down to it by gcc. Probably the quickest way to find out what's going on is compile a helloworld.c program and strace it to see what is getting passed to ld and see what's going on.

strace -v -o log -f -e trace=open,fork,execve gcc hello.c -o test

Open the log file and search for crti.o, as you can see my non-cross compiler:

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

If you see a bunch of attempts to open(...crti.o) = -1 ENOENT, ld is getting confused and you want to see where the path it's opening came from...

孤独岁月 2024-09-17 22:58:46

我在交叉编译时遇到了同样的问题。 crti.o 位于 /usr/lib64中,但链接器找不到它。

事实证明,创建一个空目录 /usr/lib解决了这个问题。链接器似乎会首先搜索路径 /usr/lib,并且只有当它存在时才会考虑 /usr/lib64>。

这是链接器中的错误吗?或者这种行为是否记录在某处?

I had the same issue while cross-compiling. crti.o was in <sysroot>/usr/lib64 but the linker would not find it.

Turns out that creating an empty directory <sysroot>/usr/lib fixed the issue. It seems that the linker would search for a path <sysroot>/usr/lib first, and only if it exists it would even consider <sysroot>/usr/lib64.

Is this a bug in the linker? Or is this behaviour documented somewhere?

姐不稀罕 2024-09-17 22:58:46

在我的情况下 Linux Mint 18.0/Ubuntu 16.04,我根本没有 crti.o

$ find /usr/ -name crti*

我什么也没找到,所以我安装了开发人员包:

sudo apt-get install libc6-dev

如果你找到一些库 在此处阅读

In my case Linux Mint 18.0/Ubuntu 16.04, I have no crti.o at all:

$ find /usr/ -name crti*

I find nothing so I install developer package:

sudo apt-get install libc6-dev

If you find some libs read here

ま柒月 2024-09-17 22:58:46

如果是交叉编译,请在LDFLAGS中添加sysroot选项

export LDFLAGS=""--sysroot=${SDKTARGETSYSROOT}" -L${SDKTARGETSYSROOT}/lib -L${SDKTARGETSYSROOT}/usr/lib -L${SDKTARGETSYSROOT}/usr/lib/arm-poky-linux-gnueabi/5.3.0"

If you are cross-compiling , add sysroot option in LDFLAGS

export LDFLAGS=""--sysroot=${SDKTARGETSYSROOT}" -L${SDKTARGETSYSROOT}/lib -L${SDKTARGETSYSROOT}/usr/lib -L${SDKTARGETSYSROOT}/usr/lib/arm-poky-linux-gnueabi/5.3.0"
壹場煙雨 2024-09-17 22:58:46

好吧,我必须重新安装工具链,以便包含丢失的文件。这看起来很奇怪,因为它应该在 gcc 路径上找到它。我猜想主要问题是我的计算机上有 15 个左右不同的 crti.o 文件,但没有指向正确的文件。从那以后仍然没有成功,但现在可以了:-)感谢您的帮助:-)

OK I had to reinstall the tool chain, so that the missing files were then included. It seems strange since it should have found it on the gcc path. The main problem I guess was that I had 15 or so different crti.o files on my computer and wasn't point to the correct one. Still doesn't make since but it works now :-) Thanks for your help :-)

小矜持 2024-09-17 22:58:46

我也遇到过类似的问题,因为交叉编译器设置不当。我是这样解决的:

/home/rob/compiler/usr/bin/arm-linux-gcc --sysroot=/home/rob/compiler hello.c

这假设 /lib、/usr/include 等存在于 sysroot 选项指向的位置。这可能不是事情应该如何完成的,但当我需要编译一个简单的 C 文件时,它让我摆脱了麻烦。

I had a similar problem with a badly set-up cross-compiler. I got around it like so:

/home/rob/compiler/usr/bin/arm-linux-gcc --sysroot=/home/rob/compiler hello.c

This assumes /lib, /usr/include and so on exist in the location pointed to by the sysroot option. This is probably not how things are supposed to be done, but it got me out of trouble when I needed to compile a simple C file.

独﹏钓一江月 2024-09-17 22:58:46

我在默认安装的 Ubuntu 8.04 上遇到了同样的问题。我必须手动获取 libc 开发人员标头/文件才能使其正常工作。

I get the same kind of issue on a default Ubuntu 8.04 install. I had to get the libc developer headers/files manually for it to work.

知足的幸福 2024-09-17 22:58:46

这为我解决了(为 ARM 交叉编译 pjsip):

export LDFLAGS='--sysroot=/home/me/<path-to-my-sysroot-parent>/sysroot'

This solved for me (cross compiling pjsip for ARM):

export LDFLAGS='--sysroot=/home/me/<path-to-my-sysroot-parent>/sysroot'
野却迷人 2024-09-17 22:58:46

除了这里的所有其他答案(以及@stsquad的好建议(https://stackoverflow.com/a/91595/385390 ),还要考虑开发工具已升级且路径已更改的可能性,但在特定的开发项目中,automake生成的文件已过时,请查看以前的开发工具路径,在这种情况下尝试再次引导automake。 - 生成的文件。

如果没有引导脚本,也许这可以完成这项工作:

aclocal \
&& automake --gnu --add-missing \
&& autoconf --verbose --force --warnings=all \
&& autoupdate \
&& libtoolize -c -f -i \
&& autoreconf --install --symlink --force

In addition to all the other answers here (and the good advice by @stsquad (https://stackoverflow.com/a/91595/385390), consider also the possibility that development tools have been upgraded and paths have changed but, in specific development projects, automake-generated files are stale, looking at the previous development tools paths. In which case try and bootstrap again automake-generated files.

If there is no bootstrap script, perhaps this can do the job:

aclocal \
&& automake --gnu --add-missing \
&& autoconf --verbose --force --warnings=all \
&& autoupdate \
&& libtoolize -c -f -i \
&& autoreconf --install --symlink --force
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文