如何使用 mingw-w64 针对 UCRT 进行构建?

1 mingw-w64 universal-crt

我希望能够使用 mingw-w64 来构建链接到 Visual Studio 2015+ 可用的通用 CRT 的二进制文件,而不是 MSVCRT.lib。mingw-w64 v6.0.0发行说明包括以下内容:“感谢 Martin Storsjö,大量添加支持 UCRT”

不幸的是,我的搜索没有显示有关如何使用此支持的文档。

有谁知道我需要提供哪些选项以及在哪里提供它们?

Aym*_*lah 5

好吧,我已经和VS 2017一起做了。但据我了解VS 2015VS 2017 都使用VCRUNTIME140.DLL,所以这里不用担心。

它分为两个步骤:

1. 创建一个导入库VCRUNTIME140.DLL

这是通过执行以下操作来完成的:

mkdir scratch; cd scratch
cp C:/Windows/System32/vcruntime140.dll .
dumpbin /exports vcruntime140.dll > exports.txt
echo LIBRARY VCRUNTIME140 > vcruntime140.def
echo EXPORTS >> vcruntime140.def
tail +20 exports.txt | head -n -10 | awk '{print $4}' >> vcruntime140.def
lib /def:vcruntime140.def /out:libvcruntime140.a /machine:x86
cp libvcruntime140.a $(MINGW_ROOT)/i686-w64-mingw32/lib
Run Code Online (Sandbox Code Playgroud)

2. 改变MinGW GCC 的运作方式来链接VCRUNTIME140UCRT代替MSVCRT

gcc -dumpspecs > $(MINGW_ROOT)/lib/gcc/i686-w64-mingw32/$(GCC_VERSION)/specs
Run Code Online (Sandbox Code Playgroud)
  1. 添加-D_UCRT到规范文件的cppcc1plus部分。这将防止未定义的引用链接scanf函数族的错误。检查我的另一个问题
  2. 在规范文件的部分替换-lmsvcrt为。-lvcruntime140 -lucrtlibgcc

$(MINGW_ROOT)与您拥有MinGW的位置交换。

笔记:

  • i686-w64-mingw32我包含的路径中的平台签名部分可能因您的情况而异。我相信基于架构。所以你可能需要相应地修改它。
  • 你需要使用一个相对较新的MinGWlibucrt.a$(MINGW_ROOT)/ i686的-W64-mingw32的/ lib目录文件夹中。我正在使用MinGW 7.0.0GCC 7.4.0

  • 关于此的两个注意事项: 1)您不需要使用 vcruntime140.dll,因此可以跳过整个步骤 1。只需删除`-lvcruntime140`,`-lucrt`就足够了。vcruntime140.dll 不作为 UCRT 本身的一部分提供,但可以与应用程序捆绑在一起(或者可能会也可能不会安装在系统目录中的某个位置)2) 编译 C 代码并且不链接任何预构建的静态库时(在默认的 libmingw32.a 和 libmingwex.a)这可以工作,但其他预构建的库可能依赖于 CRT 版本之间显着差异的细节。 (3认同)
  • 特别是 - libstdc++ 可能在很大程度上取决于它所构建的 CRT - 因此您不能使用为 msvcrt.dll 构建的预构建 libstdc++ 并将其链接到 UCRT。(或者它可能看起来有效并产生棘手的潜在错误。)因此,如果您不使用包括 libstdc++ 在内的预构建库并从划痕。最安全的方法是使用传递给 mingw-w64-headers 和 mingw-w64-crt 的“--with-default-msvcrt=ucrt”从头开始重建整个工具链。 (2认同)