Подтвердить что ты не робот

Undefined ссылка на printf при использовании перекрестного компилятора GCC

Я пытаюсь получить следующую простую программу Hello World для компиляции с использованием кросс-компилятора (GCC 4.9.2) с таргетингом mips:

#include <stdio.h>

int main()
{
  int x = 5;
  printf("x = %d\n", x);
}

Здесь существует переменная x, чтобы остановить изменение GCC printf до puts, которое, как представляется, автоматически выполняется для простой строки с завершающей строкой строки.

Я построил кросс-компилятор в ${HOME}/xc и выполняю его, используя следующую команду:

${HOME}/xc/bin/mips-gcc -v hello.c

Однако я получаю следующую ошибку:

/tmp/ccW5mHJu.o: In function `main':
(.text+0x24): undefined reference to `printf'
collect2: error: ld returned 1 exit status

Я предполагаю, что это проблема с компоновщиком, поскольку я ожидаю, что процесс завершится с ошибкой раньше, если, например, stdio.h не удалось найти на пути поиска. Я могу скомпилировать более простую программу, которая просто возвращает ноль, так что это не так, что вся инструментальная цепочка сломана, предположительно, только стандартная привязка библиотеки (я использую newlib 2.2.0-1).

Я получаю ту же ошибку, независимо от того, запускаю ли я кросс-компилятор под Linux (Ubuntu 14.10) или Cygwin (Windows 8).

Полный вывод из GCC:

Using built-in specs.
COLLECT_GCC=/home/paul/xc/bin/mips-gcc
COLLECT_LTO_WRAPPER=/home/paul/xc/libexec/gcc/mips/4.9.2/lto-wrapper
Target: mips
Configured with: /home/paul/xc/mips/tmp/gcc-4.9.2/configure --prefix=/home/paul/xc --target=mips --enable-languages=c --with-newlib --without-isl --without-cloogs --disable-threads --disable-libssp --disable-libgomp --disable-libmudflap
Thread model: single
gcc version 4.9.2 (GCC) 
COLLECT_GCC_OPTIONS='-v'
 /home/paul/xc/libexec/gcc/mips/4.9.2/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -auxbase hello -version -o /tmp/ccCpAajQ.s
GNU C (GCC) version 4.9.2 (mips)
    compiled by GNU C version 4.9.1, GMP version 6.0.0, MPFR version 3.1.2, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /home/paul/xc/lib/gcc/mips/4.9.2/include
 /home/paul/xc/lib/gcc/mips/4.9.2/include-fixed
 /home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/include
End of search list.
GNU C (GCC) version 4.9.2 (mips)
    compiled by GNU C version 4.9.1, GMP version 6.0.0, MPFR version 3.1.2, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: cffaaedf0b24662e67a5d97387fc5b17
COLLECT_GCC_OPTIONS='-v'
 /home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/as -EB -O1 -no-mdebug -mabi=32 -o /tmp/ccW5mHJu.o /tmp/ccCpAajQ.s
COMPILER_PATH=/home/paul/xc/libexec/gcc/mips/4.9.2/:/home/paul/xc/libexec/gcc/mips/4.9.2/:/home/paul/xc/libexec/gcc/mips/:/home/paul/xc/lib/gcc/mips/4.9.2/:/home/paul/xc/lib/gcc/mips/:/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/
LIBRARY_PATH=/home/paul/xc/lib/gcc/mips/4.9.2/:/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/lib/
COLLECT_GCC_OPTIONS='-v'
 /home/paul/xc/libexec/gcc/mips/4.9.2/collect2 -plugin /home/paul/xc/libexec/gcc/mips/4.9.2/liblto_plugin.so -plugin-opt=/home/paul/xc/libexec/gcc/mips/4.9.2/lto-wrapper -plugin-opt=-fresolution=/tmp/cc8TAJb9.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -EB /home/paul/xc/lib/gcc/mips/4.9.2/crti.o /home/paul/xc/lib/gcc/mips/4.9.2/crtbegin.o -L/home/paul/xc/lib/gcc/mips/4.9.2 -L/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/lib /tmp/ccW5mHJu.o -lgcc -lgcc /home/paul/xc/lib/gcc/mips/4.9.2/crtend.o /home/paul/xc/lib/gcc/mips/4.9.2/crtn.o
/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400050
/tmp/ccW5mHJu.o: In function `main':
(.text+0x24): undefined reference to `printf'
collect2: error: ld returned 1 exit status

Строка script, которую я использую, здесь (я написал ее на основе полдюжины обучающих программ, которые все предложили несколько разные вещи):

https://github.com/UoMCS/mips-cross-compile

В основном он выполняет следующие действия:

  • Построить binutils.
  • Сборка GCC (этап 1).
  • Построить newlib.
  • Сборка GCC (этап 2).

Я знаю, что есть другие инструменты, такие как crosstool-ng и builtroot, однако человек, которого я создаю, для этой инструментальной цепочки, хочет отредактировать части binutils перед тем, как начать процесс сборки, и инструментальная цепочка также должна работать под Cygwin (crosstool-ng не будет использоваться по разным причинам, в том числе к файлам, зависящим от регистра).

Я думаю, что это, вероятно, будет чем-то очевидным, но я занимаюсь этим неделю и не вижу, что это может быть. Любая помощь будет принята с благодарностью!

4b9b3361

Ответ 1

Необходимо создать библиотеки, чтобы перейти с вашим кросс-компилятором. В частности, для получения версии printf() вам нужно иметь кросс-скомпилированную версию glibc или некоторую другую реализацию стандартной библиотеки.

Посмотрите эту ссылку для примера того типа вещей, который вам нужно рассмотреть, чтобы получить все, что вам нужно - крест -компилятор, заголовки и библиотеки.

Ответ 2

Пользовательский файл спецификаций может работать:

cd /home/paul/xc/lib/gcc/mips/4.9.2/
${HOME}/xc/bin/mips-gcc -dumpspecs > specs

Добавить в файл спецификаций:

*lib:
-lc

Обратите внимание, что перед *lib: должны быть пустые строки и после -lc. Возможно, вам нужно изменить имя библиотеки на имя вашей библиотеки newlib-c. Возможно, нужно добавить больше, чем только -lc, например. раздел *lib: на моей Linux выглядит более сложным.


UPDATE. Здесь сконфигурированы встроенные спецификации lib для библиотек по умолчанию:

В файле gcc-4.9.2/gcc/gcc.c строки 527-530:

/* config.h can define LIB_SPEC to override the default libraries.  */
#ifndef LIB_SPEC
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
#endif

В файле gcc-4.9.2/gcc/config/mips/elf.h строки 40-42:

/* Leave the linker script to choose the appropriate libraries.  */
#undef  LIB_SPEC
#define LIB_SPEC ""

Возможно, по умолчанию LIB_SPEC в gcc.c работает для вас, комментируя строки 40-42 в elf.h. Возможно, вам нужно отредактировать elf.h и заменить пустой LIB_SPEC на "-lc" или что-то подобное.


ОБНОВЛЕНИЕ. Когда вы настроили gcc, вы дали --target=mips. В gcc-4.9.2\gcc\config.gcc есть другие мип-цели, которые более специфичны, например mips*-*-linux* , возможно, выбор подходящего дает правильный LIB_SPEC, и соединение будет успешным.


ОБНОВЛЕНИЕ: цель большого конечного пользователя Linux: mips-unknown-linux-gnu маленькая конечная цель Linux: mipsel-unknown-linux-gnu источник


ОБНОВЛЕНИЕ. Используя вашу сборку script, я смог связать вашу примерную программу со следующими изменениями:

В config.sh:

export ISL_VERSION="0.12.2"

В файле gcc-4.9.2/gcc/config/mips/elf.h строки 40-42:

/* Leave the linker script to choose the appropriate libraries.  */
#undef  LIB_SPEC
#define LIB_SPEC "-lc -lcfe -lc"

Если вам не нужна модификация в elf.h, библиотеки должны быть указаны при вызове mips-gcc.


UPDATE

newlib не работает вообще, GCC выходит на второй этап с ошибкой в ​​том, что он не может найти crti.o и т.д.

Странно, используя вашу сборку script crti.o:

[[email protected] 4.9.2]$ pwd
/home/osboxes/xc/lib/gcc/mips/4.9.2
[[email protected] 4.9.2]$ ll
total 6240
-rw-r--r--. 1 osboxes osboxes    3248 May 16 19:49 crtbegin.o
-rw-r--r--. 1 osboxes osboxes    1924 May 16 19:49 crtend.o
-rw-r--r--. 1 osboxes osboxes    1040 May 16 19:49 crti.o
-rw-r--r--. 1 osboxes osboxes    1056 May 16 19:49 crtn.o
drwxrwxr-x. 3 osboxes osboxes    4096 May 16 19:49 include
drwxrwxr-x. 2 osboxes osboxes    4096 May 16 19:45 include-fixed
drwxrwxr-x. 3 osboxes osboxes    4096 May 16 19:49 install-tools
-rw-r--r--. 1 osboxes osboxes 6289352 May 16 19:49 libgcc.a
-rw-r--r--. 1 osboxes osboxes   56844 May 16 19:49 libgcov.a
drwxrwxr-x. 3 osboxes osboxes    4096 May 16 19:49 plugin
-rw-rw-r--. 1 osboxes osboxes    6215 May 18 18:45 specs

Ответ 3

Попробуйте связать библиотеку с командной строкой:

${HOME}/xc/bin/mips-gcc -v hello.c -lib

Включение заголовков std (lib и io) связывает реализации по умолчанию (libc.so или .a). Тем не менее, вы используете "определяемую пользователем" реализацию и, возможно, не связываете ее.

Я предлагаю явное соединение в командной строке. Я не уверен в синтаксисе.

EDIT: Или лучше все же использовать makefile для компиляции со следующими строками и указать другие включенные каталоги в держателе места INCLUDES:

CC = gcc
CXX = g++
INCLUDES =
CFLAGS = -g -Wall $(INCLUDES)
CXXFLAGS = -g -Wall $(INCLUDES)
LDFLAGS = -g
hello: hello.o newlib.o
hello.o: hello.c newlib.h
newlib.o: newlib.c newlib.h

newlib.h - это заголовочный файл, который вы укажете в исходном файле newlib.c (реализация/определение) (который объявляет функции) и hello.c. Его можно назвать иначе, чем stdio.h.

Проверьте это, это может помочь:

Зачем вам нужно связать математическую библиотеку с C?

и это тоже:

http://www.tldp.org/HOWTO/Glibc2-HOWTO-6.html

Ответ 4

Самый удобный способ добиться этого - использовать putchar вместо printf. Может быть, вам придется изменить часть своего кода, или, возможно, вам придется добавлять макросы/функции, которые могут выполняться как printf.

Ответ 5

printf() был реализован в libc,

Пожалуйста, проверьте свой c lib, например glibc, oh, yours newlib.


  • try @4566976 way
  • use readelf -s Проверить, существует ли printf раздел libc.so libc.a

(я не уверен, что имя файла lib в newlib, мое - glibc)