Undefined reference to printf lors de l'utilisation de GCC le compilateur croisé
Je vais essayer d'obtenir les suivantes simple 'Bonjour le Monde' programme pour compiler à l'aide d'un cross compilateur (GCC 4.9.2) ciblage mips
:
#include <stdio.h>
int main()
{
int x = 5;
printf("x = %d\n", x);
}
La x
variable est là pour arrêter de GCC changer printf
à puts
, dont il semble faire automatiquement pour un simple retour à la ligne-chaîne terminée.
J'ai construit un cross compilateur sous ${HOME}/xc
et je suis d'exécution à l'aide de la commande suivante:
${HOME}/xc/bin/mips-gcc -v hello.c
Cependant, j'obtiens l'erreur suivante:
/tmp/ccW5mHJu.o: In function `main':
(.text+0x24): undefined reference to `printf'
collect2: error: ld returned 1 exit status
Je suppose que c'est un problème avec l'éditeur de liens, que je m'attends à de l'échec du processus plus tôt si par exemple stdio.h
ne pouvait pas être trouvé sur le chemin de recherche. Je peux compiler un programme plus simple qui retourne simplement zéro, il n'est donc pas le cas que l'ensemble de la chaîne est cassée, probablement juste de la bibliothèque standard de liens (je suis en utilisant newlib 2.2.0-1).
Je reçois la même erreur, indépendamment de savoir si je lance le compilateur croisé sous Linux (Ubuntu 14.10) ou Cygwin (Windows 8).
La sortie complète de GCC est:
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
Le script de build que j'utilise est ici (je l'ai écrit basé sur une demi-douzaine de tutoriels qui ont tous suggéré des choses légèrement différentes):
https://github.com/UoMCS/mips-cross-compile
Fondamentalement, il ne les étapes suivantes:
- Construire binutils.
- Construire GCC (étape 1).
- Construire newlib.
- Construire GCC (étape 2).
Je suis conscient qu'il existe d'autres outils tels que crosstool-ng et builtroot, cependant, la personne que je suis en train de construire cette suite d'outils pour veut modifier des parties de binutils avant de démarrer le processus de construction, et la suite d'outils doit aussi travailler sous Cygwin (crosstool-ng ne sera pas, pour diverses raisons, y compris les fichiers sensible à la casse des chemins).
Je pense que cela va probablement être quelque chose d'évident, mais j'ai été déconner avec ce pour une semaine et ne peut pas voir ce qu'elle pourrait être. Toute aide serait grandement appréciée!
Comment dois-je procéder?
Juste par curiosité: est-ce
int main(void) {};
compiler?Oui, j'ai toujours l'
cannot find entry symbol _start
d'avertissement (qui je pense peut être ignoré basé sur mon expérience avec les BRAS), mais il n'a compiler avec succès.Si je lance
gcc -v test.c
sur mon Linux, dans sa sortie est un -lc
pour le c-bibliothèque qui n'est pas présent dans votre sortie d'où le undefined reference to printf
.OriginalL'auteur pwaring | 2015-05-03
Vous devez vous connecter pour publier un commentaire.
Il est nécessaire de construire des bibliothèques pour aller avec votre compilateur croisé. En particulier, vous avez besoin d'avoir un cross-compilé la version de la glibc ou une autre implémentation de la bibliothèque standard, pour obtenir une version de
printf()
.Ont un coup d'oeil à ce lien pour un exemple du type de choses que vous devez prendre en compte pour obtenir toutes les choses que vous avez besoin - le cross-compilateur, les en-têtes et les bibliothèques.
C'est probablement la réponse la plus exacte de la solution éventuelle - j'ai dû utiliser la glibc et de jouer avec les différentes options de configuration jusqu'à ce que j'ai trouvé ceux qui ont travaillé (
--disable-werror
était important).Vous y êtes presque.
${HOME}/xc/bin/mips-gcc hello.c -lc -lcfe -lc
doit donner unea.out
. newlib devrait fonctionner. Juste_start
est toujours manquant pour la argv et l'appel de la fonction principale.newlib ne fonctionne pas du tout, GCC échoue à la deuxième étape, avec une erreur de ne pas être en mesure de trouver
crti.o
etc.étrange, à l'aide de votre script de construction
crti.o
a été créé: voir le contenu d'un répertoire dans la mise à jour de ma réponse.OriginalL'auteur Peter
Tentez de lier la bibliothèque sur la ligne de commande:
Y compris les mst bibliothèques (lib et io)de la tête liens les implémentations par défaut (libc.donc ou .a). Cependant, vous êtes en utilisant un "défini par l'utilisateur" mise en œuvre et ne peut pas être reliant la bonne.
Je suggère les liens explicites sur la ligne de commande. Je ne suis pas certain de la syntaxe.
EDIT:
Ou mieux Encore, utiliser un makefile pour compiler avec les lignes suivantes, et en spécifiant d'autres répertoires inclus dans la place du titulaire:
newlib.h
est le fichier d'en-tête que vous allez inclure dansnewlib.c
(mise en œuvre/définition) fichier source (qui déclare les fonctions) ethello.c
. Il peut être nommé différemment destdio.h
.Vérifier cela, il peut aider:
Pourquoi avez-vous le lien de la bibliothèque de mathématiques en C?
et cela aussi:
http://www.tldp.org/HOWTO/Glibc2-HOWTO-6.html
OriginalL'auteur paxmemento
Le moyen le plus pratique d'y parvenir est d'utiliser putchar à la place de printf. Peut-être que vous avez à changer une partie de votre code, ou peut-être que vous avez à ajouter des macros/fonctions qui peuvent fonctionner comme printf.
putchar
fait partie de la bibliothèque standard, donc si il y a un problème de linker il va se casser surputchar
juste comme il le fera pourprintf
.OriginalL'auteur totten
Une coutume spécifications de fichier pourrait fonctionner:
Ajouter aux spécifications de fichier:
Noter qu'il doit y avoir des lignes vides avant
*lib:
et après-lc
. Vous avez peut-être changer le nom de la bibliothèque pour le nom de votre newlib-c-bibliothèque. Peut-être plus doit être ajouté que seulement-lc
, par exemple, la*lib:
-section sur mon Linux a l'air plus complexe.Mise à JOUR: La builtin spécifications
lib
pour les bibliothèques par défaut sont configurés ici:Dans le fichier
gcc-4.9.2/gcc/gcc.c
lignes 527-530:Dans le fichier
gcc-4.9.2/gcc/config/mips/elf.h
lignes 40-42:Peut-être le défaut
LIB_SPEC
dansgcc.c
travaille pour vous en commentant les lignes 40-42 danself.h
.Peut-être vous avez besoin de modifier
elf.h
et remplacer le videLIB_SPEC
avec"-lc"
ou quelque chose de similaire.Mise à JOUR: Lorsque vous avez configuré
gcc
vous a donné--target=mips
. Dansgcc-4.9.2\gcc\config.gcc
il y a d'autres mips-cibles qui sont plus spécifiques, par exemplemips*-*-linux*
, peut-être à sélectionner le bon donne le droitLIB_SPEC
et la liaison sera couronnée de succès.Mise à JOUR: big endian Linux cible:
mips-unknown-linux-gnu
little endian Linux cible:mipsel-unknown-linux-gnu
sourceMise à JOUR: à l'Aide de votre script de compilation, j'ai été en mesure de relier votre exemple de programme avec les modifications suivantes:
Dans votre
config.sh
:Dans le fichier
gcc-4.9.2/gcc/config/mips/elf.h
lignes 40-42:Si vous ne voulez pas la modification dans
elf.h
les bibliothèques doivent être donnés lors de l'invocation demips-gcc
.Mise à JOUR:
Étrange, à l'aide de votre script de construction
crti.o
a été créé:OriginalL'auteur 4566976
printf()
a été mis en œuvre danslibc
,Veuillez vérifier votre c lib, comme
glibc
, oh, le vôtre estnewlib
.readelf -s
vérifier est-il unprintf
section existe danslibc.so
libc.a
( je ne suis pas sûr que la lib nom de fichier dans newlib, le mien est de la glibc )
printf
est défini danslibc
, ce que je veux savoir, c'est comment réparer l'erreur de l'éditeur de liens. 'Vérifier votre C lib' n'est pas très utile.OriginalL'auteur yurenchen