C:使用 MinGW-w64 静态/动态 Link 的正确方法
C: Correct Way to Statically / Dynamically Link with MinGW-w64
直观上:
- MinGW-w64 是 GNU 编译器工具(GCC 等)的 Windows 端口。
- Windows 的预编译二进制文件是
.dll
(动态 linking)/.lib
(静态 linking)。
- 但是,MinGW-w64 使用 GNU 编译器工具,因此需要
.so
/ .a
个二进制文件。
我发现了什么:
- 根据Red Hat Enterprise Linux documentation, seems that MinGW/MinGW-w64/Cygwin linkers look for
.dll
s and .a
s
- 根据 this tutorial,你应该动态 link 到
.so
和静态 link 到 .a
。
- 关于 SO 的一个问题表明你可以 statically link a
.lib
and another on SO says it doesn't work。
不幸的是,我无法从 MinGW 和 MinGW-w64 中找到明确的文档来说明 dynamically/statically linking 库时什么是对的,什么是错的。
根据我的经验,我总是能够动态地 link 到 .dll
s。曾经,我能够静态地 link 到 .lib
(使用 -static
标志)。
问题:
使用 MinGW-w64 GCC 工具链编译时,.dll
/ .a
二进制文件是否适合动态和静态 link 库?也就是说,为MSVC生成动态库,为GCC生成静态库?
答案:
MinGW / MinGW-w64 的 GCC's linker ld
can 端口:
- 直接link到
.dll
s动态linking
- 间接 link 到
.dll.a
s 动态 linking(在编译时使用导入库)
- link 到
.a
s 静态 linking.
为什么 MinGW / MinGW-w64 的 GCC link 端口要查找 .dll
?
简而言之,最佳答案是因为 .dll
是 Microsoft 对其 32 位和 64 位操作系统上的共享对象的回答。在Windows上,MinGW / MinGW-w64的port使用Microsoft C运行time(msvcrt.dll
)[1],所以服从WindowsOSlinker 规则。
Dynamic-link library (or DLL) is Microsoft's implementation of the shared library concept in the Microsoft Windows and OS/2 operating systems. -- From Wikipedia
因此,对于动态 link 库,您将使用文件扩展名:
.so
用于 Linux 上的共享库,因为这是 GCC binutils 的 linker 搜索的内容,
- 或
.dll
用于 Windows 上的共享库,因为这是 GCC binutils 的 MinGW / MinGW-w64 端口 linker 搜索的内容。
GCC 的 MinGW 端口用于共享库对象的扩展在源代码的 cygming
文件中明确列出。正如@ChronoKitsune 评论的那样,具体来说:libgcc/config/i386/t-slibgcc-cygming
中的 SHLIB_EXT = .dll
。 cygming
文件(用于 Cygwin 和 MinGW)对于 MinGW、MinGW-w64 以及 32 位和 64 位版本的 Cygwin 都是通用的。因此,对于 Windows.
的 GCC binutils 的所有端口都是如此
为什么 MinGW / MinGW-w64 linker 处理 .lib
那么?
原则上,GCC binutils 的 linker 不会将 .lib
识别为静态库。但是,linker 可能足够聪明,可以 link 对抗 .lib
导入的 .dll
(如果 .lib
实际上是导入库)。例如,如果库具有动态 linked 的依赖项,则该库将被动态 linked(和 flags to "force" static linking will be ignored)。
在这种情况下,我想 linker 不会抛出任何错误,而且看起来 .lib
实际上 linked 成功了。
导入库如何工作? (赠品)
在 Windows 上,.lib
可以是以下两个库之一:
- 编译器从
.dll
生成的 import 库,其中包含编译期间符号解析所需的所有定义(但是,函数实现被忽略)[2]
- 如果您尝试使用 MinGW/MinGW-w64 的 GCC binutils 端口为
xxxx.dll
生成导入库,它将生成 libxxxx.dll.a
。扩展文件扩展名对于区分 import 库和完全定义的 static 库很有用。使用 MSVC 编译时,此 distinction isn't apparent in the extension
- 一个完全定义的静态库
.lib
s 有双重用途,因为正如@ChronoKitsune 评论的那样,MSVC linker 不直接 link 反对 .dll
s。相反,需要一个导入库来在编译时解析符号定义,这样 .dll
直到 运行-time:
才会加载
An import library (.LIB files) to link with. (The linker creates the import library when the DLL is built.) -- VS 2015 Documentation
为什么 MinGW/MinGW-w64 的 GCC linker 端口寻找 .a
?
这很简单——端口利用了在 *-nix 系统上使用的 ar
归档实用程序,正如@ChronoKitsune 评论的那样:
The extension for static libraries comes from the ar
(archive) program included with binutils. You can use ar -t libxxx.a
to list the object files contained within any static library.
这类似于 MSVC 的 lib
命令,lib /list foo.lib
此命令将 return 如果 .lib
是 .obj
文件列表一个静态库。
直观上:
- MinGW-w64 是 GNU 编译器工具(GCC 等)的 Windows 端口。
- Windows 的预编译二进制文件是
.dll
(动态 linking)/.lib
(静态 linking)。 - 但是,MinGW-w64 使用 GNU 编译器工具,因此需要
.so
/.a
个二进制文件。
我发现了什么:
- 根据Red Hat Enterprise Linux documentation, seems that MinGW/MinGW-w64/Cygwin linkers look for
.dll
s and.a
s - 根据 this tutorial,你应该动态 link 到
.so
和静态 link 到.a
。 - 关于 SO 的一个问题表明你可以 statically link a
.lib
and another on SO says it doesn't work。
不幸的是,我无法从 MinGW 和 MinGW-w64 中找到明确的文档来说明 dynamically/statically linking 库时什么是对的,什么是错的。
根据我的经验,我总是能够动态地 link 到 .dll
s。曾经,我能够静态地 link 到 .lib
(使用 -static
标志)。
问题:
使用 MinGW-w64 GCC 工具链编译时,.dll
/ .a
二进制文件是否适合动态和静态 link 库?也就是说,为MSVC生成动态库,为GCC生成静态库?
答案:
MinGW / MinGW-w64 的 GCC's linker ld
can 端口:
- 直接link到
.dll
s动态linking - 间接 link 到
.dll.a
s 动态 linking(在编译时使用导入库) - link 到
.a
s 静态 linking.
为什么 MinGW / MinGW-w64 的 GCC link 端口要查找 .dll
?
简而言之,最佳答案是因为 .dll
是 Microsoft 对其 32 位和 64 位操作系统上的共享对象的回答。在Windows上,MinGW / MinGW-w64的port使用Microsoft C运行time(msvcrt.dll
)[1],所以服从WindowsOSlinker 规则。
Dynamic-link library (or DLL) is Microsoft's implementation of the shared library concept in the Microsoft Windows and OS/2 operating systems. -- From Wikipedia
因此,对于动态 link 库,您将使用文件扩展名:
.so
用于 Linux 上的共享库,因为这是 GCC binutils 的 linker 搜索的内容,- 或
.dll
用于 Windows 上的共享库,因为这是 GCC binutils 的 MinGW / MinGW-w64 端口 linker 搜索的内容。
GCC 的 MinGW 端口用于共享库对象的扩展在源代码的 cygming
文件中明确列出。正如@ChronoKitsune 评论的那样,具体来说:libgcc/config/i386/t-slibgcc-cygming
中的 SHLIB_EXT = .dll
。 cygming
文件(用于 Cygwin 和 MinGW)对于 MinGW、MinGW-w64 以及 32 位和 64 位版本的 Cygwin 都是通用的。因此,对于 Windows.
为什么 MinGW / MinGW-w64 linker 处理 .lib
那么?
原则上,GCC binutils 的 linker 不会将 .lib
识别为静态库。但是,linker 可能足够聪明,可以 link 对抗 .lib
导入的 .dll
(如果 .lib
实际上是导入库)。例如,如果库具有动态 linked 的依赖项,则该库将被动态 linked(和 flags to "force" static linking will be ignored)。
在这种情况下,我想 linker 不会抛出任何错误,而且看起来 .lib
实际上 linked 成功了。
导入库如何工作? (赠品)
在 Windows 上,.lib
可以是以下两个库之一:
- 编译器从
.dll
生成的 import 库,其中包含编译期间符号解析所需的所有定义(但是,函数实现被忽略)[2]- 如果您尝试使用 MinGW/MinGW-w64 的 GCC binutils 端口为
xxxx.dll
生成导入库,它将生成libxxxx.dll.a
。扩展文件扩展名对于区分 import 库和完全定义的 static 库很有用。使用 MSVC 编译时,此 distinction isn't apparent in the extension
- 如果您尝试使用 MinGW/MinGW-w64 的 GCC binutils 端口为
- 一个完全定义的静态库
.lib
s 有双重用途,因为正如@ChronoKitsune 评论的那样,MSVC linker 不直接 link 反对 .dll
s。相反,需要一个导入库来在编译时解析符号定义,这样 .dll
直到 运行-time:
An import library (.LIB files) to link with. (The linker creates the import library when the DLL is built.) -- VS 2015 Documentation
为什么 MinGW/MinGW-w64 的 GCC linker 端口寻找 .a
?
这很简单——端口利用了在 *-nix 系统上使用的 ar
归档实用程序,正如@ChronoKitsune 评论的那样:
The extension for static libraries comes from the
ar
(archive) program included with binutils. You can usear -t libxxx.a
to list the object files contained within any static library.
这类似于 MSVC 的 lib
命令,lib /list foo.lib
此命令将 return 如果 .lib
是 .obj
文件列表一个静态库。