Răsfoiți Sursa

Merge topic 'fix-vs-winrt-by-default'

557ea4614e VS: Change CMAKE_VS_WINRT_BY_DEFAULT to not implicitly enable WinRT
7bcef355bf Vs: Add test for VS_WINRT_BY_DEFAULT

Acked-by: Kitware Robot <[email protected]>
Merge-request: !4127
Brad King 6 ani în urmă
părinte
comite
37a30f228a

+ 12 - 2
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 <CMAKE_TOOLCHAIN_FILE>` for such platforms.

+ 4 - 5
Source/cmVisualStudio10TargetGenerator.cxx

@@ -2829,10 +2829,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 ||
@@ -2840,7 +2838,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");
       }

+ 4 - 0
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)

+ 66 - 0
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 "^ *<CompileAsWinRT( Condition=\"[^\\\"]+\")?>(true|false)</CompileAsWinRT>$")
+      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 "^ *<ClCompile Include=\"([^\"]+)\">$")
+      get_filename_component(sourceOverride "${CMAKE_MATCH_1}" NAME)
+    elseif(line MATCHES "^ *</ClCompile>$")
+      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 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)
+checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagOnlyCxx.vcxproj" GLOBAL true)

+ 16 - 0
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)