2017-04-09 125 views
2

直观:C:正确的方式来静态/动态链接使用MinGW-W64

  • 的MinGW-W64是GNU编译器工具(GCC等)的Windows端口。
  • 对Windows预编译的二进制文件是.dll(动态链接)/ .lib(静态链接)。
  • 然而,MinGW的-W64使用GNU编译工具,它会按照所需.so/.a二进制文件。

我找到了什么:

不幸的是,我无法找到的MinGW &的MinGW-W64,说什么是对,什么是错了,当动态/静态链接库明确的文档。

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

问:

是否合适.dll/.a二进制动态和静态链接库与MinGW的-W64 GCC工具链编译时?换句话说,为MSC生成的动态库和为GCC生成的静态库?

+0

这是令人惊讶的是它的工作,给予[这个邮件列表的问题(https://sourceforge.net/p/mingw-w64/wiki2/Answer%2064%20bit%20MSVC-generated%20x64%20.lib/) 。此外,对于MinGW目标上的GCC,您有.a的存档库(如Linux)和.dll的动态库(如Windows)。 –

+0

[/ dll文件的来源以及链接器如何使用它们(使用浏览器的查找文本功能查找_direct linking_)](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/ Using_ld_the_GNU_Linker/win32.html) –

+0

尽管命名,MinGW-w64默认编译为32位。 (您可以在安装程序中手动选择它的64位版本。)根据我的经验,MinGW-w64或多或少像MinGW一样工作。 – HolyBlackCat

回答

2

的答案:

GCC's linker ld can

的MinGW/MinGW的-W64的端口:

  • 直接链接到.dll S代表的动态链接
  • 间接链接到.dll.a S表示动态链接(使用导入在编译库)
  • 链接.a S表示静态链接。

为什么GCC的链接查找.dll的MinGW的/ MinGW的-W64的端口?

总之,最好的答案是因为这是.dll是微软对32位和64位操作系统上的共享对象的回答。在Windows上,MinGW/MinGW-w64的端口使用Microsoft C运行时(msvcrt.dll[1],因此它遵从Windows操作系统链接器规则。

动态链接库(或DLL)是Microsoft在Microsoft Windows和OS/2操作系统中共享库概念的实现。 - From Wikipedia

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

  1. .so对Linux共享库,因为这是海湾合作委员会的binutils'连接器搜索,
  2. .dll用于Windows上的共享库,因为这是GCC binutils链接程序的MinGW/MinGW-w64端口搜索的内容。

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

为什么MinGW/MinGW-w64连接器会处理.lib呢?

原则上,GCC binutils的链接程序不会将.lib识别为静态库。但是,链接器可能足够聪明,可以链接到.dll,即.lib导入(在.lib实际上是导入库的情况下)。例如,如果库具有动态链接的依赖关系,则库将动态链接(和flags to "force" static linking will be ignored)。

在这种情况下,我会想象链接器不会抛出任何错误,它会显示好像.lib实际上链接成功。

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

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

  1. 编译期间通过与符号解析所有需要定义一个.dll编译器生成的进口库(然而,功能实现都离开了)[2]
    1. 如果试图生成与海湾合作委员会的binutils MinGW的/ MinGW的-W64的端口xxxx.dll导入库,它会产生一个libxxxx.dll.a。扩展文件扩展名对于区分从完全定义的静态库到库的区别导入库是有用的。当MSVC编译,这distinction isn't apparent in the extension
  2. 一个完全自定义的静态库

.lib发球双重目的,因为作为@ChronoKitsune评论,MSVC的链接器并不直接针对.dll s的链路。相反,导入库需要在编译解决符号定义,从而使.dll不加载,直到运行时:

导入库(.lib文件)与链接。 (链接器创建时,DLL是建立在导入库。) - VS 2015 Documentation

为什么GCC的链接查找.a的MinGW的/ MinGW的-W64的端口?

这很简单 - 端口使用是在* -nix系统中使用的ar归档工具,因为@ChronoKitsune评论:

扩展对于静态库,来自ar(存档)程序包含在binutils中。您可以使用ar -t libxxx.a列出任何静态库中包含的对象文件。

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