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
|
|
|
|
(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
|
|
|
|
(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
|
|
|
|
(0039502)
|
Brad King
|
2015-10-02 10:04
|
|
|
|
(0040600)
|
Robert Maynard
|
2016-03-07 09:12
|
|
Closing resolved issues that have not been updated in more than 4 months. |
|