使用Visual C ++编译器在Windows上构建库时,如何正确设置目标OS版本 [英] How to properly set target OS version when building a library on Windows using Visual C++ compiler

查看:93
本文介绍了使用Visual C ++编译器在Windows上构建库时,如何正确设置目标OS版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Windows C平台上具有C ++ 11功能的Visual C ++ 2013编译器构建跨平台库,特别是使用CMake(NMake生成器)构建系统。我使用的是Windows 7。



我的库使用的某些函数/枚举值/结构成员仅在Windows 8/7中可用。



我希望能够构建适用于Windows XP,Windows Vista,Windows 7和Windows 8 / 8.1 OS版本以及x86,x64和arm体系结构的库,即不能只针对Windows XP的单个构建并且可以在任何地方使用,但是针对特定OS的版本却很多,因为较新的OS版本具有我的库可以提供的更多有用功能。



我的问题是:


  1. 如何告诉编译器以特定的OS版本(例如XP,Vista,7、8、8.1等)为目标? / p>


  2. 我如何告诉编译器针对特定的体系结构(例如x86,x64,arm等)?


  3. 如果我使用仅在Windows 8/7中可用的函数/枚举值/结构成员,但构建针对Windows XP的库,会发生什么情况?编译器会警告我Windows XP不存在这种情况吗?还是会真正编译但无法在Windows XP系统上运行?


  4. 我该怎么做,以便在为Windows XP编译时跳过我的代码是Windows XP所不具备的功能(Windows 7/8等功能)?


  5. 在针对不同的操作系统定位时使用哪个Windows SDK版本是否重要版本?我似乎已经安装了8.1、8.0和7.1 Windows SDK。即使在定位Windows XP时也始终使用最新的SDK版本可以吗?


以下是我找到的一些答案,我不确定它是否正确或完整:


  1. 我只需要设置 _WIN32_WINNT WINVER 定义为目标系统的适当值,仅此而已,我不需要进行任何设置,我的应用程序将在



    • 在设置编译器环境变量时,需要使用 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位)。

    • 我还需要指定 / SUBSYSTEM 与链接器相匹配,即 /SUBSYSTEM:WINDOWS,5.02 /SUBSYSTEM:WINDOWS,6.00 对于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,根据Wikipedia,它以64位和32位版本发布,但此处为5.02严格代表64位,这没有意义...



  2. 编译器将无法编译,因为(1)中的 WINVER 定义将排除目标操作系统中不存在的功能和内容(Windows头文件使用定义为 #ifdef 东西。)


  3. 我应该 #ifdef 在我自己的代码中基于 WINVER 的东西,就像Windows标头一样,并在需要时提供缺少功能的替代方法。


  4. 不知道。


请注意,我没有使用Visual Studio IDE,因此告诉我在IDE中设置选项X有点没意义。



我来自Linux开发,所以Windows对我来说有点新。

解决方案

您的转向您自己的问题在大多数情况下是正确的。一些澄清和更正:



子系统版本与目标体系结构正交。 / subsystem 文档说的是x86的 minimum 子系统版本为5.01,而 minimum 子系统版本为x86。 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,至少不会执行代码。)



有关列表,请参见Wikipedia页面 Microsoft Windows版本列表 操作系统版本。 Windows XP是Visual Studio 2013支持的Windows的最旧版本。



Windows 8 SDK仅支持开发Windows Vista以下版本的软件。如果要为Windows XP设置 _WIN32_WINNT WINVER 进行构建,则需要使用Windows 7 SDK (Visual Studio 2013将同时安装两个SDK)。



除非每个目标操作系统的程序都存在很大差异,否则构建一个可在以下操作系统上运行的二进制文件可能会更简单。您要支持的最旧的操作系统(Windows XP),并且可以延迟加载或动态加载(通过 LoadLibrary / GetProcAddress )可用时要在较新的操作系统上使用的任何功能。


I'm building a cross-platform library using Visual C++ 2013 compiler with C++11 features on Windows platform specifically, using CMake (NMake generator) for build system. I'm using Windows 7.

My library uses some of functions/enum values/structure members available only in Windows 8/7.

I want to be able to build the library for Windows XP, Windows Vista, Windows 7 and Windows 8/8.1 OS versions and x86, x64 and arm architectures, i.e. not a single build that just targets Windows XP and works everywhere, but many different builds targeting specific OS'es, since newer OS versions have more of useful features my library could provide.

My questions are:

  1. How do I tell the compiler to target a specific OS version (i.e. XP, Vista, 7, 8, 8.1, etc)?

  2. How do I tell the compiler to target a specific architecture (i.e. x86, x64, arm, etc)?

  3. What happens if I use functions/enum values/structure members available only in Windows 8/7 but build my library targeting Windows XP? Would compiler warn me that such things don't exist on Windows XP? Or would it actually compile but fail to run on the Windows XP system?

  4. How do I make it so the when I compile for Windows XP, my code skips over things that are not present in Windows XP (Windows 7/8 functions and such)?

  5. Does it matter which Windows SDK version I use when targeting different OS versions? I seem to have installed 8.1, 8.0 and 7.1 Windows SDKs. Is it fine if I always use the latest SDK version even when targeting Windows XP?

Here are some answers I found, which I'm not sure are correct or complete:

  1. I just need to set _WIN32_WINNT and WINVER defines to appropriate values for the target system and that's it, I don't need to set anything in addition to that, my application will run on the specified system (i.e. Windows XP) with just that.

    • I need to use appropriate option when setting up compiler enviroment variables with "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat", i.e. "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat amd64" for 64 bit.
    • I also need to specify appropriate /SUBSYSTEM value to the linker, i.e. /SUBSYSTEM:WINDOWS,5.02 or /SUBSYSTEM:WINDOWS,6.00 for x64. But what is the difference between 5.02 and 6.00? Why two values specify the same thing (64-bitness)? Same for 5.01 and 6.00, why they both specify 32-bitness? I would emagine having a single value for 64/32 bit would be enough.

      • Those values (5.01, 5.02 and 6.00) look similar to platform values from WINVER from (1). Do they also set target OS, besides the architecture? But WINVER=502 from (1) is used to target Windows Server 2003, which was released in both 64-bit and 32-bit versions according to wikipedia, but in here 5.02 stands strictly for 64-bit, which doesn't make sense...
  2. Compiler would fail to compile because the WINVER define from (1) would exclude functions and stuff not present in targeting OS (Windows header files use that define to #ifdef things).

  3. I should #ifdef things based on WINVER in my own code, like Windows headers do, and provide alternatives for the missing functionality when required.

  4. Don't know.

Note that I'm not using Visual Studio IDE, so telling me to set option X in the IDE is a bit meaningless.

I'm coming from Linux development, so Windows things are a bit new to me.

解决方案

Your answers to your own questions are for the most part correct. Some clarifications and corrections:

The subsystem version is orthogonal to the target architecture. What the /subsystem documentation is saying is that the minimum subsystem version for x86 is 5.01 and the minimum subsystem version for x64 is 5.02. For console and Windows apps, the subsystem version is the same as the internal operating system version number. 5.01 is x86 Windows XP; 5.02 is x64 Windows XP. There are two different version numbers for Windows XP because the x64 Windows XP was released later than the x86 Windows XP. Newer OSes have the same version number for all architectures (e.g., Windows Vista is version 6.0 for both x86 and x64).

Note that by setting the subsystem version, you can restrict the set of operating systems on which your program will run. E.g., if you set the subsystem version to 6.2, your program will only run on Windows 8 and above. If you try to run the program on e.g. Windows 7, it will not run. (The same is true for DLLs: If you have a DLL that targets an OS newer than the OS on which you are running, the loader will not load the DLL, at least not for code execution.)

See Wikipedia's page "List of Microsoft Windows versions" for a list of operating system versions. Windows XP is the oldest version of Windows supported by Visual Studio 2013.

The Windows 8 SDK only supports development of software down to Windows Vista. If you want to set _WIN32_WINNT or WINVER to build for Windows XP, you'll need to use the Windows 7 SDK (Visual Studio 2013 will install both SDKs).

Unless your program is substantially different for each target operating system, it would probably be much simpler to build one binary that runs on the oldest operating system you want to support (Windows XP) and either delay-load or dynamically load (via LoadLibrary/GetProcAddress) any functionality that you want to use from newer operating systems, when that functionality is available.

这篇关于使用Visual C ++编译器在Windows上构建库时,如何正确设置目标OS版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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