Отсутствует файл crti.o

Я строю проект, используя цепочку инструментов GNU, и все работает нормально, пока я не получу ссылку на него, где компоновщик жалуется, что он отсутствует / не может найти crti.o, Это не один из моих объектных файлов, похоже, что он связан с libc, но я не могу понять, зачем это нужно crti.o, не будет ли он использовать файл библиотеки, например, libc.a?

Я кросс-компиляция для платформы руки. У меня есть файл в наборе инструментов, но как мне заставить компоновщик включить его?

crti.o находится в одном из путей поиска "библиотек", но должен ли он искать .o файл на пути к библиотеке?

Является ли путь поиска одинаковым для gcc а также ld?

7 ответов

Решение

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 ENOENT, ld запутывается, и вы хотите увидеть, откуда пришел путь, которым он открывается...

У меня была такая же проблема при кросс-компиляции. crti.o находился в /usr/lib64, но компоновщик не нашел его.

Оказывается, что создание пустой директории / usr / lib решило проблему. Кажется, что компоновщик сначала будет искать путь / usr / lib, и только если он существует, он даже будет рассматривать /usr/lib64.

Это ошибка в компоновщике? Или это поведение где-то задокументировано?

В моем случае Linux Mint 18.0/Ubuntu 16.04, У меня нет crti.o совсем:

$ find /usr/ -name crti*

Я ничего не нахожу, поэтому я устанавливаю пакет разработчика:

sudo apt-get install libc6-dev

Если вы найдете несколько библиотек, читайте здесь

У меня была похожая проблема с плохо настроенным кросс-компилятором. Я обошел это так:

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

Предполагается, что /lib, /usr/include и т. Д. Существуют в месте, указанном параметром sysroot. Это, вероятно, не то, как все должно быть сделано, но это избавило меня от проблем, когда мне нужно было скомпилировать простой C-файл.

ОК, мне пришлось переустановить цепочку инструментов, чтобы отсутствующие файлы были включены. Это кажется странным, поскольку он должен был найти его на пути gcc. Основная проблема, я думаю, состояла в том, что у меня было 15 или около того разных файлов crti.o на моем компьютере, и они не указывали на правильный. До сих пор не делает, но работает сейчас:-) Спасибо за вашу помощь:-)

Если вы выполняете кросс-компиляцию, добавьте параметр sysroot в LDFLAGS

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

Это решено для меня (кросс-компиляция pjsip для ARM):

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

Я получаю такую ​​же проблему при установке Ubuntu 8.04 по умолчанию. Мне пришлось получить заголовки / файлы разработчика libc вручную, чтобы он работал.

Другие вопросы по тегам