Sorry, this will be quite a long time: - (
1. How can I tell the compiler about setting up a specific version of the OS (for example, XP, Vista, 7, 8, 8.1, etc.)?
You usually don’t tell the compiler to target a specific version of the OS. Instead, you customize the header files from the SDK using WINVER and _WIN32_WINNT . sdkddkver.h header file provides useful named constants
If you set WINVER and _WIn32_WINNT high enough, the header files will declare functions available only in later versions of the OS (assuming you use the SDK, new enough to declare these functions).
But now you have a program that calls functions that might not be available in older versions of the OS. If you're lucky there is some kind of compatibility to help you. If you're out of luck, trying to call an unknown function simply won't succeed. Or do something much worse than fail. But this opinion, for my part, I cannot find anything concrete to quote.
2. How can I tell the compiler to target a specific architecture (ie x86, x64, arm, etc.)?
No. A different compiler is used for each target platform. If you look in C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\ , you will find the bin directory and seven subdirectories:
amd64
amd64_arm
amd64_x86
arm
x86_amd64
x86_arm
You use compilers from the appropriate directory to create code for this platform. On a Win32 version of Windows, remove '(x86)' from the path above.
3. What happens if I use functions / enumerated values / structure elements, available only in Windows 8/7 ...
I am not sure if this behavior is defined. If you set _WIn32_WINNT to _WIN32_WINNT_WIN8, you pretty much say, "I intend to run this on Windows 8 and above." But that my opinion is not certain. I may not have read the documentation carefully enough.
4. How can I do this when I compile for Windows XP, my code skips everything that is missing in Windows XP (Windows 7/8 functions, etc.)?
You need to explicitly specify the code, I do not believe that you need something to solve this problem. You can do this at compile time with #ifdef and _WIN32_WINNT, or you can do this at runtime by determining whether you can call the function and then call the function or not call the function as necessary.
In the (unlikely) worst of all possible worlds, such mutable changes will occur that (for example) the Windows 8 structural parameter format is incompatible with an earlier implementation of the function. In this case, you need to find out which version of the structure to use when calling the function - and the header will give you only one structure definition based on the value of _WIN32_WINNT.
5. Does it matter which version of the Windows SDK I use when targeting different OS versions?
Maybe. Older versions of the SDK may not contain function definitions for later versions of the OS. For example, when the Vista SDK was created, most of the features introduced in Windows 8 probably did not exist.
Is it normal if I always use the latest SDK even when setting up on Windows XP?
This is probably the safest thing. If you use the latest SDK and set _WIN32_WINNT to _WIN32_WINNT_WINXP, then probably the right thing will happen if you want to start XP.
I say “maybe” because XP is something special. It is not supported. The latest SDK may or may not be tested with _WIN32_WINNT set to XP.
1. I just need to set _WIN32_WINNT and WINVER defines ...
This will give you a code file that will execute correctly on the OS version specified by _WIN32_WINNT. This, most likely, will also work on later versions of the OS (Microsoft tries to pretty much not break existing programs when they invoke a newer version of the OS). It may or may not work correctly in OS versions earlier than the one identified by _Win32_WINNT - I would not risk it.
• I need to use the appropriate option when setting compiler environment variables
Since you are using NMAKE, I am not sure about the answer to this question. The vcvarsall.bat file sets various environment variables that (among other things) can control which set of compilers are used (by controlling where MSBUILD searches for binary files, such as compilers). But I do not know if NMAKE starts MSBUILD or pays attention to these environment variables or has its own set of variables or what.
• I also need to specify the appropriate / SUBSYSTEM value for the linker, that is, /SUBSYSTEM:WINDOWS,5.02 or / SUBSYSTEM: WINDOWS.6.00 for x64
Primary / minor SUBSYSTEM values have nothing to do with the type of platform (ARM, x86, x64, etc.). They determine the minimum OS level at which the code file will work. Therefore, SUBSYSTEM 5.01 says that "this code file will work on XP," while SUBSYSTEM 5.02 says that "this code file will work on Windows Server 2003, but not XP." Ideally, you should map the main / minor subsystem to _WIN32_WINNT to avoid the risk of the file working with an older version of the OS that cannot support it.
At least that I remember - I do not have an XP environment that I can use to confirm that I remember this correctly.