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 :

clang 'undifined symbol' incomprehension


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 33
    Points : 32
    Points
    32
    Par défaut clang 'undifined symbol' incomprehension
    Bonjour,

    Je compile habituellement sur GCC avec comme flag -Wall -Wextra et -Werror. Et jusqu'ici pas de soucis.
    Me voici maintenant sur clang et j'obtiens une erreur au moment de la résolution des liens que je n'arrive ni à comprendre, ni à résoudre.. Peut être est-ce parce que je m'y prend mal mais que GCC est gentil?.. Lui!

    Cette erreur apparait à chaque fois que j'essaie d'utiliser une variable global déclarée dans une librairie (*.a)

    Voici mon test réalisé sur de très petits fichiers pour isolé l'erreur: (2 fichier sources 'test.c' et 'use_test.c' + 1 header 'test.h' pour créer une petite librairie libtest.a) + un fichier 'main.c' qui tente d'utiliser cette librairie..

    test.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #ifndef TEST_H
    # define TEST_H
     
    # include <stdio.h>
     
    extern int	g_test;
     
    int	        use_global_test(void);
     
    #endif
    test.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #include "test.h"
     
    int	g_test;
    use_test.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #include "test.h"
     
    int	use_global_test(void)
    {
    	g_test = 42;
    	printf("g_test  successfully affected: `g_test = %d`\n", g_test);
    	return (0);
    }
    La creation de 'libtest.a' (qui ne retourne aucune erreur):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    clang -Wall -Wextra -Werror -o test.o -c test.c -I.
    clang -Wall -Wextra -Werror -o use_test.o -c use_test.c -I.
     
    ar rc libtest.a test.o use_test.o
    main.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include "test.h"
     
    int	main(void)
    {
    	use_global_test();
    	return (0);
    }
    Et enfin la compile qui foire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    clang -Wall -Wextra -Werror -o test main.c -L. -ltest -I.
    L'erreur en question:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Undefined symbols for architecture x86_64:
      "_g_test", referenced from:
          _use_global_test in libtest.a(use_test.o)
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    Je mettrai le résultat de la compile avec -v si vous ne voyez pas d'énormité de ma part.. Mais elle ne me dit rien de très intéressant..

    Merci!

  2. #2
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Hello,

    Tu parles de clang, mais tu mets les lignes de compilation de gcc... C'est vraiment ton cas ?

    Est-ce que tu as bien compilé la lib ET l’exécutable avec le même compilateur ?
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 33
    Points : 32
    Points
    32
    Par défaut
    Autant pour moi.. J'ai fais un copié/collé, j'édite tout de suite.

    En fait chez moi c'est gcc sur Debian.
    A l'école c'est clang sur mac os, avec un alias gcc=clang, donc clang dans tous les cas.

    J'ai fais le test ce matin (à l'école) avec les fichiers de mon premier post, rien de plus, rien de moins, en direct.. Donc oui tout compilé avec le même compilateur exactement comme sur le premier post (édité).

    Merci pour l’intérêt que tu portes à mon cas!

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Petite question, parce que je ne sais pas: clang reprend les memes options que gcc, concernant les -W...?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 33
    Points : 32
    Points
    32
    Par défaut
    Bonjour,

    Un 'clang --help' indique:

    -W<warning> Enable the specified warning


    Pas très spécifique.. Et je ne trouve rien concernant la liste de ces warnings sur mon man.
    Par contre, -Wall -Wextra -Werror ne déclenchent par d'erreurs, contrairement à -Wtoto:

    error: unknown warning option '-Wtoto' [-Werror,-Wunknown-warning-option]

    Sur le net j'ai pu lire que clang était plus pointilleux.. cf: https://spin.atomicobject.com/2013/1...lang-compiler/

    Voilà voilà.

  6. #6
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Oui, les compilateurs n'ont pas la même interprétation des normes, et gcc est connu pour être particulièrement peu regardant (une des raisons de son succès ?), mais cela n'explique pas pourquoi tu as une erreur.

    Ce que je trouve étrange, c'est l'erreur est sur _g_test, pas sur g_test. Est-ce que tu peux faire le test en créant un nouveau répertoire, dans lequel tu copies/colle les fichiers que tu as mis dans ton post ? Est-ce que tu as toujours la même erreur ?
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  7. #7
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour

    Citation Envoyé par sben42 Voir le message
    Bonjour,

    Je compile habituellement sur GCC avec comme flag -Wall -Wextra et -Werror. Et jusqu'ici pas de soucis.
    Me voici maintenant sur clang et j'obtiens une erreur au moment de la résolution des liens que je n'arrive ni à comprendre, ni à résoudre.. Peut être est-ce parce que je m'y prend mal mais que GCC est gentil?.. Lui!

    Cette erreur apparait à chaque fois que j'essaie d'utiliser une variable global déclarée dans une librairie (*.a)

    Voici mon test réalisé sur de très petits fichiers pour isolé l'erreur: (2 fichier sources 'test.c' et 'use_test.c' + 1 header 'test.h' pour créer une petite librairie libtest.a) + un fichier 'main.c' qui tente d'utiliser cette librairie..

    test.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #ifndef TEST_H
    # define TEST_H
     
    # include <stdio.h>
     
    extern int	g_test;
     
    int	        use_global_test(void);
     
    #endif
    test.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #include "test.h"
     
    int	g_test;
    use_test.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #include "test.h"
     
    int	use_global_test(void)
    {
    	g_test = 42;
    	printf("g_test  successfully affected: `g_test = %d`\n", g_test);
    	return (0);
    }
    La creation de 'libtest.a' (qui ne retourne aucune erreur):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    clang -Wall -Wextra -Werror -o test.o -c test.c -I.
    clang -Wall -Wextra -Werror -o use_test.o -c use_test.c -I.
     
    ar rc libtest.a test.o use_test.o
    main.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include "test.h"
     
    int	main(void)
    {
    	use_global_test();
    	return (0);
    }
    Et enfin la compile qui foire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    clang -Wall -Wextra -Werror -o test main.c -L. -ltest -I.
    L'erreur en question:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Undefined symbols for architecture x86_64:
      "_g_test", referenced from:
          _use_global_test in libtest.a(use_test.o)
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    Je mettrai le résultat de la compile avec -v si vous ne voyez pas d'énormité de ma part.. Mais elle ne me dit rien de très intéressant..

    Merci!
    Premièrement, la fonction ci-dessus sert à rien vaut mieux affecter directement la variable autrement ou avec une constante que de passer par une fonction qui renvoie inutilement 0 pour dire que tout s'est bien passé même s'il s'agit d'un test.
    À la limite pour un test, opté pour une fonction simple qui incrément une variable statique (par exemple)

    Je suis sur Mac et personnellement le problème vient directement de la chaîne de compilation.
    Avant tout, il faut respecter certaines règles. Toute bibliothèque statique ou dynamique commence avec les trois lettres "lib" (faite un tour dans ls /opt/local/lib pour constater)
    reprenons depuis le début:
    Code C : 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
     
    /*
     ============================================================================
     Name        : Untitled.c
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright (c) 22/04/2016 SAMBIA39
     Description : Ansi-style
     ============================================================================
     */
     
    #ifndef MYLIBT_H
    #define MYLIBT_H
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
     
    int f_get_inc( void );
     
    #endif
    Code C : 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
     
    /*
     ============================================================================
     Name        : Untitled.c
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright (c) 22/04/2016 SAMBIA39
     Description : Ansi-style
     ============================================================================
     */
     
     #include "mylib.h"
     
    int f_get_inc( void ){
     
        static int s_ival;
        return s_ival++;
    }
    Code C : 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
     
    /*
     ============================================================================
     Name        : Untitled.c
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright (c) 22/04/2016 SAMBIA39
     Description : Ansi-style
     ============================================================================
     */
     
     #include "mylib.h"
     
     int main( void ){
     
         int i = 0;
         for( i = 0; i < 10; i = f_get_inc() )
            fprintf( stdout, "(%d)\thi !!\n", i );
     
        return EXIT_SUCCESS;
     }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    gcc -c mylib.c -Wall -Wextra -Werror -o mylib.o   /* Transformation en un fichier objet  de mylib.c */
    ar rcs libmylib.a mylib.o /* invocation ar pour produire une bibliothèque statique "libmylib" */
    ranlib libmylib.a /* génération des index de fonctions pour que l'archive devienne une bibliothèque statique ce qui manquait dans la chaîne de compilation d'où les différents messages d'erreur. */
    gcc source.c -Wall -Wextra -Werror -L. -lmylib -o Teste /* Remarque ne pas écrire "-llibmylib" mais plutôt "-lmylib"
    Code ./out : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    (0)     hi !!
    (0)     hi !!
    (1)     hi !!
    (2)     hi !!
    (3)     hi !!
    (4)     hi !!
    (5)     hi !!
    (6)     hi !!
    (7)     hi !!
    (8)     hi !!
    (9)     hi !!

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

Discussions similaires

  1. [Objective-C] undifined symbol for architecture i386
    Par smobydick dans le forum Objective-C
    Réponses: 9
    Dernier message: 26/03/2013, 14h24
  2. Code ASCII du symbole Euro
    Par FW-S dans le forum Delphi
    Réponses: 9
    Dernier message: 03/04/2007, 01h27
  3. Organigramme d'un algorithme, convention de symboles
    Par rstephane dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 12/06/2003, 17h47
  4. [Sybase] Définition des symboles
    Par SoaB dans le forum Sybase
    Réponses: 5
    Dernier message: 19/03/2003, 23h06
  5. symbole ##
    Par JEG dans le forum C
    Réponses: 2
    Dernier message: 23/01/2003, 19h15

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