35

我想从一个简单的链接用法开始来解释我的问题。假设有一个库z可以编译为共享库 libz.dll(D:/libs/z/shared/libz.dll) 或静态库 libz.a (D:/libs/z/static/libz.dll)。一种)。

让我想链接它,然后我这样做:

gcc -o main.exe main.o -LD:/libs/z/static -lz

根据此文档,gcc 将搜索 libz.a,即

成员为目标文件的归档文件

我还可以执行以下操作:

gcc -o main.exe main.o -LD:/libs/z/shared -lz

上面的文档中没有提到该-l标志将搜索lib<name>.so.

如果我的 libz.a 和 libz.dll 在同一个目录中会发生什么?库将如何与程序链接?为什么我需要标志-Wl,-Bstatic以及-Wl,-Bdynamic是否-l同时搜索共享库和静态库?

如果我编译共享库发行版,为什么有些开发人员会为相同的模块提供带有 .dll 文件的 .a 文件?

例如,Qt 在 bin 目录中提供 .dll 文件,在 lib 目录中提供 .a 文件。它是同一个库,但分别像共享和静态一样构建吗?或者 .a 文件是某种提供与共享库链接的虚拟库,哪里有真正的库实现?

另一个例子是 Windows 上的 OpenGL 库。为什么每个编译器都必须在 MingW 中提供像 libopengl32.a 这样的静态 OpenGL 库?

带有 .dll.a 和 .la 扩展名的文件有什么用途?

PS这里的题很多,但是我觉得每题都依赖上一个题,没必要拆成几个题。

4

1 回答 1

33

请看一下ld 和 WIN32 (cygwin/mingw)。特别是,直接链接到 dll-l部分以获取有关LD 的 Windows 端口上标志行为的更多信息。提炼:

例如,当使用参数 -lxxx 调用 ld 时,它将尝试在其搜索路径的第一个目录中查找,

libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll

在移动到搜索路径中的下一个目录之前。

(*) 实际上,这不是cygxxx.dll但实际上是<prefix>xxx.dll<prefix>由 ld 选项设置的位置-dll-search-prefix=<prefix>。在 cygwin 的情况下,标准 gcc 规范文件-dll-search-prefix=cyg包括cygxxx.dll.

注意:如果您曾经使用 MinGW 构建过 Boost,您可能还记得 Boost 库的命名完全遵循上面链接中描述的模式。

过去在 MinGW 中存在直接链接到 的问题*.dll,因此建议创建一个静态库lib*.a,其中包含导出的符号*.dll并链接到它。这个 MinGW wiki 页面的链接现在已经死了,所以我认为*.dll现在直接链接应该没问题。此外,我用最新的 MinGW-w64 发行版自己做了几次,还没有遇到任何问题。

您需要链接标志-Wl,-Bstatic-Wl,-Bdynamic因为有时您想强制静态链接,例如,当搜索路径中也存在同名的动态库时:

gcc object1.o object2.o -lMyLib2 -Wl,-Bstatic -lMyLib1 -Wl,-Bdynamic -o output

上面的代码片段保证-lflag 的默认链接优先级被覆盖MyLib1,即即使MyLib1.dll存在于搜索路径中,LD 也会选择libMyLib1.a链接。请注意,对于MyLib2LD 将再次更喜欢动态版本。

注意:如果MyLib2取决于MyLib1,则MyLib1也被动态链接,不管-Wl,-Bstatic(即在这种情况下它被忽略)。为了防止这种情况,您也必须MyLib2静态链接。

于 2013-04-06T16:27:12.843 回答