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

Ron*_*kas 7 c windows sdk clang-cl universal-crt

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

我的问题是:

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

Cri*_*ati 5

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

去年6月,我们发表了一篇文章,讨论了我们对Visual Studio 2015Visual C++ C运行时(CRT)所做的主要更改.... 的AppCRTDesktopCRT已经被重新组合成一个单一的库,我们有一个名为通用CRT.新的DLL命名为ucrtbase.dll(release)和ucrtbased.dll(debug); 它们不包含版本号,因为我们将在适当的位置为它们提供服务.

[MSDN.Blogs]:Great C Runtime(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>
  • corecrt.h有一个#include <vcruntime.h>

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

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

code.c:

//#include <stdio.h>


int main() {
    //printf("Dummy.... sizeof(void*): %d\n", sizeof(void*));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

结论

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

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

    • 改变它(编辑它的头文件 - 删除不需要的#includes)
    • 创建一个虚拟的vcruntime.h文件(通过编译阶段)
  2. 在名称中添加VStudio(或其他任何事实)将自动降低其" 普遍性级别 ".
    而这仅仅是1 步:它已经从分离VC运行库.把它想象成一个婴儿.随着时间的推移,它将变得成熟和(更稳定),也许其他编译器/构建工具链将最终支持它(不需要遵循斯巴达规则,并将其抛弃悬崖:) ...至少现在不是这样) .
    但是,我认为只有MS才能得到答案(尽管他们很有可能无法提供更清晰的答案)