与 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 的静态和动态/共享链接的主要内容,如果未能解决你的问题,请参考以下文章