直观地:
.dll
(动态链接)/ .lib
(静态链接)。.so
/ .a
二进制文件。我发现了什么:
.dll
s and .a
s .so
并静态链接到.a
。.lib
和另一个问题says it doesn't work。 不幸的是,我无法找到MinGW& MinGW-w64在动态/静态链接库时说明了什么是对的,什么是错的。
根据我的经验,我始终能够动态链接到.dll
。有一次,我能够静态链接到.lib
(使用-static
标志)。
问题:
在使用MinGW-w64 GCC工具链进行编译时,.dll
/ .a
二进制文件是否适合动态和静态地链接库?换句话说,为MSVC生成的动态库和为GCC生成的静态库?
答案 0 :(得分:6)
答案:
MinGW / MinGW-w64的GCC's linker ld
can端口:
.dll
以进行动态链接.dll.a
以进行动态链接(在编译时使用导入库).a
以进行静态链接。 为什么MinGW / MinGW-w64的GCC链接器端口会查找.dll
?
简而言之,最好的答案是因为.dll
是微软对其32位和64位操作系统上共享对象的回答。在Windows上,MinGW / MinGW-w64的端口使用Microsoft C运行时(msvcrt.dll
)[1],因此它遵循Windows操作系统链接器规则。
动态链接库(或DLL)是Microsoft在Microsoft Windows和OS / 2操作系统中实现的共享库概念。 - From Wikipedia
因此,要动态链接库,您将使用文件扩展名:
.so
用于Linux上的共享库,因为这是GCC binutils的链接器搜索的内容,.dll
用于Windows上的共享库,因为这是GCC binutils链接器搜索的MinGW / MinGW-w64端口。 GCC的MinGW端口用于共享库对象的扩展名明确列在源代码的cygming
文件中。正如@ChronoKitsune评论的那样,特别是libgcc/config/i386/t-slibgcc-cygming
中的SHLIB_EXT = .dll
。 cygming
文件(对于Cygwin和MinGW)对于MinGW,MinGW-w64以及Cygwin的32位和64位版本都是通用的。因此,对于Windows的GCC binutils的所有端口都是如此。
为什么MinGW / MinGW-w64链接器会处理.lib
呢?
原则上,GCC binutils的链接器不会将.lib
识别为静态库。但是,链接器可能足够智能,可以链接.dll
进行.lib
导入(在.lib
实际上是导入库的情况下)。例如,在库具有动态链接的依赖项的情况下,库将动态链接(和flags to "force" static linking will be ignored)。
在这种情况下,我认为链接器不会抛出任何错误,看起来似乎.lib
实际上已成功链接。
导入库如何工作? (免费赠品)强>
在Windows上,.lib
可以是两个库中的一个:
.dll
生成的 import 库,其中包含编译期间符号解析所需的所有定义(但是,功能实现被省略)[2]
xxxx.dll
生成导入库,它将生成libxxxx.dll.a
。扩展文件扩展名对于区分导入库和完全定义的静态库非常有用。使用MSVC进行编译时,此distinction isn't apparent in the extension .lib
用于双重目的,因为@ChronoKitsune评论说,MSVC链接器不直接链接.dll
。相反,在编译时需要导入库来解析符号定义,因此在运行时之前不会加载.dll
:
要链接的导入库(.LIB文件)。 (链接器在构建DLL时创建导入库。) - VS 2015 Documentation
为什么MinGW / MinGW-w64的GCC链接器端口会查找.a
?
这很简单 - 端口使用* -nix系统上使用的ar
归档实用程序,如@ChronoKitsune所评论的那样:
静态库的扩展来自binutils附带的
ar
(存档)程序。您可以使用ar -t libxxx.a
列出任何静态库中包含的目标文件。
这类似于MSVC的lib
命令,lib /list foo.lib
如果.obj
是静态库,则此命令将返回.lib
文件列表。