关于VS项目属性: Target Platform Version 和 Platform ToolSet
由问题引入
今天卸载了 VS 2015 ,安装了 VS 2019。使用 VS 2019 打开之前的项目,不做任何项目升级打开后尝试编译,提示没有 Windows SDK 8.1 而无法编译。
进一步探索,了解到安装 VS 2015 时,安装包已经自动带上了 Windows SDK 8.1,之前的项目选择的 Target Platform Version (对应于 Windows SDK Version) 就是选的 8.1
基于我对这个属性还没了解过,依着谨慎原则还是到官网下载安装了 Windows SDK 8.1,安装完毕后可以成功编译运行了,不过,编辑器始终还是错误地报错:
提示无法打开 Windows.h 等头文件
在网上找到了靠谱的解释和解决办法是:(来自 StackOverflow 的回答)
This happens when you have customized include/library paths in legacy projects. If you added your own additional paths in project properties, VisualStudio 2017 can't automatically figure out base paths when switching between platforms/toolsets - normally it automatically puts correct paths there, but if you added customizations, VS won't touch them.
This is legitimate problem which I ran into myself recently when migrating old project targeted for Windows XP into VS2017. None of the answers or comments listed/linked here so far are helpful. I have all legacy SDKs in VisualStudio 2017 installer, and none of that fixed VS not finding essential includes such as
<windows.h>
. In my case the project was using v120 toolset from VS2013, which is superseded by v140_xp in newer VS.After setting correct platform and toolset understood by VS2017, I did the following to resolve the problem:
Open project properties, go to VC++ Directories, for 'Include Directories' and for 'Library Directories', choose
<Inherit from parent or project defaults>
. This will remove your additional paths.Click 'Apply'. This will reset include path to something like
$(VC_IncludePath_x86);$(WindowsSdk_71A_IncludePath_x86)
(will vary for SDKs).Re-add your extra paths here, or better yet - under C/C++/General -> Additional Include Directories and Linker/General -> Additional Library Directories.
这种情况发生在你的项目属性路径设置中有自定义的路径的情况,如果你往项目属性设置中加入了额外的路径, 当切换平台/工具集 设置时 VS2017(或 VS2019)无法自动去刷新分析引用的路径——通常 VS 会正确分析默认的路径,当时如果你加了自定义的路径, VS 就不会这么做了。 ......
在设置好正确的 VS 能识别的平台和工具集后,我做了如下步骤,解决了我的问题:
- 打开项目 Properties ,进入 VC++ Directories ,对于 “Include Directories” 和 “Library Directories” 这两项,选择 <Inherit from parent or project defaults>。这样就把自己自定义加过的路径去除掉。
- 点击 “Apply” 应用,这样对应的引用的路径就变成类似 $(VC_IncludePath);$(WindowsSDK_IncludePath); 的设置(不同的 SDK 其值会有不同)
- 直接在这里重新添加之前自定义的额外的路径,或者更好的做法是,换个地方设置——在 C/C++/General -> Additional Include Directories 和 Linker/General -> Additional Library Directories 下设置路径
就这样,报错问题就解决了。
只不过,我看到很多解决办法是,既然使用新的 VS 版本后报错 SDK 8.1 找不到,就直接把 SDK 换成 SDK 10.0 的, 那么问题是:
切换 Windows SDK 版本后,对编译的程序会产生什么影响吗?
根据经验来看,我们在之前的 Windows 版本如 Win7 编译的程序,是能够直接运行在后续的版本比如 Win10 的,那如果我是在 Win10 上编译的程序,是否能够在 Win7 上正常运行呢?
在我切换了 Target Platform Version(对应于 Windows SDK 的版本)之后,编译出来的程序,是否还能够在 Win7 上正常运行呢?
还有就是,VS 项目属性页中,Target Platform Version 和 Platform ToolSet(平台工具集) 这两个属性又有什么联系呢?
要理清楚这些问题,就不得不搞清楚,这些设置,到底都是用来决定什么的。
一些基本的概念
先看看 官方文档 中的解释:
什么是 Target Platform Version 属性?
Target Platform Version
Specifies the version of the Windows SDK used to build the project. This property appears only if the project type supports it. You can select 10.0 to specify the latest version of the Windows SDK. If your app can take advantage of features in this Windows SDK version, but can still run on earlier versions without those features, perhaps with some loss of functionality, then the value of this property and the Target Platform Min. Version property might be different. If so, your code should check the version of the platform it's running against at runtime and disable features that aren't available in older platform versions.
这个解释里只是提到这个属性指定了 “用于构建项目的 Windows SDK 的版本号”,还说什么如果指定了新的Windows版本的SDK,而程序运行在更早的Windows版本,程序运行时要检测一下当前运行的 Windows 版本,把旧版本 Windows 不支持的一些功能禁用掉。
按字面上理解,就是肯定了这样的实践——如果我指定使用 Windows 10 的 SDK 10,运行在 Windows 7 系统上的话,要注意不去调用 Windows 10 支持而 Windows 7 不支持的接口
也就是说,我指定了 SDK10 的程序,还是可以在 Windows 7 上运行的。(有人确实也已经长期这么干也没出现过什么问题,来源:msdn 论坛讨论)
什么是 Windows SDK 的版本号 ?
Windows SDK Version
For the Windows target platform, this property specifies the version of the Windows SDK that your project requires. When the Visual Studio Installer installs a C++ Workload, it also installs the required parts of the Windows SDK. If you have other Windows SDK versions on your computer, each version installed appears in the dropdown.
To target Windows 7 or Windows Vista, use the value 8.1, since Windows SDK 8.1 is backward compatible to those platforms. When you target an earlier version, define the appropriate value for
_WIN32_WINNT
intargetver.h
. For Windows 7, that's 0x0601. For more information, see ModifyingWINVER
and_WIN32_WINNT
.You can install the Windows XP platform toolset included as an optional component in Visual Studio Installer to build Windows XP and Windows 2003 Server projects. For information on how to obtain and use this platform toolset, see Configuring programs for Windows XP. For more information on changing the platform toolset, see How to: Modify the target framework and platform toolset.
Windows SDK (Software Development Kit)包含了开发 Windows 应用程序需要的头文件和库文件 (dll 和 lib), 比如 windows.h 头文件等
当你安装某个版本的 Visual Studio 时,VS 会自动安装这个 VS 默认对应的 SDK,比如 VS2015 默认会安装 SDK 8.1, VS2019 则会默认安装 SDK 10
新版本的 SDK 一般会有新的 API 或 新的功能特性表现,比如某个版本会有 CreateFile2 接口,而更早的版本可能没有;
从开发者的编码的角度看,选择更新的 Windows SDK 版本号,意味着可能使用到旧版本无法使用的 Windows 接口,这种情况下编译的程序,自然是在旧的系统版本上运行会出错。不过并不是说,选择了新的 SDK 版本(比如 Win10 对应的 SDK 10)开发出的程序就不能在旧的 Windows 版本(比如 Win7)上运行,可能只是失去一些特性。这个说法对应于文档中的解释: “You can select 10.0 to specify the latest version of the Windows SDK. If your app can take advantage of features in this Windows SDK version, but can still run on earlier versions without those features”
什么是 Platform ToolSet 的版本号 ?
Platform Toolset
Specifies the toolset used for building the current configuration. This property allows the project to target a different version of the Visual C++ libraries and compiler. By default, Visual Studio C++ projects target the latest toolset installed by Visual Studio. You can choose one of the toolsets installed by several previous versions of Visual Studio instead. Some older toolsets can create executables that run on Windows XP or Vista. For more information on how to change the platform toolset, see How to: Modify the target framework and platform toolset.
这个属性指定了用来构建程序的编译器和相关C++库的版本号的。默认地,构建的 C++ 项目指向 VS 自行安装的最新的 ToolSet 版本号(比如 VS2015 对应 v140, VS2019 对应 v142)
区别
先使用 StackOverflow 相关的问题 Visual studio platform toolset vs Windows SDK 下的一个说法来总结:
Basically, the toolset is what you build with (compiler, linker, C/C++ libraries), while the SDK is what you build for (target Windows version).
本质上来说,Platform ToolSet(平台工具集)是用来构建程序的,而 Target Platform Version(这里等同于 Windows SDK)是用来面向你要运行的 Windows 版本的
联系
Target Platform Version 和 Platform ToolSet 这两个属性,共同决定了编译出来的程序能够运行的目标的 Windows 版本
实际上,决定最终能够在哪个版本的 Windows 上正常运行的,除了上面两个属性,还有在代码头文件 targetver.h 中
定义的一些宏:_WIN32_WINNT
, WINVER
, 和 TDDI_VERSION
如在官网解释如何配置出能够运行在 Windows XP 上运行的程序的文章所说
Configuring Programs for Windows XP
The toolset supplied in Visual Studio 2019 and later doesn't include support for creating code for Windows XP. Support for Windows XP development is available by using the Visual Studio 2017 v141_xp toolset. You can install the v141_xp toolset as an individual component option in the Visual Studio Installer.
你可以使用 VS2017 编译出来的 v141_xp 工具集,也可以使用 VS2015 编译出俩的 v140_xp 工具集
参考链接
What does the `Target Platform Version` mean for a VS C++ project?
What version of the SDK should I use in VS2017?
Can I target Windows 7 while using SDK 10.0.15063.0?
Which SDK do I need to ensure Windows 7 compatibility in Visual Studio C++ 2017
Visual studio platform toolset vs Windows SDK
toolSet 特性:
Microsoft C/C++ language conformance by Visual Studio version
Is C++11 available in Visual Studio 2017?
SDK 8.1 下载链接: Free: Download the Windows 8.1 SDK
版权声明 本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者 BensonLaur 和本文原始地址: |