2016-11-04 5 views
2

J'essaie de comprendre pourquoi je reçois une erreur undefined reference pendant la liaison:Trouver la cause racine de `erreur de reference` non défini

/home/amirgon/projects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib -T/home/amirgon/projects/esp8266/esp-open-sdk/sdk/ld/eagle.app.v6.cpp.ld -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain build/app_app.a -Wl,--end-group -o build/app.out 
build/app_app.a(routines.o):(.text+0x4): undefined reference to `pvPortMalloc(unsigned int, char const*, int)' 

gcc se plaint qu'il n'a pas pu trouver la fonction pvPortMalloc.
Cependant, je peux confirmer cette fonction existe dans libmain.a!

Dans la ligne de commande ci-dessus, libmain est référencé par -lmain et le chemin de bibliothèque est défini sur -L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib. Quand je largue les symboles de libmain.a sur ce chemin que je peux trouver pvPortMalloc marqué comme T, ce qui signifie que le symbole est dans le texte (code) section:

/home/amirgon/projects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-nm -g /home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib/libmain.a | grep pvPortMalloc 
     U pvPortMalloc 
0000014c T pvPortMalloc 
     U pvPortMalloc 

Alors, ai-je manqué quelque chose? quelle pourrait être la raison pour laquelle gcc ne trouve pas la fonction bien qu'elle existe dans libmain.a?
Comment puis-je déboguer davantage cette erreur?

+0

Besoin d'obtenir vos bibliothèques après vos fichiers .o sur la ligne de liaison, je crois. L'ordre est important dans la liaison. –

+0

@FredLarson Le '--start-group' /' --end-group' ne le corrigerait-il pas?il devrait résoudre les symboles de façon itérative jusqu'à ce que tous les symboles soient résolus. –

+0

Je pense que cela ne fonctionne que pour les fichiers. A, pas pour les fichiers. –

Répondre

3

Mixing de code C++ et C provoque votre problème.

Cette erreur:

undefined reference to `pvPortMalloc(unsigned int, char const*, int)' 

ne dit pas que le symbole pvPortMalloc ne peut pas être trouvé. Il dit que le symbole pvPortMalloc(unsigned int, char const*, int) ne peut pas être trouvé, et que c'est un symbole C++.

Cela signifie que quelque part vous compilez du code C++ qui pense qu'il existe une fonction C++ pvPortMalloc, dont le symbole inclut également sa signature, mais vous avez seulement une fonction C pvPortMalloc.

Code probable que votre C++ est d'inclure un fichier d'en-tête qui n'est pas C++ propre, et vous aurez besoin de faire quelque chose comme ceci:

extern "C" { 
#include "some_header.h" 
} 

Où some_header.h est le fichier d'en-tête déclarant la fonction pvPortMalloc.

+0

C'était le problème. Merci! –

1

Non seulement l'ordre des fichiers objets et des bibliothèques sur la ligne de commande est important, mais aussi l'ordre des fichiers objet dans une bibliothèque.

Tout ce qui résout une référence doit venir après le symbole est utilisé, sinon vous pourriez avoir des problèmes de liaison étranges.

L'effet que vous voyez est un problème typique d'une bibliothèque qui a été construit avec ar et le mauvais ordre de fichier objet (un certain fichier .o en utilisant une fonction externe qui est définie dans un fichier d'.o avant celui qui utilise ce symbole dans le lib).

ranlib <libfile> est l'outil qui fixe en créant un index pour tous les objets dans la bibliothèque et devrait se débarrasser de ce problème.

+0

Ceci est un bon conseil, mais ce n'était pas le problème est ce cas. Le problème était le mélange de code C et C++. –