2010-03-07 86 views
19

我試圖編譯一個同時使用libjpeg和libpng的項目。我知道libpng需要zlib,所以我編譯了所有這三個獨立並將它們(libjpeg.a,libpng.a和libz.a)放在名爲linrel32的文件夾中。我執行則是:與libpng&zlib鏈接?

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

所以,我包括三個庫。儘管如此,鏈接器抱怨:

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

(...你的想法:d)

collect2: ld returned 1 exit status 

我知道缺少的功能是從zlib的,和我添加的zlib那裏。打開libz.a,它似乎有一個很好的結構。重新編譯它,一切看起來都很好。但它不是...

我不知道,這很可能是問題微不足道,我需要的是睡一會兒。但儘管如此,如果你能幫助我弄清楚這件事......

回答

38

您需要重新排列的順序庫:

-lpng -ljpeg -lz 

正在發生的事情是,在連接器上有如何對待靜態庫的特殊規則。它所做的只是在.a中包含.o,如果需要.o來滿足參考。

此外,它按照它們出現在鏈接行上的順序處理靜態存檔。

因此,您的代碼不會直接調用zlib中的任何函數。所以,當鏈接器首先處理-lz時,還沒有任何調用,所以它不會拉入任何zlib。

接下來,當鏈接器處理libpng時,它會看到您的代碼中存在對它的調用。所以它從libpng中提取代碼,並且由於它調用了zlib,所以現在引用了zlib函數。

現在你來到你的圖書館的盡頭,並且有不滿意的調用會導致你的錯誤。

所以,如果libhigh.a利用liblow.a的,你必須有-lhigh以前-llow在您的鏈接順序。

+1

謝謝。你是絕對正確的。我認爲這個命令是可能的,但我沒有任何真正的理由支持這個理論。我錯誤地認爲鏈接器將所有內容放入「池」中,然後在追蹤每段代碼後刪除未使用的函數。 – huff 2010-03-07 06:14:41

+0

@huff - 不客氣。僅供參考,訂單僅適用於靜態檔案;如果您使用共享對象,則無關緊要。 – 2010-03-07 06:16:20

+0

現在混入例如CMake和樂趣變得更大(特別是在傳遞VERBOSE = 1之前)。 zlib是一個靜態庫嗎? boost :: iostreams依賴zlib存在類似的問題;它在我的機器上失敗,但在其他機器上失敗。無論如何 - 這是一個很好的經驗法則 - 最「基本」的依賴關係最後。 – 2016-01-14 12:33:54

-2

你可能需要圍繞zlib的和PNG頭與extern "C",如:

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

這是不正確的。如果是這種情況,你會看到「未定義的引用:」crc32(unsigned long,char const *,unsigned int)「',而不是」未定義的引用:「crc32」' – 2010-03-07 06:14:35

+0

+1「的錯誤來糾正我。 – 2010-03-07 10:48:15