如何规避Windows Universal CRT标头对vcruntime.h的依赖性

在尝试使用Windows通用C运行时(… \ Windows Kits \ 10 \ Include \ 10.0.15063.0 \ ucrt)评估Windows上的Clang时,我立即面临意外的墙,forms是未公开的意外依赖在微软的Visual Studio上。 显然,即使是最简单的C程序也只有在包含任何标准C头时才能编译,因为它们似乎最终都试图#include vcruntime.h(它不是UCRT的一部分)。

我的问题是:

  1. 有没有办法在没有Visual Studio的情况下使用Windows Universal C RTL SDK?
  2. 如果它不是有意或不可能的,为什么它不被称为“Windows CRT for Microsoft VC” – 我错过了什么?

查看[MSDN]:介绍Universal CRT (以及它引用的其他URL ):

去年6月,我们发表了一篇文章,讨论了我们对Visual Studio 2015Visual C ++ C运行时(CRT)所做的主要更改。

AppCRTDesktopCRT已重新组合成一个单独的库,我们将其命名为Universal CRT 。 新的DLL名为ucrtbase.dll(release)和ucrtbased.dll(debug); 它们不包含版本号,因为我们将在适当的位置为它们提供服务。

从[MSDN]:Great C运行时(CRT)重构 (清除( 粗体粗体项目):

为了统一这些不同的CRT,我们将CRT分为三部分:

  1. VCRuntime (vcruntime140.dll)…

  2. AppCRT (appcrt140.dll)…

  3. DesktopCRT (desktopcrt140.dll)…

根据[MS.Support]:Windows中的Universal C Runtime更新 :

当使用Windows 10软件开发工具包(SDK)构建应用程序时,Microsoft Visual Studio 2015会在Universal CRT上创建依赖关系。

从[MS.Dev]:Windows 10 SDK :

注意 :针对Windows 10,版本1803(或更高版本)的Windows 10开发需要Visual Studio 2017 。 以前版本的Visual Studio不会发现此SDK。

因此, U CRT严格限制在VStudio上通用 :意味着它不依赖于VStudio版本(所有VStudio版本都将使用普通版本( 只能有一个 ))。

UCRTUxlibcWin想要

我看了一下SDK include dir(例如“c:\ Program Files(x86)\ Windows Kits \ 10 \ Include \ 10.0.15063.0 \ ucrt” ):

  • 每个公共文件(例如stdio.h )都有一个#include
  • corecrt.h有一个#include

没有#ifdef s,所以没有办法(至少不容易)克服这一点。

但是,当达到链接阶段时,事情会更加清晰。 如果您的C代码包含UCRT标头,它(很可能)将链接到SDK lib目录中的文件(例如“c:\ Program Files(x86)\ Windows Kits \ 10 \ Lib \ 10.0.15063.0 \ ucrt \ x64” ),这是由VStudio生成的,并且很有可能失败。 例:

code.c

 //#include  int main() { //printf("Dummy.... sizeof(void*): %d\n", sizeof(void*)); return 0; } 
 e:\Work\Dev\StackOverflow\q045340527>dir /b code.c e:\Work\Dev\StackOverflow\q045340527>"c:\Install\x86\Microsoft\Visual Studio Community\2015\VC\bin\cl.exe" -nologo -c -Focode.obj code.c code.c e:\Work\Dev\StackOverflow\q045340527>"c:\Install\Google\Android_SDK\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang.exe" -c -o code.o code.c e:\Work\Dev\StackOverflow\q045340527>dir /b code.c code.o code.obj 

2个(生成的)文件不兼容

 e:\Work\Dev\StackOverflow\q045340527>"C:\Install\x86\Microsoft\Visual Studio Community\2015\VC\bin\amd64\dumpbin.exe" -nologo code.obj Dump of file code.obj File Type: COFF OBJECT Summary 80 .debug$S 2F .drectve 7 .text$mn e:\Work\Dev\StackOverflow\q045340527>"C:\Install\x86\Microsoft\Visual Studio Community\2015\VC\bin\amd64\dumpbin.exe" -nologo code.o Dump of file code.o code.o : warning LNK4048: Invalid format file; ignored Summary e:\Work\Dev\StackOverflow\q045340527>"c:\Install\x64\Cygwin\Cygwin\AllVers\bin\readelf.exe" -d code.o e:\Work\Dev\StackOverflow\q045340527>"c:\Install\x64\Cygwin\Cygwin\AllVers\bin\readelf.exe" -d code.obj readelf: Error: Not an ELF file - it has the wrong magic bytes at the start 

现在,我知道lld (我记得我过去建了它,但我找不到它,为了测试我的声明)能够链接ELFCOFF文件格式,但我怀疑它可以组合他们。

结论

基于以上所述,以下是您的问题的答案:

  1. 我想它是 – 一个不受支持的人(声称某些事情是不可能的几乎总是假的 )。 但是,会有很多限制(考虑上面的文件格式匹配),并且很可能需要一些肮脏的技巧或变通方法(如我现在想到的一些):

    • 改变它(编辑它的头文件 – 删除不需要的#include s)
    • 创建一个虚拟的vcruntime.h文件(通过编译阶段)
  2. 在名称中添加VStudio (或其他任何事实)将自动降低其“ 普遍性级别
    这只是第一步:它已经与VC Runtime分开了。 把它想象成一个婴儿。 及时,它将变得成熟和(更稳定),也许其他编译器/构建工具链将最终支持它(不需要遵循斯巴达规则,并把它扔出悬崖:) …至少现在不是这样) 。
    但是,我认为只有MS才能得到答案(尽管他们很有可能不会提供更清晰的答案)

我住在一个名叫Global的电视网络的国家。 在Globals存在的前15年,如果你住在多伦多的一个城市,你只能看它。 然而,它是全球性的。 微软对Universal有类似的定义。

在真正的编程世界中,有一个更好的通用定义,它被称为UNIX。 甚至微软也被迫(假装)了解UNIX; Linux肯定了解UNIX。 你不必忍受糟糕的开发工具; Linux和UNIX随处可用。