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

时间:2013-04-06 15:26:46

标签: c++ gcc mingw static-linking dynamic-linking

我想从一个简单的链接用法开始解释我的问题。让我们假设有一个库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位于同一目录下,会发生什么?图书馆如何与计划挂钩?如果-Wl,-Bstatic同时搜索共享库和静态库,为什么我需要标记-Wl,-Bdynamic-l

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

例如,Qt在bin目录中提供.dll文件,其中包含lib目录中的.a文件。它是相同的库,但分别构建为共享和静态?或.a文件是某种虚拟库,提供与共享库的链接,其中有真正的库实现?

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

什么是.dll.a和.la扩展名用于?

的文件

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

1 个答案:

答案 0 :(得分:28)

请看一下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的问题,因此建议创建一个静态库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

以上代码段保证-l的{​​{1}}标记的默认链接优先级被覆盖,即即使搜索路径中存在MyLib1,LD也会选择MyLib1.dll链接反对。请注意,对于libMyLib1.a,LD将再次使用动态版本。

注意:如果MyLib2取决于MyLib2,则MyLib1也会动态关联,无论MyLib1如何(即这个案例)。为了防止这种情况,您还必须静态链接-Wl,-Bstatic