我在 Windows 平台上使用具有 C++11 功能的 Visual C++ 2013 编译器构建一个跨平台库,使用 CMake(NMake 生成器)作为构建系统。我正在使用 Windows 7。
我的库使用了一些仅在 Windows 8/7 中可用的函数/枚举值/结构成员。
我希望能够为 Windows XP、Windows Vista、Windows 7 和 Windows 8/8.1 操作系统版本以及 x86、x64 和 arm 架构构建库,即不是只针对 Windows XP 并在任何地方工作的单一构建,但是许多针对特定操作系统的不同构建,因为较新的操作系统版本具有我的库可以提供的更多有用功能。
我的问题是:
如何告诉编译器以特定操作系统版本(即 XP、Vista、7、8、8.1 等)为目标?
如何告诉编译器以特定架构(即 x86、x64、arm 等)为目标?
如果我使用仅在 Windows 8/7 中可用的函数/枚举值/结构成员,但构建我的库是针对 Windows XP 的,会发生什么情况?编译器会警告我这些东西在 Windows XP 上不存在吗?还是会在 Windows XP 系统上编译但无法运行?
当我针对 Windows XP 进行编译时,我该如何使我的代码跳过 Windows XP 中不存在的内容(Windows 7/8 函数等)?
针对不同的操作系统版本时,我使用哪个 Windows SDK 版本有关系吗?我似乎已经安装了 8.1、8.0 和 7.1 Windows SDK。即使针对 Windows XP,我也始终使用最新的 SDK 版本可以吗?
以下是我找到的一些答案,但我不确定它们是否正确或完整:
我只需要将
_WIN32_WINNT
和WINVER
定义设置为 appropriate values for the target system就是这样,除此之外我不需要设置任何东西,我的应用程序将仅在指定的系统(即 Windows XP)上运行。- 在使用“C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat”设置编译器环境变量时,我需要使用适当的选项,即“C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat amd64"适用于 64 位。
我还需要指定 appropriate
/SUBSYSTEM
value到链接器,即/SUBSYSTEM:WINDOWS,5.02
或/SUBSYSTEM:WINDOWS,6.00
for x64。但是5.02
和6.00
有什么区别呢?为什么两个值指定相同的东西(64 位)?5.01
和6.00
也是一样,为什么都指定32位?我认为 64/32 位具有单个值就足够了。- 这些值(
5.01
、5.02
和6.00
)看起来类似于来自WINVER
的平台值(1 ).除了架构之外,他们是否还设置了目标操作系统?但是 (1) 中的WINVER=502
用于针对 Windows Server 2003,根据维基百科,它同时发布了 64 位和 32 位版本,但在这里 5.02 严格代表 64 位, 这没有意义...
- 这些值(
编译器将无法编译,因为 (1) 中的
WINVER
定义将排除目标操作系统中不存在的函数和内容(Windows 头文件使用#ifdef
东西)。我应该在我自己的代码中
#ifdef
基于WINVER
的东西,就像 Windows header 所做的那样,并在需要时为缺失的功能提供替代方案。不知道。
请注意,我没有使用 Visual Studio IDE,所以告诉我在 IDE 中设置选项 X 有点毫无意义。
我来自 Linux 开发,所以 Windows 的东西对我来说有点新鲜。
最佳答案
您对自己问题的大部分回答都是正确的。一些澄清和更正:
子系统版本与目标架构正交。 /subsystem
文档所说的是 x86 的最低子系统版本是 5.01,x64 的最低子系统版本是 5.02。对于控制台和 Windows 应用程序,子系统版本与内部操作系统版本号相同。 5.01 是 x86 Windows XP; 5.02 是 x64 Windows XP。 Windows XP 有两个不同的版本号,因为 x64 Windows XP 的发布时间晚于 x86 Windows XP。较新的操作系统对所有体系结构具有相同的版本号(例如,Windows Vista 是 x86 和 x64 的 6.0 版)。
请注意,通过设置子系统版本,您可以限制运行程序的操作系统集。例如,如果您将子系统版本设置为 6.2,您的程序将只能在 Windows 8 及更高版本上运行。如果您尝试在例如Windows 7,它不会运行。 (对于 DLL 也是如此:如果您的 DLL 的目标操作系统比您正在运行的操作系统更新,加载程序将不会加载 DLL,至少不会加载代码执行。)
参见维基百科页面 "List of Microsoft Windows versions"获取操作系统版本列表。 Windows XP 是 Visual Studio 2013 支持的最旧的 Windows 版本。
Windows 8 SDK 仅支持低至 Windows Vista 的软件开发。如果要将 _WIN32_WINNT
或 WINVER
设置为针对 Windows XP 构建,则需要使用 Windows 7 SDK(Visual Studio 2013 将安装这两个 SDK)。
除非您的程序对于每个目标操作系统都有很大不同,否则构建一个在您想要支持的最旧操作系统 (Windows XP) 上运行的二进制文件并延迟加载或动态加载(通过LoadLibrary
/GetProcAddress
)您希望在较新操作系统中使用的任何功能(当该功能可用时)。
关于c++ - 使用 Visual C++ 编译器在 Windows 上构建库时如何正确设置目标操作系统版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30960872/