Visual Studio 2017 / 2015 命令行编译 找不到 stdlib.h 的问题

上周折腾了下VS不能使用XP系统工具集(如:vc140_xp)编译的问题,原因是不知道为何以前安装的windows SDK 8 不完整,但是单独安装winsdk 8.0的话安装包又崩溃退出,包括用vs2015和vs2017修复都修复不成功。

所以最后是彻底卸载了vs2015、vs2017后依次再重装解决问题。
结果本周在mingw+msvc编译某项目时就报出了错误fatal error C1083: 无法打开包括文件: “stdio.h”: No such file or directory

但是单独使用VS2015或VS2017去编译时又可以编译成功,右键stdio.h打开头文件时定位到了路径"C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\stdio.h",为什么IDE能够找到头文件而命令行不行呢?

接着VS2015 x86 本机工具命令提示符中执行set INCLUDE时发现包含了一系列头文件路径中有C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\ucrt但是没有10.0.10240.0,而10.0.15063.0下没有ucrt目录。

一开始觉得可能是10.0.15063.0的安装有问题,就打开vs2017的安装程序点修改,发现所有10.0.15063.0相关的安装选项都是勾上的。然后将其全部反勾选并且勾选上另一个win10 sdk 10.0.14393.0,然后安装后使用命令行成功编译,看INCLUDE也能看到ucrt目录变成了"C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0"下的了。

然后再修改安装包将所有10.0.15063.0相关的安装选项都勾上,再安装后用命令行发现INCLUDE也能看到ucrt目录变成了"C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0"下的了,然后也能编译成功了,自此命令行的问题解决了。

猜想:命令行查找win10 sdk的方式是找注册表中的最高版本号,并不验证用户是否安装完整的win10 sdk。

衍生问题:
我机器上还有两个不完整的win10 sdk,10.0.10150.0和10.0.10240.0,在vs里的项目属性中,如果选择平台工具集为Visual Studio 2017 - Windows XP (v141_xp),则Windows SDK版本默认变成了7.0,点击下拉后有可选项8.1,目标平台显示空白。
如果选择平台工具集为Visual Studio 2017 (v141),则Windows SDK版本可选项有10.0.14393.0、10.0.15063.0、8.1三个版本。如果选择8.1,则目标平台显示Windows;如果选择10.0.x.0,则目标平台显示Windows 10。

猜想:在IDE里可选的Windows SDK版本取自完整安装的sdk,如果平台工具集是v141_xp,为了支持XP,所以目标平台不做限定,且Windows SDK至多只能使用8.1。如果选择v141,则默认不支持xp,如果同时SDK版本选择了10.x,可能默认只支持win10(仅猜测,未验证)。

还有一个疑问,在我机器上同时存在4个版本的ucrt的情况下,IDE计算出来的包含目录是10.0.10240.0,即不是最小版本号的那个,也不是最大版本号的那个,这个就不清楚原因了,可能要看下MSBUILD的那些Props文件才可以得出答案了。

2017/10/11 补充:
"X:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat"的命令行如下:

Syntax:
    vcvarsall.bat [arch] [platform_type] [winsdk_version] [-vcvars_ver=vc_version]
where :
    [arch]: x86 | amd64 | x86_amd64 | x86_arm | x86_arm64 | amd64_x86 | amd64_arm | amd64_arm64
    [platform_type]: {empty} | store | uwp
    [winsdk_version] : full Windows 10 SDK number (e.g. 10.0.10240.0) or "8.1" to use the Windows 8.1 SDK.
    [vc_version] : "14.0" for VC++ 2015 Compiler Toolset | {empty} for default VS 2017 VC++ compiler toolset

The store parameter sets environment variables to support Universal Windows Platform application
development and is an alias for 'uwp'.

For example:
    vcvarsall.bat x86_amd64
    vcvarsall.bat x86_amd64 10.0.10240.0
    vcvarsall.bat x86_arm uwp 10.0.10240.0
    vcvarsall.bat x86_arm onecore 10.0.10240.0 -vcvars_ver=14.0
    vcvarsall.bat x64 8.1
    vcvarsall.bat x64 store 8.1

看命令行中可以指定windows sdk的版本号。如果未指定,看bat的代码是引用 X:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat时不加-winsdk参数,然后在VsDevCmd.bat里转调X:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\vsdevcmd\core\winsdk.bat来确定windows sdk的版本号,在bat里有这么一段代码:

:GetWin10SdkDirHelper

@REM Get Windows 10 SDK installed folder
for /F "tokens=1,2*" %%i in ('reg query "%1\Microsoft\Microsoft SDKs\Windows\v10.0" /v "InstallationFolder"') DO (
    if "%%i"=="InstallationFolder" (
        SET WindowsSdkDir=%%~k
    )
)

@REM get windows 10 sdk version number
setlocal enableDelayedExpansion
if not "%WindowsSdkDir%"=="" for /f %%i IN ('dir "%WindowsSdkDir%include\" /b /ad-h /on') DO (
    @REM Skip if Windows.h is not found in %%i\um.  This would indicate that only the UCRT MSIs were
    @REM installed for this Windows SDK version.
    if EXIST "%WindowsSdkDir%include\%%i\um\Windows.h" (
        set result=%%i
        if "!result:~0,3!"=="10." (
            set SDK=!result!
            if "!result!"=="%VSCMD_ARG_WINSDK%" set findSDK=1
        )
    )
)

由上面代码中看出,bat里只检测windows 10安装目录里是否有某版本的include目录里有um\windows.h即拿来使用,所以才导致上面提到的引用了一个安装不完整的win10 sdk的问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容