2010-03-07 5 views
19

J'essaie de compiler un projet qui utilise à la fois libjpeg et libpng. Je sais que libpng a besoin de zlib, donc j'ai compilé tous les trois indépendamment et les mettre (libjpeg.a, libpng.a et libz.a) sur un dossier appelé linrel32. Ce que je puis est exercerai:Liens avec libpng & zlib?

g++ -Llinrel32/ program.cpp otherfile.cpp -o linrel32/executable -Izlib/ -Ilpng140/ -Ijpeg/ -lpthread -lX11 -O2 -DLINUX -s -lz -lpng -ljpeg

J'inclure les trois bibliothèques. Pourtant, l'éditeur de liens se plaint:

linrel32//libpng.a(png.o): In function `png_calculate_crc': 
png.c:(.text+0x97d): undefined reference to `crc32' 
linrel32//libpng.a(png.o): In function `png_reset_crc': 
png.c:(.text+0x9be): undefined reference to `crc32' 
linrel32//libpng.a(png.o): In function `png_reset_zstream': 
png.c:(.text+0x537): undefined reference to `inflateReset' 
linrel32//libpng.a(pngread.o): In function `png_read_destroy': 
pngread.c:(.text+0x6f4): undefined reference to `inflateEnd' 
linrel32//libpng.a(pngread.o): In function `png_read_row': 
pngread.c:(.text+0x1267): undefined reference to `inflate' 
linrel32//libpng.a(pngread.o): In function `png_create_read_struct_2': 

(... vous voyez l'idée: D)

collect2: ld returned 1 exit status 

Je connais les fonctions manquantes sont de zlib, et j'ajouter là zlib. Ouvert libz.a et il semble avoir une bonne structure. Recompilé, tout semble bien. Mais ce n'est pas ...

Je ne sais pas, est probablement que le problème est trivial, et ce dont j'ai besoin est de dormir pendant un certain temps. Mais encore, si vous pouviez me aider à comprendre cette chose ...

Répondre

38

Vous devez réorganiser l'ordre du bibliothèques:

-lpng -ljpeg -lz 

ce qui se passe est que l'éditeur de liens a des règles spéciales sur la façon dont il traite les bibliothèques statiques. Ce qu'il fait est qu'il inclut seulement un .o de l'intérieur du .a si le .o est nécessaire pour satisfaire une référence.

En outre, il gère les archives statiques dans l'ordre dans lequel elles apparaissent sur la ligne de liaison. Ainsi, votre code n'appelle directement aucune fonction dans zlib. Ainsi, lorsque l'éditeur de liens gère -lz en premier, il n'y a pas encore d'appels, donc il ne tire pas de zlib.

Ensuite, lorsque l'éditeur de liens gère libpng, il voit qu'il y a des appels provenant de votre code. Donc, il tire le code de libpng et comme il fait des appels à zlib, il y a maintenant des références aux fonctions de zlib.

Vous venez maintenant à la fin de vos bibliothèques et il y a des appels non satisfaits qui provoquent votre erreur.

Donc, si libhigh.a utilise liblow.a, vous devez avoir -lhighavant-llow dans votre commande de lien.

+1

Merci. Vous avez absolument raison. J'ai considéré que l'ordre était une possibilité, mais je n'avais aucune raison réelle de soutenir cette théorie. Je pensais à tort que l'éditeur de liens mettait tout dans un «pool», puis supprimait les fonctions inutilisées après avoir tracé chaque code. – huff

+0

@huff - de rien. Pour info, commandez seulement des questions pour les archives statiques; Si vous utilisiez des objets partagés, cela n'aurait aucune importance. –

+0

Mélangez maintenant par ex. CMake et le plaisir devient encore plus grand (surtout avant de passer VERBOSE = 1 à faire). Zlib est-il une bibliothèque statique? J'ai un problème similaire avec boost :: iostreams qui dépend de zlib; il échoue sur ma machine mais pas sur les autres.Quoi qu'il en soit - c'est une bonne règle générale - les dépendances les plus «basiques» viennent en dernier. –

-2

vous avez probablement besoin d'entourer les en-têtes de zlib et avec .png extern "C", par exemple:

extern "C" { 
#include <zlib.h> 
} 
+3

C'est incorrect. Si tel était le cas vous verriez des erreurs comme 'référence non définie à:" crc32 (unsigned long, char const *, unsigned int) "' et pas simplement 'référence non définie à:" crc32 "' –

+0

+1 pour me corriger. –