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

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

问题描述

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

我的问题是:

  1. 是否可以在没有Visual Studio的情况下使用Windows Universal C RTL SDK?
  2. 如果不希望这样做或为什么不能使用它,为什么不将其称为"Microsoft VC的Windows CRT"?我想念的是什么?

解决方案

查看 [MS .DevBlogs]:出色的C运行时(CRT)重构

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

  1. VCRuntime (vcruntime140.dll)...

  2. AppCRT (appcrt140.dll)...

  3. DesktopCRT (desktopcrt140.dll)...

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

使用 [MS.Dev]:Windows 10 SDK :

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

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

个人意见: UCRT Win (想要),等同于 Nix libc .

我查看了 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,所以没有办法(至少没有简单的办法)来克服这个问题.

但是,当进入 link 阶段时,情况就更加清楚了.如果您的 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;
}
 

输出:

 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 (我记得我曾经构建过它,但是为了测试我的陈述我找不到它)可以链接两个 ELF COFF 文件格式,但我怀疑它能否将它们结合起来.

结论

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

  1. 我想是的-尽管这是不受支持的(声称不可能做到的事几乎总是总是错误的).但是,会有很多限制(请考虑上述文件格式匹配),并且很可能需要一些肮脏的技巧或变通方法( gainarii ),例如(我现在可以想到的一些方法):

    • 更改(编辑其头文件-删除不需要的#include)
    • 创建虚拟 vcruntime.h 文件(通过编译阶段)
  2. 在名称中添加 VStudio (或其他事实)会自动降低其"大学水平" .
    这只是第一步,它已与 VC Runtime 分开.认为它就像一个婴儿.随着时间的流逝,它会变得成熟和(更稳定),也许其他编译器/构建工具链最终会支持它(无需遵循斯巴达规则,将其扔下悬崖:) ...至少现在不是). .
    但是,我认为只有 MS 可以对此做出回答(尽管很有可能他们赢得了(请提供更清晰的信息)

In trying to evaluate Clang on Windows, utilizing the Windows Universal C Run-Time (...\Windows Kits\10\Include\10.0.15063.0\ucrt) 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 Kits\10\Include\10.0.15063.0\ucrt"):

  • 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 Kits\10\Lib\10.0.15063.0\ucrt\x64"), which are generated by VStudio, and there's a great chance for that to fail. Example:

code.c:

//#include <stdio.h>


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

Output:

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

The 2 (generated) files are incompatible:

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

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 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 (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 Universal CRT标头对vcruntime.h的依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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