Compiler une librairie C

UniXUniX Membre
juin 2007 modifié dans Actualités #1
Salut à  tous.


Je suis en train de me pencher sur un sujet qui consiste à  intégrer une librairie C dans un projet Cocoa.
Un exemple, une librairie pour faire des TIFF : libtiff.

Si j'ai bien tout compri en lisant pas mal de sujets, la première étape est de compiler la librairie, puis l'ajouter dans le projet Xcode, et enfin déclarer le .h et faire des appels aux méthodes.

Je bute déjà  sur la première étape, comment compiler la librairie ? J'ai lu que ça se passait avec une ligne de commande, mais je n'ai pas réussi à  trouver la syntaxe ...
«1

Réponses

  • schlumschlum Membre
    16:11 modifié #2
    ./configure
    make

    Y a sans doute des options avec ./configure pour obtenir une bibliothèque statique.
  • UniXUniX Membre
    16:11 modifié #3
    Ouais, en fait j'ai vu ça, je l'ai fait, mais .... le problème, c'est que je suis vraiment nul dans tout ça, et je ne sais même pas ce que ça doit faire ....! J'ai essayé de voir s'il y avait eu un fichier créé, j'ai pas vu ....
  • schlumschlum Membre
    16:11 modifié #4
    Une fois que c'est passé, il faut faire "make install" pour installer les bibliothèques et headers à  l'endroit indiqué au niveau du ./configure (/usr/local par défaut)
  • UniXUniX Membre
    16:11 modifié #5
    Ouais OK, vu.
    J'ai donc plusieurs fichiers qui ont été placés dans /usr/local/

    J'ai :
    - libtiff.dylib
    - libtiff.a
    - libtiff.la
    - libtiffxx.dylib
    - libtiffxx.a
    - libtiffxx.la

    Bon, donc là , j'ai compilé la librairie.

    Maintenant, il faut l'importer dans le projet Xcode. Il faut importer quel fichier ? J'imagine qu'il n'y en a qu'un d'important. Et il faut l'ajouter dans Resources ?
  • schlumschlum Membre
    16:11 modifié #6
    Les .dylib sont des bibliothèques dynamiques ; tu peux les inclures, mais en diffusant ton application, il faudra que la personne qui la lance ait la même bibliothèque au même endroit.
    Tu peux également les copier dans les ressources de ton appli et les utiliser comme ça.

    Mais le mieux c'est quand même d'utiliser les .a (bibliothèques statiques) ; ça sera intégré dans ton exécutable comme ça...

    Les .la, je ne sais pas trop ce que c'est...

    Sinon, "libtiff", c'est la standard ; "libtiffxx", j'imagine que c'est une "improved" plus lourde ?
  • UniXUniX Membre
    16:11 modifié #7
    Pour libtiffxx, ça doit plutot être l'inverse, une light, car elle pèse 80 ko contre 910 pour libtiff ....

    Je me suis amusé à  compiler deux autres librairies, et effectivement, le fichier qui est crée à  chaque fois, c'est le .a

    Donc, j'ai ma librairie statique que j'importe dans Xcode. Je l'ai ajoutée, en choisissant Add existing files du menu contextuel de Resources. Ma librairie apparait donc avec son icone de caisse à  outils ...

    Et maintenant, j'ai fini ?
  • schlumschlum Membre
    16:11 modifié #8
    Oui... Pour les .a, pas besoin de les ajouter aux ressources ; il suffit que le projet sache où elle est, et elle sera incluse à  l'édition de lien.
  • UniXUniX Membre
    16:11 modifié #9
    OK.

    Et au niveau du code, j'ai quoi à  faire ? Un #import quelque part ... ?
  • schlumschlum Membre
    16:11 modifié #10
    #include "libtiff.h"

    Il faut que tu importes le .h dans le projet aussi quand même...
  • UniXUniX Membre
    16:11 modifié #11
    OK. ça roule.
    Merci pour ta patience .... ;)
  • UniXUniX Membre
    16:11 modifié #12
    Question subsidiaire un peu hors du sujet, mais qui est la suite logique ...

    J'ai un fichier fichier.c qui contient une seule méthode, un main(), et qui effectue tout un tas d'opération, en faisant appel à  des méthodes de la librairie récemment importée.
    Comment faire pour lancer l'exécution de ce main() depuis une méthode Cocoa ?
  • schlumschlum Membre
    16:11 modifié #13
    dans 1180906099:

    Question subsidiaire un peu hors du sujet, mais qui est la suite logique ...

    J'ai un fichier fichier.c qui contient une seule méthode, un main(), et qui effectue tout un tas d'opération, en faisant appel à  des méthodes de la librairie récemment importée.
    Comment faire pour lancer l'exécution de ce main() depuis une méthode Cocoa ?

    Euh... En mettant dans la méthode Cocoa le contenu du main...  :)
  • UniXUniX Membre
    16:11 modifié #14
    Ouais  :)
    J'étais parti pour le faire, et puis je me suis dit qu'il devait y avoir une façon de faire plus correcte.

    Bon, ben on va faire ça ....!
  • UniXUniX Membre
    16:11 modifié #15
    Par contre, le main() attend un argument de type char. Moi j'ai une NSString à  lui filer, alors pour la transformer en char, j'ai fait :
    [stringATransformer cStringUsingEncoding:NSUTF8StringEncoding]
    


    Mais le compilo me met un warning comme quoi c'est pas le type attendu. J'ai pas employé la bonne méthode ?
  • schlumschlum Membre
    16:11 modifié #16
    Là , il va falloir plus de code pour voir ce qui ne va pas...
  • UniXUniX Membre
    16:11 modifié #17
    J'ai le warning au niveau de l'appel à  bsb_open_header().
    Malgrès tout, ça à  l'air de fonctionner.

    BSBImage	image;<br />			int			i;<br />			uint16_t	red[256], green[256], blue[256];<br />			TIFF*		tif;<br />			uint8_t		*buf;<br />			<br />			bsb_open_header([cheminCarte UTF8String], &amp;image);<br />			<br />			/* Initialise colormap entries */<br />			memset(red, 0, sizeof(red));<br />			memset(green, 0, sizeof(green));<br />			memset(blue, 0, sizeof(blue));<br />			<br />			/* convert BSB colormap to libtiff style colormap */<br />			for (i = 0; i &lt; image.num_colors; i++)<br />			{<br />				red[i] = image.red[i] * 65536 / 256;<br />				green[i] = image.green[i] * 65536 / 256;<br />				blue[i] = image.blue[i] * 65536 / 256;<br />			}<br />			<br />			buf = (uint8_t *)malloc(image.width);<br />			if (! buf)<br />				exit(1);<br />			<br />			/* Open tif file for output (truncates any existing file) */<br />			tif = TIFFOpen([cheminCarteTempo UTF8String], &quot;w&quot;);<br />			if (! tif)<br />			{<br />				perror([cheminCarteTempo UTF8String]);<br />				exit(1);<br />			}<br />			<br />			/* From TIFF spec, these are required fields for palette-color images */<br />			TIFFSetField(tif,TIFFTAG_IMAGEWIDTH, image.width);<br />			TIFFSetField(tif,TIFFTAG_IMAGELENGTH, image.height);<br />			/* Can&#39;t rely on tiff library having LZW support so use PACKBITS */<br />			TIFFSetField(tif,TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);<br />			/* BSB is strictly a colormap only format */<br />			TIFFSetField(tif,TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);<br />			TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP, 1);<br />			TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE, 8);<br />			/* CONTIG means R G B grouped together in each STRIP */<br />			TIFFSetField(tif,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);<br />			TIFFSetField(tif,TIFFTAG_COLORMAP, red, green, blue);<br />			<br />			/* Read rows from bsb file, write to tif file */<br />			for (i = 0; i &lt; image.height; i++)<br />			{<br />				bsb_seek_to_row(&amp;image, i);<br />				bsb_read_row(&amp;image, buf);<br />				TIFFWriteScanline(tif, buf, i, 0);<br />			}<br />			<br />			TIFFClose(tif);<br />			free(buf);<br />			<br />			bsb_close(&amp;image);
    
  • schlumschlum Membre
    16:11 modifié #18
    Quelle est la signature de la fonction "bsb_open_header" ?
  • UniXUniX Membre
    16:11 modifié #19
    Ah oui pardon, il était tard ....
    extern int bsb_open_header(char *filename, BSBImage *p)
    
  • BruBru Membre
    16:11 modifié #20
    -[NSString UTF8String] renvoie un const char *, alors que bsb_open_header() veut recevoir un char * : comme y'a bon différence de signature, y'a bon warning.

    Si tu veux éliminer ce message sans conséquence, caste !
    <br />bsb_open_header( (const char *)[cheminCarte UTF8String], &amp;image);<br />
    


    .
  • schlumschlum Membre
    16:11 modifié #21
    Oui, il faut un cast à  cause du "const"

    "UTF8String" te renvoie un "const char*" que tu donnes à  "bsb_open_header" qui prend un "char*" (il est donc susceptible de le modifier ! Un oubli du programmeur je pense, car en général ces fonctions prennent du "const")...

    -> (char*)[cheminCarte UTF8String]
  • UniXUniX Membre
    16:11 modifié #22
    OK, merci les gars.
    ;)
  • UniXUniX Membre
    16:11 modifié #23
    Salut.

    Je resors un peu ce sujet pour un complément.
    Lorsque j'ai compilé la librairie, les paramètres définis étaient ceux pour ma machine (Intel). Du coup la librairie n'est pas Universal Binaries ....

    Comment faut-il s'y prendre pour crééer une version UB ?

    J'ai trouvé une note technique d'Apple qui traite du sujet, mais j'avoue ne pas avoir tout compris ...
    Lien
  • schlumschlum Membre
    16:11 modifié #24
    D'abord, on ne dit pas une "librairie", mais une "bibliothèque" (traduction littérale de "library")  :P

    Ensuite, pour créer de l'UB, il faut compiler une fois avec -ppc, une autre avec -i386, et ensuite assembler les deux exécutables avec lipo...
    Je crois qu'on peut le faire en une étape avec -ppc et -i386 d'un coup, mais pas sûr.
  • UniXUniX Membre
    16:11 modifié #25
    Oui j'ai cru comprendre ça.
    Le problème c'est que je ne sais pas trop comment le mettre en oeuvre ....

    Pour la version i386, je l'ai puisque c'est celle que j'ai obtenu en suivant tes conseils. Pour la PPC, comment la faire ?
    Et lipo ?
  • schlumschlum Membre
    16:11 modifié #26
    Même chose, en ajoutant l'option -arch ppc (et pas -ppc comme j'ai dit au dessus...), et en enlevant éventuellement -arch i386 (et pas...)

    Pour "lipo" -> man lipo
  • UniXUniX Membre
    16:11 modifié #27
    Eeuuhh oui, amsi à  quel moment ?
    Pour construire la version i386, je n'ai fait que :
    ./configure
    make
    make install
  • schlumschlum Membre
    16:11 modifié #28
    ben faut refaire pareil, mais avec "-arch ppc" dans $CFLAGS
  • UniXUniX Membre
    16:11 modifié #29
    Tu vas me trouver bébête, mais là  je suis largué ....
    Je le trouve ou le $CFLAGS à  modifier ?
    Je viens de passer tout les fichiers de configuration de la bibliothèque, et je n'ai rien trouvé de concluant, en tout cas pas quelquechose du style "-arch i386" ou "-arch ppc" .... :(
  • schlumschlum Membre
    16:11 modifié #30
    C'est une variable d'environnement du shell  :P
  • UniXUniX Membre
    16:11 modifié #31
    OK, c'est donc dans le terminal que je dois paramétrer cette variable.
    Il faut que je fasse quoi comme commande ?
    $CFLAGS="-arch ppc" ?

    Dans la note technique d'Apple, ils mettent :
    CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc"
    LDFLAGS="-arch i386 -arch ppc"
    ./configure --prefix=${HOME}/Hello --disable-dependency-tracking
Connectez-vous ou Inscrivez-vous pour répondre.