C:与MinGW-w64静态/动态链接的正确方法

Vla*_*tin 4 windows gcc dynamic-linking mingw-w64

直观地:

  • MinGW-w64是GNU编译器工具(GCC等)的Windows端口。
  • Windows的预编译二进制文件是.dll(动态链接)/ .lib(静态链接)。
  • 但是,MinGW-w64使用GNU编译器工具,因此需要.so/ .abinary。

我发现了什么:

不幸的是,我在MinGW和MinGW-w64上找不到明确的文档来说明在动态/静态链接库时正确与错误的地方。

根据我的经验,我一直能够动态链接到.dll。一次,我能够静态链接到.lib(使用-static标志)。

题:

.dll/ .a与MinGW的-W64 GCC工具链编译的二进制文件时拨出动,静链接库?换句话说,为MSVC生成的动态库和为GCC生成的静态库?

Vla*_*tin 6

答案:

MinGW / MinGW-w64的GCC链接器ld端口可以

  • 直接链接到.dlls以进行动态链接
  • 间接链接到.dll.as以进行动态链接(在编译时使用导入库)
  • 链接到.a进行静态链接。

为什么要查找MinGW / MinGW-w64的GCC链接器端口.dll

简而言之,最好的答案是,因为这.dll是Microsoft在其32位和64位操作系统上共享对象的答案。在Windows上,MinGW / MinGW-w64的端口使用Microsoft C运行时(msvcrt.dll[1],因此它遵循Windows OS链接程序规则。

动态链接库(或DLL)是Microsoft在Microsoft Windows和OS / 2操作系统中对共享库概念的实现。- 来自维基百科

因此,要动态链接库,您将使用文件扩展名:

  1. .so 对于Linux上的共享库,因为这是GCC binutils的链接程序搜索的内容,
  2. .dllWindows上的共享库,因为这就是GCC binutils链接程序搜索的MinGW / MinGW-w64端口。

GCC的MinGW端口用于共享库对象的扩展名cygming在源代码的文件中明确列出。正如@ChronoKitsune所评论的,特别是:SHLIB_EXT = .dlllibgcc/config/i386/t-slibgcc-cygming。这些cygming文件(用于Cygwin和MinGW)对于MinGW,MinGW-w64以及Cygwin的32位和64位版本都是通用的。因此,对于Windows的GCC binutils的所有端口都是如此。

为什么要用MinGW / MinGW-w64链接器处理.lib

原则上,GCC binutils的链接器不会将a识别.lib为静态库。但是,它是可能的连接是足够聪明到对链接.dll,一个.lib进口(的情况下,该.lib实际上是一个导入库)。例如,在库具有动态链接的依赖项的情况下,该库将动态链接(并且将忽略“强制”静态链接的标志)。

在这种情况下,我想链接器将不会抛出任何错误,并且看起来好像.lib实际上已成功链接。

导入库如何工作?(赠品)

在Windows上,a .lib可以是两个库之一:

  1. 一个进口由编译器从生成的文库.dll与编译过程中用于符号解析所有需要的定义(然而,函数的实现被排除)[2]
    1. 如果您尝试xxxx.dll使用MinGW / MinGW-w64的GCC binutils端口生成导入库,它将生成一个libxxxx.dll.a。扩展文件扩展名对于区分导入库和完全定义的静态库很有用。使用MSVC进行编译时,这种区别在扩展中并不明显
  2. 完全定义的静态库

.libs具有双重作用,因为正如@ChronoKitsune所述,MSVC链接器不会直接链接到.dlls。而是需要一个导入库来在编译时解析符号定义,以便在.dll运行时不加载:

要链接的导入库(.LIB文件)。(构建DLL时,链接器会创建导入库。)- VS 2015文档

为什么要寻找MinGW / MinGW-w64的GCC链接器端口.a

这很简单-端口使用ar* -nix系统上使用的归档实用程序,如@ChronoKitsune所评论:

静态库的扩展来自arbinutils 随附的(归档)程序。您可以ar -t libxxx.a用来列出任何静态库中包含的目标文件。

这类似于libMSVC 的命令,如果是静态库,则lib /list foo.lib此命令将返回.obj内部文件列表.lib