IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Compilation et "undefined reference"


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2011
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2011
    Messages : 75
    Points : 88
    Points
    88
    Par défaut Compilation et "undefined reference"
    Bonjour,

    J'ai entre les mains un code censé être propre (un mec a quand même fait sa thèse dessus...).

    Le code est libre, c'est le premier lien dans les Softwares http://en.wikipedia.org/wiki/K-means%2B%2B#Software (David Arthur), si ça peut vous aider...

    Bref, le problème est que le code est en C++, et que moi je connais le python, le java, j'ai des notions rapides de C, mais ca s'arrête là. Heureusement, je n'ai pas l'intention de toucher au code (pour le moment), je veux juste compiler et l'exécuter.

    J'ai donc cherché sur le net comment compiler du c++, ca m'a donné ça :

    > /kmpp$ g++ -o kmeans KMeans.cpp
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 12
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 2 has invalid symbol index 2
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 3 has invalid symbol index 2
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 4 has invalid symbol index 11
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 5 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 6 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 7 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 8 has invalid symbol index 2
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 9 has invalid symbol index 2
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 10 has invalid symbol index 12
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 11 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 12 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 13 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 14 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 15 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 16 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 17 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 18 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 19 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 20 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 21 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/i386-linux-gnu/crt1.o(.debug_info): relocation 22 has invalid symbol index 21
    /usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crt1.o: In function `_start':
    (.text+0x18): undefined reference to `main'
    /tmp/cczEr47h.o: In function `RunKMeansOnce(KmTree const&, int, int, int, double*, double*, double*, double*, double*, double, double*, double*, double*, double*, int*)':
    KMeans.cpp:(.text+0xcc): undefined reference to `KmTree::DoKMeansStep(int, double*, int*) const'
    KMeans.cpp:(.text+0x39a): undefined reference to `KmTree::DoKMeansStep(int, double*, int*) const'
    /tmp/cczEr47h.o: In function `RunKMeans(int, int, int, double*, int, double*, int*)':
    KMeans.cpp:(.text+0x93f): undefined reference to `__KMeansAssertionFailure(char const*, int, char const*)'
    KMeans.cpp:(.text+0xa33): undefined reference to `KmTree::KmTree(int, int, double*)'
    KMeans.cpp:(.text+0xb54): undefined reference to `__KMeansAssertionFailure(char const*, int, char const*)'
    KMeans.cpp:(.text+0xd6b): undefined reference to `KmTree::~KmTree()'
    KMeans.cpp:(.text+0xdd0): undefined reference to `KmTree::~KmTree()'
    /tmp/cczEr47h.o: In function `RunKMeansPlusPlus(int, int, int, double*, int, double*, int*)':
    KMeans.cpp:(.text+0xe16): undefined reference to `__KMeansAssertionFailure(char const*, int, char const*)'
    KMeans.cpp:(.text+0xf07): undefined reference to `KmTree::KmTree(int, int, double*)'
    KMeans.cpp:(.text+0x1021): undefined reference to `__KMeansAssertionFailure(char const*, int, char const*)'
    KMeans.cpp:(.text+0x1074): undefined reference to `KmTree::SeedKMeansPlusPlus(int, double*) const'
    KMeans.cpp:(.text+0x1152): undefined reference to `KmTree::~KmTree()'
    KMeans.cpp:(.text+0x11b4): undefined reference to `KmTree::~KmTree()'
    collect2: ld a retourné 1 code d'état d'exécution
    > /kmpp$ ls
    KMeans.cpp KMeans.cpp~ KMeans.h KmTree.cpp KmTree.h KmUtils.cpp KmUtils.h README.txt sample_input.txt spam_input.txt TestKm.cpp
    Déjà la première moitié on dirait des erreurs dues à linux, je les comprends pas trop trop.
    Et après c'est des undefined references, que je comprends pas non plus, je sais pas ce que ca veut dire vu que ya pas ces références dans les fonctions.

    Exemple, KMeans.cpp/RunKMeansPlusPlus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    Scalar RunKMeansPlusPlus(int n, int k, int d, Scalar *points, int attempts,
                             Scalar *ret_centers, int *ret_assignment) {
      KM_ASSERT(k >= 1);
     
      // Create the tree and log
      LOG(false, "Running k-means++..." << endl);
      KmTree tree(n, d, points);
      LOG(false, "Done preprocessing..." << endl);
     
      // Initialization
      Scalar *centers = (Scalar*)malloc(sizeof(Scalar)*k*d);
      KM_ASSERT(centers != 0);
      Scalar min_cost = -1, max_cost = -1, total_cost = 0;
      double min_time = -1, max_time = -1, total_time = 0;
     
      // Run all the attempts
      for (int attempt = 0; attempt < attempts; attempt++) {
        double start_time = GetSeconds();
     
        // Choose centers using k-means++ seeding			<<<<<--------------------               iiiiiiiiiiiiiiiiiiiiiiiiiiii
        tree.SeedKMeansPlusPlus(k, centers);
     
        // Run k-means
        RunKMeansOnce(tree, n, k, d, points, centers, &min_cost, &max_cost, &total_cost, start_time,
                      &min_time, &max_time, &total_time, ret_centers, ret_assignment);
      }
      LogMetaStats(min_cost, max_cost, total_cost, min_time, max_time, total_time, attempts);
     
      // Clean up and return
      free(centers);
      return min_cost;
    }
    Enfin voilà, moi tout ce que je veux c'est utiliser ce programme :( le modifier ca sera pour plus tard.

    Des inspirés ?

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Je ne connais pas vraiment gcc, mais tu devrais déjà utiliser l'option -c avant -o, et voir ce que ça donne.

    Peut-être devrais-tu aller voir cette page.

  3. #3
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2011
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2011
    Messages : 75
    Points : 88
    Points
    88
    Par défaut
    Effectivement, g++ -c -o testkmeans KMeans.cpp me renvoie aucune erreur.

    J'ai plutôt compilé TestKm, qui contient un main. Mais quand je fais ./testkmeans, il me dit "permission non accordée"...

    je dois tous les compiler ?

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Je pense que tu dois compiler tous les .cpp, sauf TestKm.cpp, faire des fichiers objets résultants une bibliothèque statique, puis compiler TestKm.cpp et en faire un exécutable (faisant appel à ta bibliothèque).

  5. #5
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2011
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2011
    Messages : 75
    Points : 88
    Points
    88
    Par défaut
    En utilisant le lien qui tu m'as donné dans ta première réponse, j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    gcc -c KMeans.cpp -o KMeans.o
    gcc -c KmTree.cpp -o KmTree.o
    gcc -c KmUtils.cpp -o KmUtils.o
     
    ar rcs KMeans.a KMeans.o
    ar rcs KmTree.a KmTree.o
    ar rcs KmUtils.a KmUtils.o
    Aucune erreur.

    et après gcc TestKm.cpp -o testkmeans me renvoie un message d'erreur tellement gros que ca serait inutile de le linker.

    sur le site il y a écrit que la commande est gcc -static main.c -L. -lmean -o statically_linked dans leur exemple. Mais je n'ai pas bien compris le sens des -L. et -l...

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Tu dois je pense créer une sule bibliothèque à partir des trois fichiers objets.
    Ce qui donnerait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ar rcs KM.a KMeans.o KmTree.o KmUtils.o
    Ensuite, utilise la commande avec static.

    -L donne le chemin des bibliothèques, et -l leur nom.

  7. #7
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2011
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2011
    Messages : 75
    Points : 88
    Points
    88
    Par défaut
    > /kmpp$ ls
    KM.a KMeans.cpp~ KMeans.o KmTree.h KmUtils.cpp KmUtils.o sample_input.txt TestKm.cpp
    KMeans.cpp KMeans.h KmTree.cpp KmTree.o KmUtils.h README.txt spam_input.txt
    > /kmpp$ gcc -static TestKm.cpp -o testkmeans -L. -lKM.a
    /usr/bin/ld: cannot find -lKM.a
    collect2: ld a retourné 1 code d'état d'exécution
    > /kmpp$ gcc -static TestKm.cpp -o testkmeans -L //home/tahi/Téléchargements/kmpp -l KM.a
    /usr/bin/ld: cannot find -lKM.a
    collect2: ld a retourné 1 code d'état d'exécution
    il le trouve pas o.O

    Il me renvoie la même chose quand je mets le chemin absolu à la place du point, ou quand je mets un espace.

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Ben quand tu fais ton ls, KM.a n'apparaît pas.
    Il est donc normal que gcc ne le trouve pas.

  9. #9
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2011
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2011
    Messages : 75
    Points : 88
    Points
    88
    Par défaut
    Bin si, il est premier dans la liste

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par bzerath Voir le message
    Bin si, il est premier dans la liste
    Ah oui, effectivement...

    Je crois qu'il faut que le nom de ton fichier .a commence par le préfixe lib, mais que tu dois omettre ce préfixe quand tu le désigne à l'aide du commutateur -l.

    Mais comme je te l'ai dit, je ne connais quasiment pas gcc...

  11. #11
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2011
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2011
    Messages : 75
    Points : 88
    Points
    88
    Par défaut
    Bon, heureusement j'ai eu la chance de tomber sur un copain qui connait le C++, il m'a fait un makefile rapidos.

    Pour ceux que ca intéresse...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CXX=g++
    CFLAGS=-W -Wall
    LDFLAGS=
    EXEC=kmpp
    OBJ= KMeans.o KmUtils.o KmTree.cpp TestKm.cpp
     
    all: $(EXEC)
     
    $(EXEC): $(OBJ)
    	$(CXX) -o $@ $^ $(LDFLAGS)
     
    %.o: %.cpp
    	$(CXX) -o $@ -c $< $(CFLAGS)
     
    clean:
    	rm *.o
    Merci quand même oodini !

  12. #12
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par oodini Voir le message
    Ah oui, effectivement...

    Je crois qu'il faut que le nom de ton fichier .a commence par le préfixe lib, mais que tu dois omettre ce préfixe quand tu le désigne à l'aide du commutateur -l.

    Mais comme je te l'ai dit, je ne connais quasiment pas gcc...
    Tu as néanmoins raison. Le nom d'une librairie sous Unix est de la forme : lib$(nom).$(suffixe) où suffixe est a ou so (pour une librairie dynamique). $(nom) est quelconque. A l'édition de lien, on peut utliser les librairies de deux façons différentes :

    1/ gcc ... -L$(chemin) -l$(nom)

    Va chercher les librairies dans $(chemin), et en particulier une librairie lib$(nom).*, de manière à la lier avec le programme.

    2/ gcc .... $(chemin)/lib$(nom).a

    Va chercher la librairie lib$(nom).a dans le répertoire $(chemin) pour la lier avec le programme.

    Histoire de résoudre ton casse-tête, voici un fichier Makefile à copier dans ton répertoire courant. Ensuite, "make" devrait construire la librairie ET l'exécutable.

    Code Makefile : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    # programmes
    LD := gcc
    CC := gcc
    AR := ar
     
    # cibles
    SRCS_pgm := $(shell grep "[^a-zA-Z0-9_]main(" *.c | cut -d ':' -f 1 | head -n 1)
    SRCS_lib := $(filter-out $(SRCS_pgm),$(wildcard *.c))
     
    OBJS_pgm := $(SRCS_pgm:%.c=%.o)
    OBJS_lib := $(SRCS_lib:%.c=%.o)
     
    TARGET_pgm := $(SRCS_pgm:%.c=%)
    TARGET_lib := lib$(TARGET_pgm).a
     
    # flags
    LDFLAGS += -L.
    LIBS += -l$(TARGET_pgm)
     
    .phony: all clean FORCE
     
    all: $(TARGET_pgm)
     
    $(TARGET_pgm): $(TARGET_lib) $(OBJS_pgm)
    	$(LD) $(LDFLAGS) -o $@ $(OBJS_pgm) $(LIBS)
     
    $(TARGET_lib): $(OBJS_lib)
    	$(AR) cru $@ $^
     
    %.o: %.c
    	$(CC) $(CFLAGS) -o $@ -c $<
     
    clean: FORCE
    	rm -f $(OBJS_libs)
    	rm -f $(OBJS_pgm)
    	rm -f $(TARGET_lib)
    	rm -f $(TARGET_pgm)
     
    FORCE:

    Pas testé, mais devrait fonctionner (attention : les caractères blancs qui sont en début de ligne sont des tabulation, pas des espaces).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SDL_mixer] Compilation sous windows, undefined reference
    Par sunny62 dans le forum SDL
    Réponses: 10
    Dernier message: 05/02/2015, 14h00
  2. Réponses: 5
    Dernier message: 17/10/2007, 01h10
  3. Réponses: 5
    Dernier message: 04/10/2007, 18h11
  4. Compilation de xmms : undefined reference to...
    Par Michaël dans le forum Applications et environnements graphiques
    Réponses: 4
    Dernier message: 04/02/2005, 19h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo