2010-03-07 98 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