与 MinGW 的静态和动态/共享链接

Posted

技术标签:

【中文标题】与 MinGW 的静态和动态/共享链接【英文标题】:Static and Dynamic/Shared Linking with MinGW 【发布时间】:2013-04-06 15:26:45 【问题描述】:

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

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

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

根据this documentation,gcc会搜索libz.a,即

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

我还可以做到以下几点:

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

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

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

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

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

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

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

附:这里有很多问题,但我认为每个问题都取决于前一个问题,没有必要将它们分成几个问题。

【问题讨论】:

我们以cygwin为例:据我了解,用cygwin编译的程序需要一定的dll才能运行。 dll 绑定到某个许可证(免费许可证之一),并且必须存在于程序的主机系统上。如果您作为开发人员忘记将其与程序一起提供,则程序将无法运行。另一个例子是版本冲突的 DLL(即 opengl)。每个系统都有不同的功能,因此某些 DLL 的实现也不同。所以有时候开发者喜欢使用正确的库版本 => 静态链接。 【参考方案1】:

请查看ld and WIN32 (cygwin/mingw)。特别是直接链接到 dll 部分,了解有关 LD 的 Windows 端口上-l 标志行为的更多信息。摘录:

例如,当使用参数 -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 的问题,因此建议使用从 *.dll 导出的符号创建一个静态库 lib*.a 并链接到它。这个 MinGW wiki 页面的链接现在已经失效,所以我认为现在直接链接到 *.dll 应该没问题。此外,我使用最新的 MinGW-w64 发行版自己做了几次,但都没有问题。

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

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

上面的 sn-p 保证 -l 标志的默认链接优先级被 MyLib1 覆盖,即即使 MyLib1.dll 存在于搜索路径中,LD 也会选择 libMyLib1.a 进行链接。请注意,对于MyLib2,LD 将再次更喜欢动态版本。

注意:如果MyLib2 依赖于MyLib1,那么MyLib1 也是动态链接的,而不管-Wl,-Bstatic(即在这种情况下被忽略)。为了防止这种情况,您还必须静态链接MyLib2

【讨论】:

链接已失效...您有对此的参考吗?您可以更新答案。

以上是关于与 MinGW 的静态和动态/共享链接的主要内容,如果未能解决你的问题,请参考以下文章

linux下的动态链接库和静态链接库到底是个什么鬼?动态链接库的编译与使用

Linux下的静态链接库和动态链接库

Qt 共享库(动态链接库)和静态链接库的创建及调用

计算机系统篇之链接:动态链接

关于动态库和静态库的问题。

静态库和共享库