[Résolu] Probleme template BSD Static Library

Sev3nSev3n Membre
avril 2010 modifié dans Xcode et Developer Tools #1
Bonjour,
J'ai un petit problème concernant les libraires statiques avec Xcode. J'ai essayé de créer un projet command-line tout simple (en C) pour voir comment gérer les lib static sous xcode. Donc j'ai juste créer 3 fichiers le main.c, util.h, util.c (util est ma lib).

Mon main.c
<br />#include &quot;util.h&quot;<br /><br />int main (int argc, const char * argv&#91;]) {<br />	printSomething();&nbsp; // dans la lib<br />&nbsp; &nbsp; return 0;<br />}<br />


util.h
<br />#ifndef H_UTIL_H<br />#define H_UTIL_H<br /><br />extern void printSomething(void);<br /><br />#endif<br />


util.c
<br />#include &lt;stdio.h&gt;<br /><br />void printSomething(void) {<br />	printf(&quot;hello world&#092;n&quot;);<br />}<br />


J'ai donc dans mon projet 2 targets, une pour créer l'exe et l'autre pour la lib statique qui suit le template BSD Static Library. J'ai ajouté des dépendances dans la target de l'exe et ajoute la libutil.a dans la build phase Link Binary With Library. Mais lorsque j'essaie de build l'exe le linker n'arrive pas à  trouver le symbole et affiche une erreur :

<br />Undefined symbols:<br />&nbsp; &quot;_printSomething&quot;, referenced from:<br />&nbsp; &nbsp; &nbsp; _main in ccu5JEeP.o<br />ld: symbol(s) not found<br />collect2: ld returned 1 exit status<br />


En revanche lorsque je teste via une lib shared tout fonctionne correctement. Le plus curieux c'est que lorsque j'utilise le template BSD Static library juste après (j'ai clean la build dir avant) je n'ai plus d'erreur et cela fonctionne.

J'ai aussi essayer de le faire manuellement en ligne de commande

<br />gcc -c util.c -o util.c<br />ar rs libutil.a util.o<br />gcc main.c -o main -L. -lutil<br />


J'ai toujours la même erreur alors que sous Solaris, par exemple,  ça fonctionne.

Etant novice sous mac, je voudrais comprendre pourquoi ça ne marche et savoir s'il y a des options de configurations dont j'ignore l'existence pour résoudre ce problème.

Merci.

(Je suis sous Xcode 3.2.1)

Réponses

  • Philippe49Philippe49 Membre
    00:21 modifié #2
    Essai sans problème : je Build d'abord la librairie, puis l'exécutable de test ... pas de problème ni en mode Release, ni en mode Debug

    Pourquoi mets-tu extern sur le prototype de printSomething( ) ?
  • Philippe49Philippe49 Membre
    00:21 modifié #3
    dans 1271249561:

    J'ai aussi essayer de le faire manuellement en ligne de commande

    <br />gcc -c util.c -o util.c<br />ar rs libutil.a util.o<br />gcc main.c -o main -L. -lutil<br />
    




    et en ajoutant la mise à  jour de la table de ta librairie ?

    gcc -c util.c -o util.c
    ar rs libutil.a util.o
    ranlib libutil.a
    gcc main.c -o main -L. -lutil

    Voir la page man de Libtool et ranlib ...
  • Sev3nSev3n Membre
    avril 2010 modifié #4
    Merci Philippe49  pour ta réponse.
    Concernant la première partie avec l'image du projet Xcode, j'avais exactement la même chose à  part que le main.c n'était pas dans les Compiled Sources de la target de la lib. Chez moi ça marche toujours pas. Eventuellement pourrais-tu joindre ton archive du projet pour que je teste ?
    Concernant ton second post,

    gcc -c util.c -o util.c
    ar rs libutil.a util.o
    ranlib libutil.a
    gcc main.c -o main -L. -lutil

    D'après ce que j'avais lu dans le man de ar, ar -s est équivalent à  faire un ranlib sur la lib donc ça ne change rien dans mon cas (j'ai quand même essayé de le faire explicitement histoire d'être sur).

    Par exemple, si je lance un otool -Sv libutil.a j'obtiens le résultat suivant :
    <br />&nbsp; &nbsp; ~&gt; otool -Sv libutil.a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />Archive : libutil.a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />Table of contents from: libutil.a(__.SYMDEF SORTED)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br />size of ranlib structures: 8 (number 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />size of strings: 16&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />object&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  symbol name <br />util.o&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  _printSomething<br />
    


    Comme je suis loin d'être un expert, j'ai un peu du mal à  comprendre pourquoi le linker ne trouve pas le symbole. En revanche, si je passe la lib sans le -l ça compile normalement.

    <br />gcc main.c libutil.a -o main<br />
    
  • Philippe49Philippe49 Membre
    avril 2010 modifié #5
    Voici le projet

    dans 1271416887:

    Merci Philippe49  pour ta réponse.
    Concernant la première partie avec l'image du projet Xcode, j'avais exactement la même chose à  part que le main.c n'était pas dans les Compiled Sources de la target de la lib.

    Oui, le main.c n'a aucune raison d'être là .



  • Philippe49Philippe49 Membre
    00:21 modifié #6
    Autrement la librairie fonctionne correctement en ligne de commande

    <br />% cd ~/Desktop/Sev3n<br />% gcc main.c -L./build/Debug -lSev3n -o pgm<br />% ./pgm<br />hello world<br />% <br />
    
  • Sev3nSev3n Membre
    00:21 modifié #7
    Merci Philippe49 pour ta réponse rapide.

    Je viens de comprendre mon erreur (et j'ai l'air d'un gros noob now :S).
    En fait le problème venait du nommage de ma lib. Comme le linker regarde d'abord les répertoires standards avant le -L et cherche d'abord les .dylib avant les .a il se trouve qu'il y a une lib qui s'appelle libutil.dylib dans /usr/lib ce qui s'explique pourquoi il ne trouvait pas le symbole.
    La prochaine fois, je choisirai des noms un peu moins courant, çà  m'évitera ce genre de déconvenue.

    Merci encore phil.
  • Philippe49Philippe49 Membre
    00:21 modifié #8


    Oui, j'aurais du penser aussi à  cette librairie

    A l'occasion, la lecture de la page man libtool apprend que ar est en vue d'être "deprecated" sur mac os.


    Libtool with -static is intended to replace ar(5) and ranlib. For backward compatibility, ranlib is still available, and it supports universal files. Ranlib adds or updates the table of contents to each ar_chive so it can be linked by the link editor, ld(1) .



    Le build result (menu Build > Build Result après avoir fait un Build > Clean All Targets) de la librairie donne la commande de référence suivante

    <br />Libtool build/Debug/libSev3n.a normal x86_64<br />cd /Users/bureau/Desktop/Sev3n<br />setenv MACOSX_DEPLOYMENT_TARGET 10.6<br />/Developer/usr/bin/libtool -static -arch_only x86_64 -syslibroot /Developer/SDKs/MacOSX10.6.sdk -L/Users/bureau/Desktop/Sev3n/build/Debug -filelist /Users/bureau/Desktop/Sev3n/build/Sev3n.build/Debug/Sev3n.build/Objects-normal/x86_64/Sev3n.LinkFileList -o /Users/bureau/Desktop/Sev3n/build/Debug/libSev3n.a<br />
    
Connectez-vous ou Inscrivez-vous pour répondre.