【问题标题】:crti.o file missingcrti.o 文件丢失
【发布时间】:2010-09-10 15:10:45
【问题描述】:

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

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

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

gccld 的搜索路径是否相同?

【问题讨论】:

标签: makefile linker


【解决方案1】:

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

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

你不是在交叉编译吧?

如果您进行交叉编译,通常是 gcc 的搜索路径与您的 crti.o 所在位置不匹配的问题。它应该是在工具链存在时构建的。首先要检查的是gcc -print-search-dirs,看看crti.o 是否在这些路径中。

链接实际上是由 ld 完成的,但它的路径由 gcc 传递给它。找出发生了什么的最快方法可能是编译一个 helloworld.c 程序并对其进行 strace 以查看传递给 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 ENOENT 的大量尝试,ld 会感到困惑,您想看看它打开的路径来自哪里...

【讨论】:

  • +1 表示非常有用的 strace 技巧。但我的问题仍未解决(在 ARM 上交叉编译 pjsip)
  • @FractalSpace 这可能是一个不同的问题。你能发布一个关于你得到的输出的问题吗?
  • @stsquad 同样是工具链配置错误的问题。我找到了一个可以为我解决问题的解决方案。请参阅下面的答案。
【解决方案2】:

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

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

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

【讨论】:

  • 这对我有用。我害怕想到你必须经历多少混乱才能发现这一点。不知道这是一个错误还是什么 - 但也许值得关注 GNU ld bugzilla 或邮件列表或其他东西。
【解决方案3】:

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

$ find /usr/ -name crti*

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

sudo apt-get install libc6-dev

如果你找到一些库read here

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      我遇到了类似的问题,交叉编译器设置不当。我是这样绕过它的:

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

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-01-08
              • 2015-12-19
              • 2010-11-25
              • 2014-05-26
              • 2015-05-06
              • 1970-01-01
              • 2018-03-22
              • 1970-01-01
              相关资源
              最近更新 更多