我想从一个简单的链接用法开始解释我的问题。让我们假设有一个库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。这里有很多问题,但我认为每个问题都取决于前一个问题,没有必要将它们分成几个问题。
答案 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
。