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

Yuk*_*uki 28 c++ gcc mingw dynamic-linking static-linking

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

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

gcc -o main.exe main.o -LD:/libs/z/static -lz
Run Code Online (Sandbox Code Playgroud)

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

归档文件,其成员是目标文件

我也可以做以下事情:

gcc -o main.exe main.o -LD:/libs/z/shared -lz
Run Code Online (Sandbox Code Playgroud)

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

如果我libz.a和libz.dll将在同一目录中会发生什么?图书馆如何与计划挂钩?为什么我需要标志-Wl,-Bstatic,-Wl,-Bdynamic如果-l搜索共享和静态库?

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

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

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

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

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

Ale*_*aev 28

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

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

libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll
Run Code Online (Sandbox Code Playgroud)

然后转到搜索路径中的下一个目录.

(*)实际上,这不是,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
Run Code Online (Sandbox Code Playgroud)

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

注意:如果MyLib2取决于MyLib1,则MyLib1无论是否动态链接-Wl,-Bstatic(即在这种情况下被忽略).为了防止这种情况,您还必须MyLib2静态链接.