如何规避 Windows 通用 CRT 头文件对 vcruntime.h 的依赖 [英] How to circumvent Windows Universal CRT headers dependency on vcruntime.h

查看:19
本文介绍了如何规避 Windows 通用 CRT 头文件对 vcruntime.h 的依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试使用 Windows 通用 C 运行时 (...Windows Kits10Include10.0.15063.0ucrt) 在 Windows 上评估 Clang 时,我立即以未公开的形式面临着意想不到的墙以及对 Microsoft 的 Visual Studio 的意外依赖.显然,一旦您包含任何标准 C 头文件,即使是最简单的 C 程序也无法立即编译,因为它们似乎最终都会尝试 #include vcruntime.h(这不是 UCRT 的一部分).

我的问题是:

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

解决方案

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

<块引用>

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

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

<块引用>

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

  1. VCRuntime (vcruntime140.dll) ...

  2. AppCRT (appcrt140.dll) ...

  3. DesktopCRT (desktopcrt140.dll) ...

根据 [MS.Support]:Windows 中通用 C 运行时的更新:

<块引用>

Microsoft Visual Studio 2015 在使用 Windows 10 软件开发工具包 (SDK).

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

<块引用>

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

因此,UCRT 严格绑定到 VStudio.通用:表示不依赖于VStudio版本(所有VStudio版本都会使用一个通用的(只能有一个)).

个人意见:UCRTNixlibcWin (wannabe) 等价物.

我查看了 SDK 包括 dir (eg "c:Program文件 (x86)Windows Kits10Include10.0.15063.0ucrt"):

  • 每个通用文件(例如 stdio.h)都有一个 #include <corecrt.h>
  • corecrt.h 有一个 #include <vcruntime.h>

没有#ifdefs,所以没有办法(至少没有简单的办法)克服这个问题.

但是,当到达 link 阶段时,事情会更加清晰.如果您的 C 代码包含 UCRT 标头,它将(很可能)链接到来自 SDK lib dir 的文件(eg c:Program Files (x86)Windows Kits10Lib10.0.15063.0ucrtx64"),由 生成>VStudio,而且很有可能会失败.示例:

code00.c:

//#include <stdio.h>int main() {//printf("Dummy.... sizeof(void*): %d
", sizeof(void*));返回0;}

输出:

<块引用>

[cfati@CFATI-5510-0:e:WorkDevStackOverflowq045340527]>sopr.bat*** 粘贴到 StackOverflow(或其他)页面时,设置更短的提示以更好地适应 ***[提示]>目录/b代码00.c[提示]>c:Installx86MicrosoftVisual Studio Community2015VCincl.exe"-nologo -c -Focode00.obj code00.c代码00.c[提示]>c:InstallGoogleAndroid_SDK
dk-bundle	oolchainsllvmprebuiltwindows-x86_64inclang.exe"-c -o 代码00.o 代码00.c[提示]>目录/b代码00.c代码00.ocode00.obj

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

<块引用>

[prompt]>C:Installx86MicrosoftVisual Studio Community2015VCinamd64dumpbin.exe"-nologo code00.obj文件code00.obj的转储文件类型:COFF 对象概括80 .调试$S2F .drectve7 .text$mn[提示]>C:Installx86MicrosoftVisual Studio Community2015VCinamd64dumpbin.exe"-nologo 代码00.o文件code00.o的转储code00.o:警告 LNK4048:无效的格式文件;忽略概括[提示]>c:Installx64CygwinCygwinAllVersin
eadelf.exe"-d 代码00.o[提示]>c:Installx64CygwinCygwinAllVersin
eadelf.exe"-d 代码00.objreadelf:错误:不是 ELF 文件 - 它在开始时有错误的魔术字节

现在,我知道 lld (我记得我过去构建它,但我找不到它,以便测试我的陈述)能够链接两者 ELFCOFF 文件格式,但我怀疑它是否可以将它们结合起来.

结论

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

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

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

In trying to evaluate Clang on Windows, utilizing the Windows Universal C Run-Time (...Windows Kits10Include10.0.15063.0ucrt) I was immediately facing unexpected wall, in the form of an undisclosed and unexpected dependency on Microsoft's Visual Studio. Apparently even the simplest C program will not be able to compile as soon as you include any standard C header, because they all seem to end-up attempting to #include vcruntime.h (which is not part of the UCRT).

My questions are:

  1. Is there a way to utilize the Windows Universal C RTL SDK withOUT Visual Studio?
  2. If it is not intended or possible, why then is it not called "Windows CRT for Microsoft VC" - what am I missing?

解决方案

Check out [MSDN.Blogs]: Introducing the Universal CRT (and also the other URLs that it references). Emphases are mine:

In June of last year we published a pair of articles discussing the major changes that we had made to the Visual C++ C Runtime (CRT) for Visual Studio 2015.
...
The AppCRT and DesktopCRT have been recombined into a single library, which we have named the Universal CRT. The new DLLs are named ucrtbase.dll (release) and ucrtbased.dll (debug); they do not include a version number because we’ll be servicing them in-place.

From [MS.DevBlogs]: The Great C Runtime (CRT) Refactoring

In order to unify these different CRTs, we have split the CRT into three pieces:

  1. VCRuntime (vcruntime140.dll) ...

  2. AppCRT (appcrt140.dll) ...

  3. DesktopCRT (desktopcrt140.dll) ...

According to [MS.Support]: Update for Universal C Runtime in Windows:

Microsoft Visual Studio 2015 creates a dependency on the Universal CRT when applications are built by using the Windows 10 Software Development Kit (SDK).

and from [MS.Dev]: Windows 10 SDK:

Note: Windows 10 development targeting Windows 10, version 1803 (or later) requires Visual Studio 2017. This SDK will not be discovered by previous versions of Visual Studio.

So, UCRT is strictly bound to VStudio. Universal: means that it's not dependent on VStudio version (all VStudio versions will use a common one (there can be only one)).

Personal opinion: UCRT is the Win (wannabe) equivalent of Nix's libc.

I took a look in SDK include dir (e.g. "c:Program Files (x86)Windows Kits10Include10.0.15063.0ucrt"):

  • Every common file (e.g. stdio.h) has an #include <corecrt.h>
  • corecrt.h has an #include <vcruntime.h>

no #ifdefs, so there is no way (at least no easy one) to overcome this.

But, things are even clearer when reaching link phase. If your C code includes UCRT headers, it will (most likely) link to files from SDK lib dir (e.g. "c:Program Files (x86)Windows Kits10Lib10.0.15063.0ucrtx64"), which are generated by VStudio, and there's a great chance for that to fail. Example:

code00.c:

//#include <stdio.h>


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

Output:

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

[prompt]> dir /b
code00.c

[prompt]> "c:Installx86MicrosoftVisual Studio Community2015VCincl.exe" -nologo -c -Focode00.obj code00.c
code00.c

[prompt]> "c:InstallGoogleAndroid_SDK
dk-bundle	oolchainsllvmprebuiltwindows-x86_64inclang.exe" -c -o code00.o code00.c

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

The 2 (generated) files are incompatible:

[prompt]> "C:Installx86MicrosoftVisual Studio Community2015VCinamd64dumpbin.exe" -nologo code00.obj

Dump of file code00.obj

File Type: COFF OBJECT

  Summary

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

[prompt]> "C:Installx86MicrosoftVisual Studio Community2015VCinamd64dumpbin.exe" -nologo code00.o

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

  Summary



[prompt]> "c:Installx64CygwinCygwinAllVersin
eadelf.exe" -d code00.o

[prompt]> "c:Installx64CygwinCygwinAllVersin
eadelf.exe" -d code00.obj
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

Now, I know that lld (I remember that I built it in the past, but I can't find it, in order to test my statement) is able to link both ELF and COFF file formats, but I doubt that it can combine them.

Conclusion

Based on the above, here are the answers to your questions:

  1. I suppose it is - an unsupported one though (claiming that something is impossible is almost always false). But, there would be lots of restrictions (consider the above file format matching), and would most likely require some dirty tricks or (lame) workarounds (gainarii) like (some that I can think of now):

    • Altering it (editing its header files - to remove the unwanted #includes)
    • Creating a dummy vcruntime.h file (to get past the compile phase)
  2. Adding VStudio (or anything else, as a matter of fact) in the name would automatically decrease its "universality level".
    And this is only the 1st step: it has been separated from VC Runtime. Think of it as of a baby. In time, it will become mature (and more stable,) and maybe other compilers / build toolchains will end up supporting it as well (no need to follow the spartan rules, and throw it off the cliff :) ... at least not right now).
    But, I think only MS could have an answer to this (although there's a great chance that they won't provide a clearer one)

这篇关于如何规避 Windows 通用 CRT 头文件对 vcruntime.h 的依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆