MantisBT - CMake
View Issue Details
0015670CMakeCMakepublic2015-07-29 18:342016-03-07 09:12
Christian Maaser 
Gilles Khouzam 
normalfeaturealways
closedfixed 
PCWindows10
CMake 3.2.3 
CMake 3.4CMake 3.4 
0015670: Add support for setting "Windows target platform version" in VS2015
The MSVS generator currently does not support setting a new property introduced with MSVS2015: The "Windows target platform version". This property effectively selects the platform SDK to use, which is independent from the selected compiler/platform toolset.
Use "Visual Studio 14 2015 [Win64]" generator and see how <WindowsTargetPlatformVersion> tag is missing in the generated .vcxproj files
See attached screenshot showing the new setting.

Here is a subset from a regular .vcxproj file which selects the recently released Windows 10 platform SDK version.
...
    <CharacterSet>MultiByte</CharacterSet>
    <PlatformToolset>v140</PlatformToolset>
    <WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion>
  </PropertyGroup>
...
No tags attached.
related to 0015674closed Gilles Khouzam Windows: Correctly determine Windows version for CMAKE_HOST_SYSTEM_VERSION 
related to 0015686closed Gilles Khouzam Windows phone projects targeting Windows 10 differ from Windows Phone 8.1 projects 
png targetplatformversion.png (59,109) 2015-07-29 18:34
https://public.kitware.com/Bug/file/5494/targetplatformversion.png
png

patch cmake-3.3.0-vs_target_platform_version.patch (1,788) 2015-07-29 18:49
https://public.kitware.com/Bug/file/5495/cmake-3.3.0-vs_target_platform_version.patch
Issue History
2015-07-29 18:34Christian MaaserNew Issue
2015-07-29 18:34Christian MaaserFile Added: targetplatformversion.png
2015-07-29 18:49Christian MaaserNote Added: 0039188
2015-07-29 18:49Christian MaaserFile Added: cmake-3.3.0-vs_target_platform_version.patch
2015-07-29 18:57Christian MaaserNote Added: 0039189
2015-07-29 19:42Christian MaaserNote Added: 0039190
2015-07-30 09:37Brad KingNote Added: 0039195
2015-07-30 11:14Christian MaaserNote Added: 0039197
2015-07-30 11:15Christian MaaserNote Edited: 0039197bug_revision_view_page.php?bugnote_id=39197#r1851
2015-07-30 11:17Christian MaaserNote Edited: 0039197bug_revision_view_page.php?bugnote_id=39197#r1852
2015-07-31 10:12Brad KingRelationship addedrelated to 0015674
2015-08-03 10:53Brad KingNote Added: 0039221
2015-08-03 10:57Brad KingNote Added: 0039222
2015-08-04 20:17Christian MaaserNote Added: 0039233
2015-08-04 20:39Christian MaaserNote Added: 0039234
2015-08-04 20:49Christian MaaserNote Added: 0039235
2015-08-06 11:17Brad KingRelationship addedrelated to 0015686
2015-08-06 11:22Brad KingNote Added: 0039246
2015-08-06 14:32Gilles KhouzamNote Added: 0039247
2015-08-06 16:17Christian MaaserNote Added: 0039248
2015-08-06 16:17Christian MaaserNote Edited: 0039248bug_revision_view_page.php?bugnote_id=39248#r1860
2015-08-06 16:18Christian MaaserNote Edited: 0039248bug_revision_view_page.php?bugnote_id=39248#r1861
2015-08-07 07:38Christian MaaserNote Edited: 0039248bug_revision_view_page.php?bugnote_id=39248#r1862
2015-08-31 15:51Brad KingNote Added: 0039361
2015-10-01 08:21Felix BrunsNote Added: 0039495
2015-10-01 08:26Brad KingAssigned To => Gilles Khouzam
2015-10-01 08:26Brad KingStatusnew => assigned
2015-10-01 08:28Brad KingNote Added: 0039496
2015-10-02 10:04Brad KingNote Added: 0039502
2015-10-05 13:18Brad KingStatusassigned => resolved
2015-10-05 13:18Brad KingResolutionopen => fixed
2015-10-05 13:18Brad KingFixed in Version => CMake 3.4
2015-10-05 13:18Brad KingTarget Version => CMake 3.4
2016-03-07 09:12Robert MaynardNote Added: 0040600
2016-03-07 09:12Robert MaynardStatusresolved => closed

Notes
(0039188)
Christian Maaser   
2015-07-29 18:49   
I've written a minimal patch against 3.3.0 to support this setting using a new per-target variable VS_WINDOWS_TARGET_PLATFORM_VERSION.
However, I'm unsure if this feature should be implemented that way. By choosing a different Windows platform SDK version the compiler (or rather msbuild) selects a different set of system include/lib folders, which might interact with some other cmake features.
(0039189)
Christian Maaser   
2015-07-29 18:57   
As a side note why this feature is important on Windows 10: Without explicitly setting the Windows target platform version the default choice seems to be 8.1 on my Windows 10 system. As a consequence I cannot include d3d12.h (the DirectX SDK is part of the Platform SDK for a while now). Manually adding additional include paths result in mixing 8.1 and 10 header files like e.g. Windows.h.
(0039190)
Christian Maaser   
2015-07-29 19:42   
After thinking about it for a while, selecting a different target platform than the currently running one is by definition cross compiling and should be handled that way. As such, the MSVS2015 generator should make use of CMAKE_SYSTEM_VERSION for this setting, rather than my earlier suggested new per-target variable, to prevent msbuild to automatically choose a (possibly wrong) SDK.

However, CMAKE_SYSTEM_VERSION somehow defaults to 6.2 on my Windows 10 system, which might be a different bug. I don't have any older Windows systems at hand right now to check if this is Windows 10 specific.

What do you guys think?
(0039195)
Brad King   
2015-07-30 09:37   
How does one select the preferred SDK from a command-line build (e.g. NMake)? Is it just a matter of setting the environment correctly? If so, the setting in question here is only needed for the VS generators to get the IDE to set the proper environment when launching the compiler.

On OS X we handle this with the CMAKE_OSX_SYSROOT variable that holds the selected platform SDK and turns into passing -isysroot to the compiler. Something similar may be needed here. Note there is also CMAKE_SYSROOT and there has been discussion on the developer mailing list before about whether it should subsume CMAKE_OSX_SYSROOT.

The default value of CMAKE_SYSTEM_VERSION comes from CMAKE_HOST_SYSTEM_VERSION when not cross-compiling and is determined here:

 http://www.cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmGlobalGenerator.cxx;hb=v3.3.0#l439 [^]

but is using the deprecated GetVersionEx API.
(0039197)
Christian Maaser   
2015-07-30 11:14   
(edited on: 2015-07-30 11:17)
Yes confirmed, the command-line build depends only on the environment being set. I don't see any way to select the Platform SDK using the vcvarsall.bat and that batch script always selects the latest one found (or rather the lexicographical last one):

:GetWindowsSdkDirHelper64
@REM Get Windows 10 SDK installed folder
@for /F "tokens=1,2*" %%i in ('reg query "%1\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0" /v "InstallationFolder"') DO (
    @if "%%i"=="InstallationFolder" (
        @SET WindowsSdkDir=%%k
    )
)
@REM get windows 10 sdk version number
@if not "%WindowsSdkDir%"=="" @FOR /F "delims=" %%i IN ('dir "%WindowsSdkDir%include\" /b /ad-h /on') DO @SET WindowsSDKVersion=%%i\
...

Note that the folder hierarchy of the Windows 10 Platform SDK is slightly different:
C:\Program Files (x86)\Windows Kits\8.1\Include\...
vs.
C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\...

I also confirm that the IDE (or rather msbuild) simply sets the environment depending on the Windows target platform SDK setting (by printing PATH, INCLUDE and LIBPATH as a custom build step), but chooses a different default value than the console batch scripts. There is no special compiler parameter like on OSX.

(0039221)
Brad King   
2015-08-03 10:53   
Related PR:

 https://github.com/Kitware/CMake/pull/175 [^]
(0039222)
Brad King   
2015-08-03 10:57   
PR 175 points out that this is similar to the TargetFrameworkVersion field for which support was added here:

 VS: Add support for .NET target framework version
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cfe6300a [^]

Actually I think both these cases may not have been resolved properly yet. The problem with these settings being a target property is that they would have to be set on every target explicitly. Furthermore, try_compile results may not be representative of how the targets would build.

I think a more general interface for both WindowsTargetPlatformVersion and TargetFrameworkVersion may be needed.
(0039233)
Christian Maaser   
2015-08-04 20:17   
As you already pointed out, the new setting instructs msbuild to modify the environment (variables) later used by the compiler. Additionally, these changes may be controversial with what has already been set in the environment before (globally or before invoking msbuild). As a consequence cmake would need to do the same at some early point when using the MSVS2015 generator.

Regarding your comment about whether this should be a per-target setting or not: VS2015 now allows using different platform SDKs in different projects within a single solution. However, I highly doubt that anybody needs this.
What about a global property in addition to the target property?
(0039234)
Christian Maaser   
2015-08-04 20:39   
A different approach would be to detect what platform SDK has been selected in the environment upon calling cmake and generating the XML entry appropriately. This strategy would avoid said potential conflicts between the environment and the new setting.

The main issue with this approach is that Microsoft does not offer a way to select different platform SDKs from the console (at least according to what I've seen in the batch scripts so far), and users might struggle when trying to use a different platform SDK. I don't quite know how often this might be required though... The option to use different SDKs in two separate targets would also be impossible.

Additionally, the code to detect the SDK from the environment will be error prone, e.g. when using a platform SDK that hasn't been properly installed.

Yet another potential issue is the use of automated builds through Microsoft Team Foundation Server (TFS). This terrible piece of software tends to setup the environment differently than a local build through Visual Studio. However, thats out of scope of this ticket.
(0039235)
Christian Maaser   
2015-08-04 20:49   
Regarding PR 175: I don't remember/haven't checked how msbuild passes this setting to the compiler, but by looking at all the environment variables set by vcvars32.bat (particularly 'FrameworkVersion') it is probably indeed the same mechanic.

Luckily (almost) nobody uses C++/CLI ;-)
(0039246)
Brad King   
2015-08-06 11:22   
Re 0015670:0039233, 0015670:0039234: IIUC the IDE fully defines the environment and does not care about the surrounding environment, at least for toolchain-related variables like INCLUDE and LIB.

We could make VS_WINDOWS_TARGET_PLATFORM_VERSION a per-target setting just like VS_DOTNET_TARGET_FRAMEWORK_VERSION for projects that want to customize it for specific targets. However, I think that would be an extra feature beyond whatever approach we use to configure these settings globally.

The global configuration of these settings needs to affect all in-project targets and any try_compile-generated projects as well.

We already have CMAKE_GENERATOR_PLATFORM (cmake -A) for the target architecture and CMAKE_GENERATOR_TOOLSET (cmake -T) for the toolchain selection. Both of these settings are defined to have generator-specific behavior. Both affect all targets. Both propagate into try_compile projects (see cmMakefile::TryCompile's use of SetGeneratorPlatform and SetGeneratorToolset). However, both of these are fairly generic concepts that could map to other generators and platforms as well.

I think TargetFrameworkVersion is pretty specific to VS. WindowsTargetPlatformVersion is similar to CMAKE_OSX_DEPLOYMENT_TARGET and CMAKE_OSX_SYSROOT but not exactly like either.

The earlier suggestion to use CMAKE_SYSTEM_VERSION for WindowsTargetPlatformVersion is interesting. It is already stored in a file in the build tree configured from Modules/CMakeSystem.cmake.in and is shared with try_compile projects. However, currently Modules/CMakeDetermineSystem.cmake will always set CMAKE_SYSTEM_VERSION based on CMAKE_HOST_SYSTEM_VERSION unless one explicitly sets CMAKE_SYSTEM_NAME too (to indicate cross-compiling).
(0039247)
Gilles Khouzam   
2015-08-06 14:32   
Using CMAKE_SYSTEM_VERSION will not work, it's already being used for determining the Version for Windows Store and Windows Phone apps and the TargetPlatformVersion is also needed in for Universal Windows 10 apps which are WindowsStore apps.

I think that the WindowsTargetPlatformVersion could be set to the latest SDK installed when it is not specified, but overridden with VS_WINDOWS_TARGET_PLATFORM_VERSION.

Our fork has that support currently and I'm looking to clean it up and submit a patch to add proper Windows 10 support.
(0039248)
Christian Maaser   
2015-08-06 16:17   
(edited on: 2015-08-07 07:38)
I think thats not quite accurate. Support for Universal Windows Apps is part of the Windows Platform SDK. Both version settings have to match according to
https://msdn.microsoft.com/en-us/library/Mt148501.aspx#MigrateCPlusPlus [^] :
"Find the <PropertyGroup> element that contains the <TargetPlatformVersion> and <TargetPlatformMinVersion> elements. Change the existing value of the <TargetPlatformVersion> and <TargetPlatformMinVersion> elements to be the same version of the Universal Windows Platform that you have installed."

If you'd actually wanted to have different version settings there (I don't know if that would work at all), you're still free to choose a per target property like VS_WINDOWS_TARGET_PLATFORM_VERSION in the patch above. Reserving CMAKE_SYSTEM_VERSION just for store apps doesn't make much sense at all.

I think cmake should not choose the latest SDK installed automatically, but rather one that matches CMAKE_HOST_SYSTEM_VERSION.

Re 0015670:0039246 : If cmake currently only allows specifying CMAKE_SYSTEM_VERSION when also setting CMAKE_SYSTEM_NAME, then this rule could be relaxed. It is already some sort of cross-compiling when choosing a platform SDK that doesn't match the current version of Windows. For example, it is possible to build an universal app on Windows 8 using the new Windows 10 API, thus making the app non-backwards compatible.

(0039361)
Brad King   
2015-08-31 15:51   
Relevant mailing list thread:

 [Patch] Adding Windows 10 support
 http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/14201 [^]

The patch proposed at the start of this thread defines a VS_TARGET_PLATFORM_VERSION target property and if not set checks for a VS_DEFAULT_TARGET_PLATFORM_VERSION variable.
(0039495)
Felix Bruns   
2015-10-01 08:21   
Any updates on this? Currently every time CMake (re-)generated a solution, I need to right-click it and select "Retarget solution". It would be great if CMake could make it configurable to pick the latest "Target Platform Version" available.
(0039496)
Brad King   
2015-10-01 08:28   
Re 0015670:0039495: The thread linked in 0015670:0039361 is still making progress.
(0039502)
Brad King   
2015-10-02 10:04   
After discussion in the mailing list thread linked in 0015670:0039361 we now have this implemented as follows:

 Allow CMAKE_SYSTEM_VERSION to be set without CMAKE_SYSTEM_NAME
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b31ac171 [^]

 VS: Add support for selecting the Windows 10 SDK
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3f077996 [^]

Basically one can build with -DCMAKE_SYSTEM_VERSION=10.0.##### and CMake will select the highest Windows 10 SDK available that is not greater than the version specified.
(0040600)
Robert Maynard   
2016-03-07 09:12   
Closing resolved issues that have not been updated in more than 4 months.