2008-09-18 2 views
21

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

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

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

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

+0

Для Mac , см. http://stackoverflow.com/questions/1365211/error-in-xcode-project-ld-library-not-found-for-lcrt1-10-6-o/16102800 http://stackoverflow.com/ Questio ns/10941247/command-line-library-build-fail-with-linker-error/16102769 – kenorb 2013-04-19 10:44:44

ответ

22

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

+0

+1 для невероятно полезного трюка. Но мой вопрос по-прежнему остается нерешенным (кросс-компиляция pjsip на ARM) – FractalSpace 2014-09-17 21:29:33

+0

@FractalSpace это может быть другая проблема. Можете ли вы опубликовать вопрос с результатами получения? – stsquad 2014-09-18 16:16:08

0

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

1

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

1

У меня была аналогичная проблема с плохо настроенным кросс-компилятором. Я получил вокруг него так:

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

Это предполагает/Пб/USR/включать и так далее существовать в месте, на которое указывает вариант SYSROOT. Вероятно, это не так, как это должно быть сделано, но это избавило меня от неприятностей, когда мне нужно было скомпилировать простой файл C.

0

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

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

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

Оказывается, что создание в пустой каталог <SYSROOT>/USR/Библиотека исправили проблему. Кажется, что компоновщик будет искать пути <SYSROOT>/USR/Lib первым, и только если он существует, то он будет даже рассматривать <SYSROOT>/USR/lib64.

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

1

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

$ find /usr/ -name crti* 

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

sudo apt-get install libc6-dev 

Если вы нашли несколько библиотек read here