Вопрос
Я создаю проект, используя цепочку инструментов GNU, и все работает нормально, пока я не доберусь до его связывания, где компоновщик жалуется, что он отсутствует / не может найти crti.o
.Это не один из моих объектных файлов, кажется, он связан с libc, но я не могу понять, зачем это нужно crti.o
, разве он не использовал бы файл библиотеки, например libc.a
?
Я занимаюсь кросс-компиляцией для платформы arm.У меня есть файл в наборе инструментов, но как мне заставить компоновщик включить его?
crti.o
находится на одном из путей поиска "библиотек", но должен ли он искать .o
файл по пути к библиотеке?
Является ли путь поиска одинаковым для gcc
и ld
?
Решение
crti.o
это библиотека bootstrap, как правило, довольно маленькая.Обычно он статически связан с вашим двоичным файлом.Это должно быть найдено в /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 был в <sysroot>/usr/lib64 но компоновщик не нашел бы его.
Получается, что создание пустого каталога <sysroot>/usr/ библиотека исправлена проблема.Похоже, что компоновщик будет искать путь <sysroot>/usr/ библиотека во-первых, и только в том случае, если он существует, он даже рассматривал бы <sysroot>/usr/lib64.
Это ошибка в компоновщике?Или это поведение где-то задокументировано?
В моем случае Linux Mint 18.0/Ubuntu 16.04
, У меня нет crti.o
вообще:
$ find /usr/ -name crti*
Я ничего не нахожу, поэтому устанавливаю пакет разработчика:
sudo apt-get install libc6-dev
Если вы найдете какие-нибудь библиотеки читайте здесь
Хорошо, мне пришлось переустановить цепочку инструментов, чтобы затем были включены недостающие файлы.Это кажется странным, поскольку он должен был найти его по пути gcc.Основная проблема, я думаю, заключалась в том, что у меня на компьютере было около 15 разных файлов crti.o, и они не указывали на правильный.С тех пор все еще не работает, но сейчас работает :-) Спасибо за вашу помощь :-)
У меня была похожая проблема с плохо настроенным кросс-компилятором.Я обошел это стороной вот так:
/home/rob/compiler/usr/bin/arm-linux-gcc --sysroot=/home/rob/compiler hello.c
Это предполагает, что /lib, /usr/include и так далее существуют в расположении, на которое указывает параметр sysroot.Вероятно, это не так, как все должно быть сделано, но это избавило меня от проблем, когда мне нужно было скомпилировать простой файл на языке Си.
Я получаю такую же проблему при установке Ubuntu 8.04 по умолчанию.Мне пришлось вручную получить заголовки / файлы разработчика libc, чтобы это заработало.
Это решилось для меня (кросс-компиляция pjsip для ARM):
export LDFLAGS='--sysroot=/home/me/<path-to-my-sysroot-parent>/sysroot'