it-swarm.com.de

Undefinierter Verweis auf printf bei Verwendung des GCC-Cross-Compilers

Ich versuche, das folgende einfache 'Hello World'-Programm zum Kompilieren mit einem Cross-Compiler (GCC 4.9.2) zum Targeting mips zu erhalten:

#include <stdio.h>

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

Die Variable x gibt an, dass GCC nicht printf in puts ändert. Dies scheint automatisch für eine einfache, mit Zeilenumbruch abgeschlossene Zeichenfolge zu erfolgen.

Ich habe unter ${HOME}/xc einen Cross-Compiler erstellt, der mit folgendem Befehl ausgeführt wird:

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

Ich erhalte jedoch die folgende Fehlermeldung:

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

Ich gehe davon aus, dass dies ein Problem mit dem Linker ist, da ich davon ausgehen könnte, dass der Prozess früher fehlschlägt, wenn stdio.h nicht im Suchpfad gefunden werden konnte. Ich kann ein einfacheres Programm erstellen, das einfach Null zurückgibt. Es ist also nicht so, dass die gesamte Toolchain defekt ist, vermutlich nur die Standard-Bibliotheksverknüpfung (ich verwende newlib 2.2.0-1).

Ich bekomme dieselbe Fehlermeldung, unabhängig davon, ob ich den Cross-Compiler unter Linux (Ubuntu 14.10) oder Cygwin (Windows 8) betreibe.

Die vollständige Ausgabe von GCC ist:

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

Das Build-Skript, das ich verwende, ist hier (ich habe es basierend auf einem halben Dutzend Tutorials geschrieben, die alle etwas unterschiedliche Dinge vorschlugen):

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

Grundsätzlich werden folgende Schritte ausgeführt:

  1. Baue Binutils.
  2. Baue GCC (Stufe 1).
  3. Erstelle newlib.
  4. GCC aufbauen (Stufe 2).

Ich bin mir bewusst, dass es andere Tools wie Crosstool-ng und builtroot gibt. Die Person, für die ich diese Toolchain baue, möchte jedoch Teile von binutils bearbeiten, bevor der Build-Prozess gestartet wird. Die Toolchain muss auch unter Cygwin funktionieren ( crosstool-ng wird aus verschiedenen Gründen (einschließlich der Groß- und Kleinschreibung der Dateipfade) nicht verwendet.

Ich denke, das wird wahrscheinlich etwas offensichtliches sein, aber ich habe eine Woche lang damit herumgespielt und kann nicht sehen, was es sein könnte. Jede Hilfe wäre sehr dankbar!

13
pwaring

Es ist notwendig, Bibliotheken für Ihren Cross-Compiler zu erstellen. Insbesondere benötigen Sie eine kreuzkompilierte Version von glibc oder eine andere Implementierung der Standardbibliothek, um eine Version von printf() zu erhalten.

In diesem Link finden Sie ein Beispiel für die Art der Dinge, die Sie berücksichtigen müssen, um alle benötigten Elemente zu erhalten - den Cross-Compiler, die Header und die Bibliotheken.

5
Peter

Versuchen Sie, die Bibliothek in der Befehlszeile zu verknüpfen:

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

Durch die Einbindung des Header der Bibliotheken std (lib und io) werden die Implementierungen standardmäßig (libc.so oder .a) verknüpft. Sie verwenden jedoch eine 'benutzerdefinierte' Implementierung und verknüpfen möglicherweise nicht die richtige.

Ich empfehle eine explizite Verknüpfung in der Befehlszeile. Ich bin mir der Syntax nicht sicher.

EDIT: Oder besser Verwenden Sie ein Makefile, um mit den folgenden Zeilen zu kompilieren und andere Include-Verzeichnisse im Platzhalter INCLUDES anzugeben:

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 ist die Header-Datei, die Sie in newlib.c (Implementierung/Definition) -Quelldatei (die die Funktionen deklariert) und hello.c enthalten. Es kann anders als stdio.h benannt werden. 

Schauen Sie sich das an, es kann helfen:

Warum musst du die Mathematikbibliothek in C verlinken?

und das auch:

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

0
paxmemento

Der bequemste Weg, dies zu erreichen, ist die Verwendung von putchar anstelle von printf. Möglicherweise müssen Sie etwas Code ändern oder Makros/Funktionen hinzufügen, die wie printf ausgeführt werden können.

0
totten

Eine benutzerdefinierte Specs-Datei könnte funktionieren:

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

Fügen Sie der Specs-Datei hinzu:

*lib:
-lc

Beachten Sie, dass vor *lib: und nach -lc Leerzeilen vorhanden sein müssen. Möglicherweise müssen Sie den Bibliotheksnamen in den Namen Ihrer newlib-c-Bibliothek ändern. Vielleicht muss mehr hinzugefügt werden als nur -lc, z. Der *lib:- Abschnitt auf meinem Linux sieht komplexer aus.


UPDATE: Die eingebauten Spezifikationen lib für die Standardbibliotheken werden hier konfiguriert:

In der Datei gcc-4.9.2/gcc/gcc.c Zeilen 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

In Datei gcc-4.9.2/gcc/config/mips/elf.h Zeilen 40-42:

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

Möglicherweise funktioniert der Standardcode LIB_SPEC in gcc.c für Sie, indem Sie die Zeilen 40-42 in elf.h____ auskommentieren. Möglicherweise müssen Sie elf.h bearbeiten und den leeren LIB_SPEC durch "-lc" oder ähnliches ersetzen.


UPDATE: Bei der Konfiguration von gcc haben Sie --target=mips angegeben. In gcc-4.9.2\gcc\config.gcc gibt es andere Mips-Ziele, die spezifischer sind, z. B. mips*-*-linux*, die Auswahl des geeigneten Ziels gibt vielleicht den richtigen LIB_SPEC und die Verknüpfung wird erfolgreich sein.


UPDATE: Linux-Ziel für big endian: mips-unknown-linux-gnu Linux-Ziel für little endian: mipsel-unknown-linux-gnusource


UPDATE: Mit Ihrem Build-Skript konnte ich Ihr Beispielprogramm mit folgenden Änderungen verknüpfen:

In Ihrem config.sh:

export ISL_VERSION="0.12.2"

In Datei gcc-4.9.2/gcc/config/mips/elf.h Zeilen 40-42:

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

Wenn Sie die änderung in elf.h nicht wünschen, müssen die Bibliotheken beim Aufruf von mips-gcc angegeben werden.


UPDATE:

newlib funktioniert überhaupt nicht, GCC schlägt in der zweiten Stufe fehl mit dem Fehler, crti.o nicht finden zu können usw.

Seltsam, mit Ihrem Build-Skript wurde crti.o erstellt:

[[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
0
4566976