Référence non définie à printf lors de L'utilisation du compilateur croisé GCC
j'essaie d'obtenir le programme simple 'Hello World' suivant pour compiler en utilisant un compilateur croisé (GCC 4.9.2) ciblant mips
:
#include <stdio.h>
int main()
{
int x = 5;
printf("x = %dn", x);
}
x
variable est là pour arrêter de GCC changer printf
puts
, ce qui semble se faire automatiquement pour une simple chaîne de fin de ligne.
j'ai construit un compilateur croisé sous ${HOME}/xc
et je suis d'exécution à l'aide de la commande suivante:
${HOME}/xc/bin/mips-gcc -v hello.c
Cependant, je reçois le suivant erreur:
/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 le linker, car je m'attendrais à ce que le processus échoue plus tôt si par exemple stdio.h
introuvable sur le chemin de recherche. Je peux compiler un programme plus simple qui retourne simplement zéro, donc ce n'est pas le cas que toute la chaîne d'outils est cassée, probablement juste le lien de bibliothèque standard (j'utilise newlib 2.2.0-1).
j'obtiens la même erreur que J'exécute 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 construction que j'utilise est ici (je l'ai écrit à partir d'une demi-douzaine de tutoriels qui suggéraient tous des choses légèrement différentes):
https://github.com/UoMCS/mips-cross-compile
fondamentalement, il fait les étapes suivantes:
- construire des binutils.
- construire GCC (étape 1).
- construction newlib.
- construire GCC (étape 2).
je suis conscient qu'il existe d'autres outils tels que crosstool-ng et builtroot, mais la personne pour laquelle je construis cette chaîne d'outils veut éditer des parties de binutils avant de lancer le processus de construction, et la chaîne d'outils doit aussi fonctionner sous Cygwin (crosstool-ng ne fonctionnera pas pour diverses raisons, y compris les chemins de fichiers sensibles à la casse).
je pense que cela va probablement être quelque chose d'évident, mais j'ai été déconner avec ça pendant une semaine et je ne vois pas ce que ça pourrait être. Toute aide serait grandement appréciée!
5 réponses
Il est nécessaire de construire des bibliothèques pour aller avec votre compilateur croisé. En particulier, vous devez avoir une version compilée de glibc ou une autre implémentation de la bibliothèque standard, pour obtenir une version de printf()
.
regardez ce lien pour un exemple du type de choses que vous devez considérer pour obtenir toutes les choses dont vous avez besoin - le compilateur croisé, les en-têtes, et les bibliothèques.
essayez de relier la bibliothèque en ligne de commande:
${HOME}/xc/bin/mips-gcc -v hello.c -lib
incluant l'en-tête des bibliothèques std (lib et io) relie les implémentations par défaut (libc.ou alors .un.) Cependant, vous utilisez une implémentation "définie par l'utilisateur" et ne liez pas nécessairement la bonne implémentation.
je suggère un lien explicite sur la ligne de commande. Je ne suis pas certain de la syntaxe.
modifier: Ou encore, utilisez un makefile pour compiler avec les lignes suivantes, et en spécifiant autre include répertoires à la place du titulaire:
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
est le fichier d'en-tête que vous incluez dans newlib.c
(implementation/definition) fichier source (qui déclare les fonctions) et hello.c
. Il peut être nommé différemment de stdio.h
.
Vérifier cela, il peut aider:
Pourquoi devez-vous relier la bibliothèque de mathématiques en C?
et ce trop:
Une coutume spécifications de fichier pourrait fonctionner:
cd /home/paul/xc/lib/gcc/mips/4.9.2/
${HOME}/xc/bin/mips-gcc -dumpspecs > specs
ajouter au fichier specs:
*lib:
-lc
Notez qu'il doit y avoir des lignes vides avant *lib:
et après -lc
. Peut-être que vous devez changer le nom de la bibliothèque pour le nom de votre nouvelle bibliothèque. Peut-être faut-il ajouter plus que -lc
, par exemple le *lib:
- la section sur mon Linux semble plus complexe.
UPDATE: Le groupe builtin specs
lib
par défaut les bibliothèques sont configurées ici:
Dans le fichier gcc-4.9.2/gcc/gcc.c
lignes 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
Dans le fichier gcc-4.9.2/gcc/config/mips/elf.h
lignes 40-42:
/* Leave the linker script to choose the appropriate libraries. */
#undef LIB_SPEC
#define LIB_SPEC ""
peut-être la valeur par défaut LIB_SPEC
gcc.c
fonctionne pour vous en commentant les lignes 40-42 elf.h
.
Vous devrez peut-être modifier elf.h
et remplacer le vide LIB_SPEC
"-lc"
ou quelque chose de similaire.
UPDATE: quand vous avez configuré
gcc
vous avez donné --target=mips
. Dans gcc-4.9.2\gcc\config.gcc
il y a d'autres cibles mips qui sont plus spécifiques, par exemplemips*-*-linux*
, peut-être en choisissant la bonne donne le droit LIB_SPEC
et l'établissement de liens réussira.
UPDATE: big endian cible Linux:
mips-unknown-linux-gnu
little endian cible Linux: mipsel-unknown-linux-gnu
source
UPDATE: en utilisant votre script de construction, j'ai pu lier votre programme échantillon avec ce qui suit: modification:
Dans votre config.sh
:
export ISL_VERSION="0.12.2"
Dans le fichier gcc-4.9.2/gcc/config/mips/elf.h
lignes 40-42:
/* Leave the linker script to choose the appropriate libraries. */
#undef LIB_SPEC
#define LIB_SPEC "-lc -lcfe -lc"
Si vous ne voulez pas une modification elf.h
les bibliothèques doivent être indiquées lors de l'invocation mips-gcc
.
UPDATE:
newlib ne fonctionne pas du tout, GCC échoue dans la deuxième étape avec une erreur de ne pas pouvoir trouver crti.O etc.
Étrange, à l'aide de votre construction script crti.o
a été créé:
[osboxes@osboxes 4.9.2]$ pwd
/home/osboxes/xc/lib/gcc/mips/4.9.2
[osboxes@osboxes 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
printf()
a été implémenté dans libc
,
Veuillez vérifier votre c lib, tels que glibc
, oh, le vôtre est newlib
.
- @4566976 '
- utiliser
readelf -s
cocher est-il unprintf
la 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 )