From 7bcef355bfa25e8d9d2dbc015b04831a7cf8c5a9 Mon Sep 17 00:00:00 2001 From: Petr Polezhaev Date: Thu, 12 Dec 2019 13:50:52 +0300 Subject: Vs: Add test for VS_WINRT_BY_DEFAULT --- Tests/RunCMake/VS10Project/RunCMakeTest.cmake | 4 ++ .../VS10Project/VsWinRTByDefault-check.cmake | 66 ++++++++++++++++++++++ Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake | 16 ++++++ 3 files changed, 86 insertions(+) create mode 100644 Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake create mode 100644 Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index 1487161..5cbe333 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -1,3 +1,5 @@ +cmake_policy(SET CMP0057 NEW) + include(RunCMake) cmake_policy(SET CMP0054 NEW) @@ -29,6 +31,8 @@ run_cmake(VsDpiAwareBadParam) run_cmake(VsPrecompileHeaders) run_cmake(VsPrecompileHeadersReuseFromCompilePDBName) +run_cmake(VsWinRTByDefault) + set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=$(VCTargetsPath)") run_cmake(VsVCTargetsPath) unset(RunCMake_GENERATOR_TOOLSET) diff --git a/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake b/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake new file mode 100644 index 0000000..d352946 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake @@ -0,0 +1,66 @@ +macro(checkCompileAsWinRT projectPath) + if(RunCMake_TEST_FAILED) + return() + endif() + + if (NOT EXISTS "${projectPath}") + set(RunCMake_TEST_FAILED "Project file ${projectPath} does not exist.") + return() + endif() + + get_filename_component(projectName "${projectPath}" NAME_WE) + + cmake_parse_arguments("" "" "GLOBAL" "OVERRIDES_ENABLE;OVERRIDES_DISABLE" ${ARGN}) + + unset(sourceOverride) + + file(STRINGS "${projectPath}" lines) + set(foundGlobalWinRT false) + + foreach(line IN LISTS lines) + if(line MATCHES "^ *(true|false)$") + set(value ${CMAKE_MATCH_2}) + + if(sourceOverride) + set(expectedList) + + if(value) + set(expectedList _OVERRIDES_ENABLE) + else() + set(expectedList _OVERRIDES_DISABLE) + endif() + + if(NOT sourceOverride IN_LIST ${expectedList}) + set(RunCMake_TEST_FAILED + "${projectName}: Unexpected CompileAsWinRT override ${value} for ${sourceOverride}") + return() + endif() + else() + if (NOT _GLOBAL STREQUAL value) + set(RunCMake_TEST_FAILED + "${projectName}: Global CompileAsWinRT value is ${value}, but expected ${_GLOBAL}") + return() + endif() + + set(foundGlobalWinRT true) + endif() + elseif(line MATCHES "^ *$") + get_filename_component(sourceOverride "${CMAKE_MATCH_1}" NAME) + elseif(line MATCHES "^ *$") + unset(sourceOverride) + endif() + endforeach() + + if(NOT foundGlobalWinRT AND DEFINED _GLOBAL) + set(RunCMake_TEST_FAILED "${projectName}: Global CompileAsWinRT not found or have invalid value, but expected") + return() + endif() +endmacro() + +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagOnlyC.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c) +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagMixedCAndCxx.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c) +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagOnlyCxx.vcxproj" GLOBAL true) + +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagOnlyC.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c) +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagMixedCAndCxx.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c) +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagOnlyCxx.vcxproj" GLOBAL true) diff --git a/Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake b/Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake new file mode 100644 index 0000000..139048b --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake @@ -0,0 +1,16 @@ +set(CMAKE_VS_WINRT_BY_DEFAULT true) + +enable_language(C) +enable_language(CXX) + +add_library(noFlagOnlyC empty.c) +add_library(noFlagMixedCAndCXX empty.c foo.cpp) +add_library(noFlagOnlyCXX foo.cpp) + +add_library(flagOnlyC empty.c) +add_library(flagMixedCAndCXX empty.c foo.cpp) +add_library(flagOnlyCXX foo.cpp) + +target_compile_options(flagOnlyC PRIVATE /ZW) +target_compile_options(flagMixedCAndCXX PRIVATE /ZW) +target_compile_options(flagOnlyCXX PRIVATE /ZW) -- cgit v0.12 From 557ea4614ee9352cbfff7798033175230a39e0e0 Mon Sep 17 00:00:00 2001 From: Petr Polezhaev Date: Tue, 3 Dec 2019 16:00:41 +0300 Subject: VS: Change CMAKE_VS_WINRT_BY_DEFAULT to not implicitly enable WinRT Original behaviour would unconditionally enable WinRT for all projects so source file flag generation code can acknowledge WinRT being present and disable it for C language source files. An unintentional result of that approach is that WinRT is enabled for ALL projects, including C++ projects/source files with no way to disable it Instead use `CMAKE_VS_WINRT_BY_DEFAULT` as a hint that the platform is WinRT-by-default and set global `CompileAsWinRT` flag to `false` unless it was explicitly requested by either `WINRT_COMPONENT` option or `/ZW` compilation option - similar to what Windows Phone/Windows Store platform logic does In case WinRT compilation is enabled for a project by either of aforementioned methods, C language source file override logic will still kick in and disable CompileAsWinRT for C source files Fixes: #20063 --- Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst | 14 ++++++++++++-- Source/cmVisualStudio10TargetGenerator.cxx | 9 ++++----- Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake | 6 +++--- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst b/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst index 2ba8fe2..2eea424 100644 --- a/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst +++ b/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst @@ -1,8 +1,18 @@ CMAKE_VS_WINRT_BY_DEFAULT ------------------------- -Tell :ref:`Visual Studio Generators` for VS 2010 and above that the -target platform compiles as WinRT by default (compiles with ``/ZW``). +Inform :ref:`Visual Studio Generators` for VS 2010 and above that the +target platform enables WinRT compilation by default and it needs to +be explicitly disabled if ``/ZW`` or :prop_tgt:`VS_WINRT_COMPONENT` is +omitted (as opposed to enabling it when either of those options is +present) + +This makes cmake configuration consistent in terms of WinRT among +platforms - if you did not enable the WinRT compilation explicitly, it +will be disabled (by either not enabling it or explicitly disabling it) + +Note: WinRT compilation is always explicitly disabled for C language +source files, even if it is expliclty enabled for a project This variable is meant to be set by a :variable:`toolchain file ` for such platforms. diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 8fc40a79..5e005ea 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2832,10 +2832,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( } if (this->MSTools) { - // If we have the VS_WINRT_COMPONENT or CMAKE_VS_WINRT_BY_DEFAULT - // set then force Compile as WinRT. - if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") || - this->Makefile->IsOn("CMAKE_VS_WINRT_BY_DEFAULT")) { + // If we have the VS_WINRT_COMPONENT set then force Compile as WinRT + if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT")) { clOptions.AddFlag("CompileAsWinRT", "true"); // For WinRT components, add the _WINRT_DLL define to produce a lib if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY || @@ -2843,7 +2841,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.AddDefine("_WINRT_DLL"); } } else if (this->GlobalGenerator->TargetsWindowsStore() || - this->GlobalGenerator->TargetsWindowsPhone()) { + this->GlobalGenerator->TargetsWindowsPhone() || + this->Makefile->IsOn("CMAKE_VS_WINRT_BY_DEFAULT")) { if (!clOptions.IsWinRt()) { clOptions.AddFlag("CompileAsWinRT", "false"); } diff --git a/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake b/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake index d352946..15bbaf2 100644 --- a/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake +++ b/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake @@ -57,9 +57,9 @@ macro(checkCompileAsWinRT projectPath) endif() endmacro() -checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagOnlyC.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c) -checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagMixedCAndCxx.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c) -checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagOnlyCxx.vcxproj" GLOBAL true) +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagOnlyC.vcxproj" GLOBAL false) +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagMixedCAndCxx.vcxproj" GLOBAL false) +checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagOnlyCxx.vcxproj" GLOBAL false) checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagOnlyC.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c) checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagMixedCAndCxx.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c) -- cgit v0.12