8

在尝试使用 Windows Universal C Run-Time (...\Windows Kits\10\Include\10.0.15063.0\ucrt) 在 Windows 上评估 Clang 时,我立即以未公开和意外依赖的形式面临意外的墙在微软的 Visual Studio 上。显然,一旦您包含任何标准 C 头文件,即使是最简单的 C 程序也无法立即编译,因为它们似乎最终都试图 #include vcruntime.h(这不是 UCRT 的一部分)。

我的问题是:

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

1 回答 1

6

查看[MSDN.Blogs]:介绍通用 CRT(以及它引用的其他URL )。重点是我的:

去年 6 月,我们发表了两篇文章,讨论了我们对Visual Studio 2015的Visual C++ C 运行时 (CRT)所做的重大更改。... AppCRT和DesktopCRT已重新组合成一个库,我们将其命名为Universal CRT。新的 DLL 被命名为 ucrtbase.dll(发布)和 ucrtbased.dll(调试);它们不包括版本号,因为我们将就地为它们提供服务。

来自[MS.DevBlogs]:伟大的 C 运行时 (CRT) 重构

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

  1. VCRuntime (vcruntime140.dll) ...

  2. AppCRT (appcrt140.dll) ...

  3. 桌面CRT ( desktopcrt140.dll ) ...

根据[MS.Support]:Update for Universal C Runtime in Windows

Microsoft Visual Studio 2015 在使用Windows 10 软件开发工具包 (SDK)构建应用程序时创建对通用 CRT 的依赖项。

并来自[MS.Dev]:Windows 10 SDK

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

因此,U CRT严格绑定到VStudioUniversal:表示它不依赖于VStudio版本(所有VStudio版本都将使用一个通用的(只能有一个))。

个人观点:UCRTNixlibc的Win(想要)等价物

我查看了SDK包含目录例如 “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生成的,并且很有可能会失败。例子:

代码00.c

//#include <stdio.h>


int main() {
    //printf("Dummy.... sizeof(void*): %d\n", sizeof(void*));
    return 0;
}

输出

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q045340527]> sopr.bat
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***

[prompt]> dir /b
code00.c

[prompt]> "c:\Install\x86\Microsoft\Visual Studio Community\2015\VC\bin\cl.exe" -nologo -c -Focode00.obj code00.c
code00.c

[prompt]> "c:\Install\Google\Android_SDK\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang.exe" -c -o code00.o code00.c

[prompt]> dir /b
code00.c
code00.o
code00.obj

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

[prompt]> "C:\Install\x86\Microsoft\Visual Studio Community\2015\VC\bin\amd64\dumpbin.exe" -nologo code00.obj

Dump of file code00.obj

File Type: COFF OBJECT

  Summary

          80 .debug$S
          2F .drectve
           7 .text$mn

[prompt]> "C:\Install\x86\Microsoft\Visual Studio Community\2015\VC\bin\amd64\dumpbin.exe" -nologo code00.o

Dump of file code00.o
code00.o : warning LNK4048: Invalid format file; ignored

  Summary



[prompt]> "c:\Install\x64\Cygwin\Cygwin\AllVers\bin\readelf.exe" -d code00.o

[prompt]> "c:\Install\x64\Cygwin\Cygwin\AllVers\bin\readelf.exe" -d code00.obj
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

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

结论

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

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

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

于 2018-06-13T13:06:31.883 回答