移除对 Windows SDK 版本的依赖

Posted

技术标签:

【中文标题】移除对 Windows SDK 版本的依赖【英文标题】:Removing dependency on Windows SDK version 【发布时间】:2019-04-23 06:33:35 【问题描述】:

我正在尝试编译 MPIR(适用于 Windows 的 GMP 版本)。我安装了 Visual Studio 2017,所以它应该可以工作,但我收到以下错误消息:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.Cpp.WindowsSDK.targets(46,5): error MSB8036: The Windows SDK version 8.1 was not found. Install the required version of Windows SDK or change the SDK version in the project property pages or by right-clicking the solution and selecting "Retarget solution". [C:\mpir\msvc\vs17\lib_mpir_gc\lib_mpir_gc.vcxproj]

我特别需要达到它可以在任何机器上编译的程度,而不仅仅是这台机器,因此在这台机器上安装确切的 SDK 版本并不能解决问题。我需要更改一些内容才能使用 Visual Studio 2017 构建它。

查看C:\mpir\msvc\vs17\lib_mpir_gc\lib_mpir_gc.vcxproj,我找到了这条线:

<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>

这看起来很有希望,但删除它没有任何效果;错误信息保持不变。

我可以改变什么来消除这个错误?

总结一下我认为这应该是可能的原因:

如果您编写一个 C++ 程序,例如在最简单的场景中,在一个名为 foo.cpp 的文件中,并使用命令行编译器 cl foo.cpp 对其进行编译,它将自动编译并链接到当前使用的任何 SDK 版本安装 Visual Studio 以生成 foo.exe,它将(除非您使用某些仅在更高版本的 Windows 中可用的非常专业的 API)在至少从 Vista 开始的任何 Windows 上运行。

这与 msbuild 调用的 cl.exe 完全相同。所以我不是要求新功能。相反,之所以会生成上述错误消息,是因为 出了问题 打破了默认的“它只是工作”场景并将锁定添加到特定的 SDK 版本。我在问如何解除锁定并返回到默认情况下,它只适用于 Visual Studio 附带的任何 SDK 版本。

【问题讨论】:

那么您基本上是在问如何消除平台定位,这是 VS 项目的重要组成部分。 @VTT 消除,是的。必要的,这没有任何意义。不同的 SDK 版本相互兼容。一个编写良好的 C++ 程序,除非它正在做一些极其专业的事情,需要仅在最新版本的 Windows 中提供的功能,否则应该能够使用过去十年左右发布的任何 SDK 进行构建。 不幸的是,事情并非如此。例如,为了使用自 Windows Vista 以来一直存在的GetFileVersionInfoSizeExW 函数,需要链接到 version.dll 或 api-ms-win-core-version-l1-1-0.dll 或 api-ms -win-core-version-l1-1-1.dll,取决于目标 SDK。很多东西被转移或重新设计(DirectX SDK 是最臭名昭著的例子)。 嗯,这是一个不同的问题。通常,人们只针对与受支持的最旧系统相对应的 Windows 版本。如果他们需要在新系统上使用一些新功能而不破坏与旧系统的兼容性,则需要拆分项目,或者需要通过手动加载适当的 dll 来调用新的东西(当它是基于 COM 的东西时,这不是一个大问题) . @rwallace:针对 Windows 7 或 8 SDK。 Windows 10 向后兼容。它仍然有来自 Vista 的version.dll。 Windows 知道使用旧 DLL 的程序是使用旧 SDK 构建的。 【参考方案1】:

正如 cmets 所说,这是不可避免的。

如果您使用 Windows 8.1 SDK 构建,您将获得在 Windows 8.1 或更高版本上运行的版本。如果您使用 Windows 10 SDK 构建,您可以将其功能限制为 Windows 8,或者您可以选择 Windows 10 构建(例如 1607)。当然,如果您选择一个新的 SDK 来使用新的 Windows 10 功能,您将无法在缺少该功能的 Windows 8.1 上运行它。

但如果您选择 Windows SDK,那么您会为哪个 Windows 版本构建?你会使用哪个<windows.h>

[编辑] 至于可移植的 C++ 程序,它们显然不包含 <windows.h>,并且它们不直接链接到 Windows API。相反,它们依赖于微软的 C++ 标准库(又名 MSVCRT)的实现

[编辑2] 我刚刚数了一下,我的 Visual Studio 2017 安装(15.7.5)有 12 个不同的 SDK 选项。诚然,有些是针对 ARM 的,但这只是基本前提的变体:您选择的 SDK 会影响您可以在其上运行生成的应用程序的机器。

【讨论】:

Visual Studio 附带的版本,无论是什么版本。这就是您使用命令行编译器时的工作方式,因此工具链中的某些内容正在竭尽全力打破这一点——为问题文本添加了解释。 @rwallace:VS2017/19 自带的版本已经不存在了。 这是一个可以运行的简单测试:用 C++ 编写一个“hello world”程序,然后cl hello.cpp。有用。而且它不需要您猜测 SDK 版本。它成功找到了一个。 好的,现在用一个稍微复杂一点的程序再试一次,该程序包括<windows.h> 并进行一些 Windows API 调用。 cl hello_win.cpp。仍然有效。 @MSalters 我很清楚这一点,但是您应该能够链接不依赖于运行时的程序。当然,您可能无法使用某些 C++ 功能,例如全局 ctor/dtors、异常、RTTI 等。我说“应该”是因为我从未特别尝试过使用 MSVC,但确实可以使用其他编译器。对于 MSVC,/NODEFAULTLIBs 可以解决问题。在最坏的情况下,还可以通过/TC 使用他们的 C 模式并完全避免使用 C++,这应该证明更容易制作独立的可执行文件。【参考方案2】:

VS2019 支持通过选择适当的项目将项目定位到最新安装的 Windows SDK 版本。这可能会或可能不会产生预期的结果,但肯定会消除手动重新定位项目的需要。

【讨论】:

以上是关于移除对 Windows SDK 版本的依赖的主要内容,如果未能解决你的问题,请参考以下文章

和 jQuery 说再见!Bootstrap 5 将移除对其依赖

jQuery再见!Bootstrap 5将移除对其依赖;阿里巴巴将建浙江云计算数据中心;Delphi 10.3.1发布

1.7 移除对参数的赋值动作

重构改善既有代码设计--重构手法07:Remove Assignments to Parameters (移除对参数的赋值)

第2章 重新组织函数:引入解释性变量分解临时变量和移除对参数的赋值

极客日报:阿里CEO张勇辞任微博董事;谷歌副总裁怒批苹果iMessage封闭;​Fedora 36将移除对ifcfg的支持