UNdefined reference to 'cv::function_name' sous ubuntu 11.10

Résolu/Fermé
mimya1 Messages postés 15 Date d'inscription lundi 23 mai 2011 Statut Membre Dernière intervention 19 décembre 2012 - 15 déc. 2012 à 18:40
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 19 déc. 2012 à 19:47
Salam, Bonsoir

J'utilise OpenCV 2.4.2 sous ubuntu 11.10 et genom 2 ( du package robotpkg développé par le laboratoire LAAS)
J'essaye d'installer un module en utilisant make make install, dans le code du module, des fonctions de librairie OpenCV sont utilisées. À chaque référence à celles-ci j'ai l'erreur Undefined reference suivi du nom de la fonction.
J'ai déja essayé OpenCV avec des programmes simples. Je compilait avec la commande

g++ 'pkg-config --cflags opencv' my_code.cpp -o my_code 'pkg-config --libs opencv'

et ça fonctionne correctement.

L'enête du programme contient:
#include <portLib.h>
 
#include "server/targdetHeader.h"
#include <portLib.h>
#include <cv.h>
#include <highgui.h>
 
#include "/home/amina/src/openrobots/include/opencv2/imgproc/imgproc.hpp"
#include "/home/amina/src/openrobots/include/opencv2/objdetect/objdetect.hpp"
#include "/home/amina/src/openrobots/include/opencv2/highgui/highgui.hpp"
 
#include <stdio.h>
#include <h2timeLib.h>
#include <time.h>
#include <iostream>
#include <fstream>
#include <string>
 
#include <viam/viamStruct.h>

les variables PATH, PKGCONFIG et LD_LIBRARY_PATH sont normalement bien configuré dans les fichiers .bashrc et /etc/bash.bashrc

Toute indication est la bienvenue, merci d'avance

A voir également:

7 réponses

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
16 déc. 2012 à 14:06
Bonjour Amina,

Quand tu as un "undefined reference", cela signifie que le header (fichier .h) a été trouvé, mais que tu as oublié de linker avec la librairie (fichier .so ou fichier .a) qui fournit le code compilé de cette fonction.

Petit rappel de C/C++ :
- un fichier header (.h/.hpp) déclare une fonction et permet au compilateur dans un premier temps d'ignorer les références à cette fonction (qui sera résolue au linkage)
- un fichier source (.c/.cpp) est destiné à être compilé généralement sous la forme d'un fichier objet (.o) typiquement avec une ligne du genre :

gcc -W -Wall -O2 -o toto.o toto.c


- le fichier final (un exécutable (pas d'extension sous linux), une librairie statique (.a) ou dynamique (.so)) est produit en réunissant et en linkant l'ensemble des fichiers .o et les éventuelles librairies nécessaires à sa construction (.so et .a).

Supposons que tu linkes ton programme avec libtiti1.so et libtiti2.so, alors l'option à passer sera -ltoto1 -ltoto2 (et supposons que tes fichiers objets soient toto1.o et toto2.o)

gcc -W -Wall -O2 -o monprogramme main.c toto1.o toto2.o -ltiti1 -ltiti2


Évidemment ça devient extrêmement fastidieux de lancer toutes ces commandes gcc/g++ dès qu'on a beaucoup de fichiers, et c'est la raison pour laquelle je t'invite vivement à écrire un Makefile. Tu peux regarder ce fil de discussion où je donne un makefile générique, il faut juste respecter certaines convention pour organiser tes fichiers (tu peux aussi t'en inspirer pour écrire un makefile plus simple) :
https://forums.commentcamarche.net/forum/affich-21500291-pb-makefile-suite-portage-vers-autre-noyau#7

Autre truc qui ne va pas : dans ton code tu as injecté explicitement le chemin de fichiers headers (/home/amina/...). Cela signifie que si quelqu'un essaye de compiler ton programme il devra absolument respecter cette arborescence, ce qui tu en conviendras est un peu gênant. Par contre on peut dire à gcc de chercher des ".h" avec l'option -I (ou -isystem).

Par exemple :

#include "/home/amina/src/openrobots/include/opencv2/imgproc/imgproc.hpp"
#include "/home/amina/src/openrobots/include/opencv2/objdetect/objdetect.hpp"
#include "/home/amina/src/openrobots/include/opencv2/highgui/highgui.hpp"


... deviendrait en toute rigueur :

#include<opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>


... en compilant comme suit :

g++ -W -Wall -O2 -I/home/amina/src/openrobots/include/ -o toto.o toto.cpp


Sur le même principe les options -L et -Wl,R permettent d'enrichir les répertoires dans lesquels gcc/g++ va chercher des .so et des .a. Pour plus de détails je t'invite à lire ceci :
https://forums.commentcamarche.net/forum/affich-37604426-la-compilation-et-les-modules-en-c-et-en-c

Autres précisions :
- La variable LD_LIBRARY_PATH n'aide en rien le linkage, ça indique juste au shell (le truc dans lequel tu tapes des commandes) où trouver des ".so" quand tu lances une commande (on est donc à l'exécution, pas à la compilation).
- De la même manière, PATH est une variable shell (donc qui intervient à l'exécution, donc après la compilation) pour indiquer au shell ou espérer trouver des commandes (par exemple la commande "ls").

Donc aucune de ces deux variables ne permet de résoudre ton problème.
2
mimya1 Messages postés 15 Date d'inscription lundi 23 mai 2011 Statut Membre Dernière intervention 19 décembre 2012
16 déc. 2012 à 18:52
Un grand et énorme merci pour toute ces explications. Je visiterai le lien que tu m'a proposé tout de suite. Mais je tiens à réexpliquer mon prblème encore plus:

Je ne compile pas avec gcc ni g++. J'ai déjà les makefile qui sont générés par GenoM ( Generator of Modules développé par le laboratoire LAAS pour les architectures des robots) .
Donc, j'écris un fichier descriptif du module, qui est spécifique à genom, celui-ci, génère la squelette du module ( les autoconf, configure, ..., là ou insérer du code c++,...). Ensuite je lance le ./configure qui génère les makefile nécéssaire.
Je suis ensuite sencé lancé make suivi de make install pour avoir le module en question dans mon répertoire bin et pouvoir le lancer à partir du shell.

Pour le chemin explicite, c'est juste pour tester , je m'en occuperai de ça une fois le make fonctionne correctement.

Je rappelle aussi que lorsque je compilais avec g++ des codes pour tester le bon fonctionnement d'OpenCV, j'utilisais la commande

g++ 'pkg-config --cflags opencv' my_code.cpp -o my_code 'pkg-config --libs opencv'
et ça fonctionne correctement avec g++.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
17 déc. 2012 à 00:23
Du coup je me demande qu'elle est la question. Tu as toujours des erreurs de linkages (undefined references) ? Si oui à quelle librairie sont-elles liées, c'est une fonction des sources du LAAS ? Si oui, quel est le chemin du ".so" correspondant et quelle commande de compilation est déclenchée par ton makefile ?

Bonne chance
0
mimya1 Messages postés 15 Date d'inscription lundi 23 mai 2011 Statut Membre Dernière intervention 19 décembre 2012
17 déc. 2012 à 00:40
La question est Comment éliminer cette erreur de linkage?
les erreurs sont liées à OpenCV, le chemin des librairies est
/usr/local/lib ou /home/amina/src/openrobots/lib ( celui là est ajouté par robotpkg) donc j'ai la librairie installé dans deux endroits ( une fois je l'ai faite moi même et la seconde fois par robotpkg dans le reperoire /home/amina/src/openrobots parce qu'il y avait des module qui nécessitait cette bibliothèque)

la commande de compilation est normalement g++ -o 02 -pthread

Merci pour votre aide
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié par mamiemando le 17/12/2012 à 00:47
A priori les librairies qui sont dans /usr/local/lib devraient être trouvées automatiquement (au même titre que celles qui seraient dans /lib ou /usr/lib). Par contre comme je te l'ai dit plus haut, les ".so" et ".a" situés ailleurs (donc notamment dans /home/amina/src/openrobots/lib) ne seront pas trouvés par ton compilateur à moins d'indiquer ce chemin en plus.

Pour cela il faut que tu passes les options -L et -Wl,R :

gcc -W -Wall -O2  -Wl,R /home/amina/src/openrobots/lib -L /home/amina/src/openrobots/lib -o monprogramme toto1.o toto2.o -ltiti1 -ltiti2


Autre solution tu peux mettre les .a et .so dans /usr/local/lib (ou créer un lien symbolique de /usr/local/lib vers /home/amina/src/openrobots/lib).

cd /usr/local/lib 
sudo ln -s /home/amina/src/openrobots/lib/libtiti1.so


Bonne chance
0
mimya1 Messages postés 15 Date d'inscription lundi 23 mai 2011 Statut Membre Dernière intervention 19 décembre 2012
19 déc. 2012 à 18:01
Salam

Je viens de résoudre le problème. J'ai donc pensé à partager la solution.
La version d'OpenCV que j'ai installé manuellement est 2.4.2 dont le prefix d'installation est /usr/local/lib
Genom a aussi installé automatiquement la version 2.4.1 d'OpenCV avec le prefix /home/amina/src/openrobots.

Mes variables PKG_CONFIG_PATH et LD_LIBRARY_PATH contiennent les deux chemins, et le prefix donné au moment du configure était celui de genom ( pour créer les makefiles), celà crée un conflit quelque part. J'ai donc modifié mes variable PKG_CONFIG_PATH et LD_LIBRARY_PATH pour ne contenir qu'un seul chemin, celui de genom.

Merci à vous mamiemando
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
19 déc. 2012 à 19:47
Merci pour ces précisions !
0