2010-03-07 6 views
19

Ich versuche ein Projekt zu kompilieren, das sowohl libjpeg als auch libpng verwendet. Ich weiß, dass libpng zlib benötigt, also kompilierte ich alle drei unabhängig und legte sie (libjpeg.a, libpng.a und libz.a) in einen Ordner namens linrel32. Was ich ausführen, dann ist:Verlinkung mit libpng & zlib?

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

So schließe ich die drei Bibliotheken. Dennoch beklagt sich der Linker:

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': 

(... Sie auf die Idee: D)

collect2: ld returned 1 exit status 

weiß, dass ich die fehlenden Funktionen von zlib sind, und ich bin zlib Zugabe von dort. Eröffnet libz.a und es scheint eine gute Struktur zu haben. Neukompiliert, alles sieht gut aus. Aber es ist nicht ...

Ich weiß nicht, ist wahrscheinlich, dass das Problem trivial ist, und was ich brauche, ist für eine Weile zu schlafen. Aber dennoch, wenn Sie mir helfen können, diese Sache, um herauszufinden, ...

Antwort

38

Sie müssen die Reihenfolge der neu zu ordnen Bibliotheken:

-lpng -ljpeg -lz 

Was passiert ist, dass der Linker spezielle Regeln, wie hat es statische Bibliotheken behandelt. Was es tut ist, dass es nur ein .o von innerhalb des .a enthält, wenn das .o benötigt wird, um eine Referenz zu erfüllen.

Darüber hinaus verarbeitet statische Archive in der Reihenfolge, in der sie auf der Verbindungslinie angezeigt werden.

Ihr Code ruft also keine Funktionen in zlib direkt auf. Wenn also der Linker -lz zuerst behandelt, gibt es noch keine Aufrufe, so dass er keine von zlib einliest.

Als nächstes, wenn der Linker libpng behandelt, sieht es, dass es Aufrufe von Ihrem Code gibt. Also zieht es den Code von libpng und da es Aufrufe an zlib macht, gibt es nun Verweise auf die zlib-Funktionen.

Jetzt kommen Sie zum Ende Ihrer Bibliotheken und es gibt unzufriedene Anrufe, die Ihren Fehler verursachen.

Also, wenn libhigh.a Verwendung von liblow.a macht, müssen Sie -lhighvor-llow in Ihrem Link bestellen haben.

+1

Danke. Du hast absolut recht. Ich dachte, dass die Reihenfolge eine Möglichkeit wäre, aber ich hatte keinen wirklichen Grund, diese Theorie zu unterstützen. Ich dachte fälschlicherweise, dass der Linker alles in einen "Pool" legte, und löschte dann die unbenutzten Funktionen, nachdem er jedes Stück Code verfolgt hatte. – huff

+0

@huff - Gern geschehen. FYI, Bestellung nur für statische Archive; Wenn Sie geteilte Objekte verwenden, ist das egal. –

+0

Jetzt mische z.B. CMake und der Spaß wird noch größer (vor allem vor dem Übergeben von VERBOSE = 1 zu machen). Ist zlib eine statische Bibliothek? Ich habe ein ähnliches Problem mit boost :: iostreams, die von zlib abhängen; es scheitert an meiner Maschine, aber nicht an anderen.Wie auch immer - das ist eine gute Faustregel - die meisten "grundlegenden" Abhängigkeiten kommen zuletzt. –

-2

Sie wahrscheinlich die zlib und png-Header mit extern "C" umgeben benötigen, zB:

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

Das ist falsch. Wenn das der Fall wäre, würden Sie Fehler wie "undefinierter Verweis auf:" crc32 (unsigned long, charconst *, unsigned int) "' und nicht nur 'undefined Verweis auf:" crc32 "' –

+0

+1 für die Korrektur von mir sehen. –