View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015670CMakeCMakepublic2015-07-29 18:342016-03-07 09:12
ReporterChristian Maaser 
Assigned ToGilles Khouzam 
PrioritynormalSeverityfeatureReproducibilityalways
StatusclosedResolutionfixed 
PlatformPCOSWindowsOS Version10
Product VersionCMake 3.2.3 
Target VersionCMake 3.4Fixed in VersionCMake 3.4 
Summary0015670: Add support for setting "Windows target platform version" in VS2015
DescriptionThe 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.
Steps To ReproduceUse "Visual Studio 14 2015 [Win64]" generator and see how <WindowsTargetPlatformVersion> tag is missing in the generated .vcxproj files
Additional InformationSee 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>
...
TagsNo tags attached.
Attached Filespng file icon targetplatformversion.png [^] (59,109 bytes) 2015-07-29 18:34


patch file icon cmake-3.3.0-vs_target_platform_version.patch [^] (1,788 bytes) 2015-07-29 18:49 [Show Content]

 Relationships
related to 0015674closedGilles Khouzam Windows: Correctly determine Windows version for CMAKE_HOST_SYSTEM_VERSION 
related to 0015686closedGilles Khouzam Windows phone projects targeting Windows 10 differ from Windows Phone 8.1 projects 

  Notes
(0039188)
Christian Maaser (reporter)
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 (reporter)
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 (reporter)
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 (manager)
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 (reporter)
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 (manager)
2015-08-03 10:53

Related PR:

 https://github.com/Kitware/CMake/pull/175 [^]
(0039222)
Brad King (manager)
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 (reporter)
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 (reporter)
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 (reporter)
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 (manager)
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 (developer)
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 (reporter)
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 (manager)
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 (reporter)
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 (manager)
2015-10-01 08:28

Re 0015670:0039495: The thread linked in 0015670:0039361 is still making progress.
(0039502)
Brad King (manager)
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 (manager)
2016-03-07 09:12

Closing resolved issues that have not been updated in more than 4 months.

 Issue History
Date Modified Username Field Change
2015-07-29 18:34 Christian Maaser New Issue
2015-07-29 18:34 Christian Maaser File Added: targetplatformversion.png
2015-07-29 18:49 Christian Maaser Note Added: 0039188
2015-07-29 18:49 Christian Maaser File Added: cmake-3.3.0-vs_target_platform_version.patch
2015-07-29 18:57 Christian Maaser Note Added: 0039189
2015-07-29 19:42 Christian Maaser Note Added: 0039190
2015-07-30 09:37 Brad King Note Added: 0039195
2015-07-30 11:14 Christian Maaser Note Added: 0039197
2015-07-30 11:15 Christian Maaser Note Edited: 0039197
2015-07-30 11:17 Christian Maaser Note Edited: 0039197
2015-07-31 10:12 Brad King Relationship added related to 0015674
2015-08-03 10:53 Brad King Note Added: 0039221
2015-08-03 10:57 Brad King Note Added: 0039222
2015-08-04 20:17 Christian Maaser Note Added: 0039233
2015-08-04 20:39 Christian Maaser Note Added: 0039234
2015-08-04 20:49 Christian Maaser Note Added: 0039235
2015-08-06 11:17 Brad King Relationship added related to 0015686
2015-08-06 11:22 Brad King Note Added: 0039246
2015-08-06 14:32 Gilles Khouzam Note Added: 0039247
2015-08-06 16:17 Christian Maaser Note Added: 0039248
2015-08-06 16:17 Christian Maaser Note Edited: 0039248
2015-08-06 16:18 Christian Maaser Note Edited: 0039248
2015-08-07 07:38 Christian Maaser Note Edited: 0039248
2015-08-31 15:51 Brad King Note Added: 0039361
2015-10-01 08:21 Felix Bruns Note Added: 0039495
2015-10-01 08:26 Brad King Assigned To => Gilles Khouzam
2015-10-01 08:26 Brad King Status new => assigned
2015-10-01 08:28 Brad King Note Added: 0039496
2015-10-02 10:04 Brad King Note Added: 0039502
2015-10-05 13:18 Brad King Status assigned => resolved
2015-10-05 13:18 Brad King Resolution open => fixed
2015-10-05 13:18 Brad King Fixed in Version => CMake 3.4
2015-10-05 13:18 Brad King Target Version => CMake 3.4
2016-03-07 09:12 Robert Maynard Note Added: 0040600
2016-03-07 09:12 Robert Maynard Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team