46

Je tente d'utiliser la bibliothèque libtommath. J'utilise l'EDI NetBeans pour mon projet sur Linux Ubuntu. J'ai téléchargé et construit la bibliothèque, j'ai fait un 'make install' pour mettre le fichier .a résultant dans/usr/lib/et les fichiers .h dans/usr/includeEssayez d'inclure une bibliothèque, mais continuez à recevoir des messages de "référence indéfinie"

Il semble être de trouver les fichiers de façon appropriée (puisque je n'obtiens plus ces erreurs, ce que j'ai fait avant d'installer dans les répertoires/usr).

Cependant, lorsque je crée simple principal faisant un appel à mp_init (qui est dans la bibliothèque), je reçois l'erreur suivante lorsque je tente de faire mon projet:

mkdir -p build/Debug/GNU-Linux-x86 
rm -f build/Debug/GNU-Linux-x86/main.o.d 
gcc -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.c 
mkdir -p dist/Debug/GNU-Linux-x86 
gcc -o dist/Debug/GNU-Linux-x86/cproj1 build/Debug/GNU-Linux-x86/main.o 
build/Debug/GNU-Linux-x86/main.o: In function 'main': 
/home/[[myusername]]/NetBeansProjects/CProj1/main.c:18: undefined reference to `mp_init' 
collect2: ld returned 1 exit status 
make[2]: *** [dist/Debug/GNU-Linux-x86/cproj1] Error 1 

, il ressemble l'éditeur de liens ne peut pas trouver la fonction dans la bibliothèque, mais il est là, donc je ne sais pas ce qui pourrait causer cela.

Je reçois la même erreur si je tape directement la commande gcc et ignore le makefile, je me suis également assuré que la bibliothèque statique a été compilée avec gcc.

Modifié à ajouter:

Je reçois ces mêmes erreurs si je fais la compilation directement et ajoutez la bibliothèque -l ou -L:

$ gcc -l /usr/lib/libtommath.a main.c 
/usr/bin/ld: cannot find -l/usr/lib/libtommath.a 
collect2: ld returned 1 exit status 

$ gcc -llibtommath.a main.c 
/usr/bin/ld: cannot find -llibtommath.a 
collect2: ld returned 1 exit status 

$ gcc -Llibtommath.a main.c 
/tmp/ccOxzclw.o: In function `main': 
main.c:(.text+0x18): undefined reference to `mp_init' 
collect2: ld returned 1 exit status 

$ gcc -Llibtommath.a main.c 
/tmp/ccOxzclw.o: In function `main': 
main.c:(.text+0x18): undefined reference to `mp_init' 
collect2: ld returned 1 exit status 

Je suis très rouillé sur ce genre de choses, alors Je ne suis pas sûr d'utiliser la bonne commande ici, dans les exemples -L les bibliothèques sont-elles trouvées? Si la bibliothèque n'est pas trouvée comment diable puis-je trouver la bibliothèque? C'est dans/usr/lib, je l'ai essayé avec le fichier .a dans le répertoire courant, etc. Y a-t-il une variable d'environnement que je dois définir? Si oui, comment, etc.

J'ai essayé une bibliothèque complètement différente (GMP) et j'ai eu le même problème. Cela doit être une sorte de problème d'environnement Ubuntu? Quelqu'un a-t-il une idée de la façon de résoudre ce problème?

Répondre

113

L'astuce ici est de mettre la bibliothèque APRES le module que vous compilez. Le problème est une chose de référence. L'éditeur de liens résout les références dans l'ordre, donc quand la bibliothèque est AVANT que le module soit compilé, l'éditeur de liens est confus et ne pense pas qu'une des fonctions de la bibliothèque soit nécessaire. En mettant la bibliothèque APRES le module, les références à la bibliothèque dans le module sont résolues par l'éditeur de liens.

+7

+1 Oh, merci! Je sais que l'ordre de résolution des liens est parfaitement logique, mais cela aide vraiment à se souvenir de ces faits! – scraimer

+1

Cela a fonctionné pour moi. Mon très ancien makefile avait l'habitude de fonctionner, mais maintenant il semble que le compilateur devienne trop intelligent pour son propre bien :) –

+2

Merci, c'était un GRAND rappel! –

35

Oui, il est nécessaire d'ajouter des bibliothèques après les fichiers/objets sources. Cette commande va résoudre le problème:

gcc -static -L/usr/lib -I/usr/lib main.c -ltommath 
+1

+ 1 pour écrire la bonne façon de lier avec 'libtommath.a' – scraimer

+0

Wow, c'est assez difficile. Merci d'avoir fait remarquer cela. – lolski

4

Si les fichiers source .c sont convertis Cpp (comme comme dans parsec), le extern doit être suivi de « C », comme dans

extern "C" void foo(); 
Questions connexes