gcc/ld 如何找到 zlib.so?

pat*_*cek 4 linker gcc zlib shared-libraries ld

我已经使用 zlib 很多年了,从来没有想过它的命名有点不合常规。虽然 Linux 上的大多数库都遵循lib<name>.sofor shared objects 和lib<name>.afor archives的命名约定,但 zlib 被命名为zlib.so/ zlib.a。我的问题是:zlib.so当我-lz用作链接标志时,gcc/ld 如何知道要查找?

我知道对于链接,gcc 会调用 ld,它会在某些默认路径和用 指定的任何路径中搜索库-L,并根据需要附加lib.so.a.部分。奇怪的是,gcc 的链接选项手册页只提到链接器可以找到档案;没有提到.so扩展名。ld手册页至少提到了这两个扩展,但仍然只提到通过lib在指定的库名前面添加来进行搜索。ld 怎么知道在for zliblib 之后添加z?我从未见过这种情况发生在另一个图书馆。

twa*_*erg 5

gcc有几种不同的链接库的方法,共享的或静态的。如果您指定-lz,gcc将查找libz.so(可能在libz和之间有一些版本位.so,但重要的部分是文件名将以 开头libz和结尾.so),或者 for libz.a(同样,可能带有版本信息),如果您正在编译静态,或者作为后备,如果共享库不存在。如果您指定-lzlib它将查找libzlib.so(这不是标准名称 - 包通常命名为zlib,但库本身是libz)。另一种链接方式是不使用该-l<lib>选项,只需指定/path/to/zlib.so-L /path/to zlib.so(或zlib.a如果你想)。在这种情况下,库不必具有lib前缀,但您必须明确提供任何版本信息,除非为符号链接或类似的东西提供了文字 name zlib.so

应用程序还可以在运行时通过dlopen()它的其他关联函数加载共享库,在这种情况下,库也可以命名为您想要的任何名称(当然,这不适用于静态库)。

因此,如果您正在查看的库实际上被称为zlib.so,那么它不会被 找到gcc ... -lz,除非它恰好是到的符号链接libz.so(反之亦然,在这种情况下gcc实际上只是使用libz.so,恰好具有相同的内容为您的zlib.so)。但是gcc,如果构建过程在链接阶段显式命名库(不使用-l<lib>),或者如果您的应用程序通过加载它dlopen()(但在这种情况下,它并没有真正链接到您的程序 - 它只是在运行时加载),则可能会使用它。