我已经使用了zlib多年,并且从未想过它被命名为略微非常规的事实。虽然Linux上的大多数库遵循lib<name>.so
的共享对象和lib<name>.a
的归档命名约定,但zlib的名称为zlib.so
/ zlib.a
。我的问题是:当我使用zlib.so
作为链接标记时,gcc / ld如何知道查找-lz
?
我理解,对于链接,gcc会调用ld,它会搜索某些默认路径中的库以及-L
指定的任何路径,并附加lib
和.so
或{{必要时1}}部分。奇怪的是,gcc's manual page for linking options只提到链接器可以找到档案;没有提到.a.
扩展名。 man page for ld至少提到了这两个扩展名,但仍然只是通过将.so
添加到指定的库名称来提及搜索。如果ld知道在 lib
之后为zlib添加lib
?我从未见过这种情况发生在另一个图书馆。
答案 0 :(得分:4)
gcc
有几种不同的方法可以链接库,共享或静态。如果您指定-lz
,则gcc
将查找libz.so
(可能在libz
和.so
之间有一些版本位,但重要的部分是文件名将以libz
开头,以.so
结束),或libz.a
(再次,可能包含版本信息),如果您正在静态编译,或作为共享库的后备不存在。如果您指定-lzlib
,它将查找libzlib.so
(这不是标准名称 - 包通常命名为zlib
,但库本身为libz
)。另一种链接方式是不使用-l<lib>
选项,只需指定/path/to/zlib.so
或-L /path/to zlib.so
(或zlib.a
(如果需要)。在这种情况下,库不必具有lib
前缀,但您必须明确提供任何版本信息,除非为符号链接或类似提供文字名称{{1 }}
应用程序也可以在运行时通过zlib.so
和其他相关函数加载共享库,在这种情况下,库也可以按照你想要的名称命名(这当然不适用于静态库,当然)。
因此,如果您正在查看的库实际上名为dlopen()
,则zlib.so
找不到它,除非它恰好是gcc ... -lz
的符号链接(反之亦然,在这种情况下,libz.so
实际上只是使用gcc
,它恰好与您的libz.so
具有相同的内容。但是,zlib.so
可能正在使用它,如果构建过程在链接阶段明确命名库(不使用gcc
),或者您的应用程序通过-l<lib>
加载它(但在这种情况下,它是没有真正链接到你的程序 - 它只是在运行时加载。)