ソースを参照

Merge topic 'cmp0128-fixup'

e47dfce75d CMP0128: Enable/disable extensions if standard same as default

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !6723
Brad King 4 年 前
コミット
648b66a1d3

+ 13 - 22
Help/policy/CMP0128.rst

@@ -9,8 +9,8 @@ When this policy is set to ``NEW``:
   :variable:`CMAKE_<LANG>_EXTENSIONS` if set, otherwise falling back to
   :variable:`CMAKE_<LANG>_EXTENSIONS_DEFAULT`.
 
-* Extensions are correctly disabled/enabled if :prop_tgt:`<LANG>_STANDARD` is
-  unset.
+* Extensions are correctly enabled/disabled if :prop_tgt:`<LANG>_STANDARD` is
+  unset or satisfied by the default.
 
 * Standard mode-affecting flags aren't added unless necessary to achieve the
   specified mode.
@@ -33,26 +33,6 @@ The ``OLD`` behavior:
 
 Code may need to be updated for the ``NEW`` behavior in the following cases:
 
-* If :prop_tgt:`<LANG>_EXTENSIONS` matches
-  :variable:`CMAKE_<LANG>_EXTENSIONS_DEFAULT` or is unset and the compiler's
-  default satisfies :prop_tgt:`<LANG>_STANDARD` but the compiled code requires
-  the exact standard specified.
-  Such code should set :prop_tgt:`<LANG>_STANDARD_REQUIRED` to ``ON``.
-
-  For example:
-
-  .. code-block:: cmake
-
-    cmake_minimum_required(VERSION |release|)
-    project(example C)
-
-    add_executable(exe main.c)
-    set_property(TARGET exe PROPERTY C_STANDARD 99)
-
-  If the compiler defaults to C11 then the standard specification for C99 is
-  satisfied and CMake will pass no flags. ``main.c`` will no longer compile if
-  it is incompatible with C11.
-
 * If a standard mode flag previously overridden by CMake's and not used during
   compiler detection now takes effect due to CMake no longer adding one as the
   default detected is appropriate.
@@ -64,6 +44,17 @@ Code may need to be updated for the ``NEW`` behavior in the following cases:
 
   * Or ensure the manually-specified flags are used during compiler detection.
 
+* If extensions were disabled without :prop_tgt:`<LANG>_STANDARD` being set
+  CMake previously wouldn't actually disable extensions.
+
+  Such code should be updated to not disable extensions if they are required.
+
+* If extensions were enabled/disabled when :prop_tgt:`<LANG>_STANDARD` was
+  satisfied by the compiler's default CMake previously wouldn't actually
+  enable/disable extensions.
+
+  Such code should be updated to set the correct extensions mode.
+
 If compiler flags affecting the standard mode are used during compiler
 detection (for example in :manual:`a toolchain file <cmake-toolchains(7)>`
 using :variable:`CMAKE_<LANG>_FLAGS_INIT`) then they will affect the detected

+ 2 - 1
Source/cmStandardLevelResolver.cxx

@@ -206,7 +206,8 @@ struct StandardLevelComputer
 
     // If the standard requested is older than the compiler's default or the
     // extension mode doesn't match then we need to use a flag.
-    if (stdIt < defaultStdIt) {
+    if (stdIt < defaultStdIt ||
+        (cmp0128 == cmPolicies::NEW && ext != defaultExt)) {
       auto offset = std::distance(cm::cbegin(stds), stdIt);
       return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
                       "_COMPILE_OPTION");

+ 12 - 0
Tests/RunCMake/CompileFeatures/ExtensionsStandardDefault-build-check.cmake

@@ -0,0 +1,12 @@
+foreach(flag @flags@)
+  string(FIND "${actual_stdout}" "${flag}" position)
+
+  if(NOT position EQUAL -1)
+    set(found TRUE)
+    break()
+  endif()
+endforeach()
+
+if(NOT found)
+  set(RunCMake_TEST_FAILED "No compile flags from \"@flags@\" found for LANG_STANDARD=default and @lang@_EXTENSIONS=@extensions_opposite@.")
+endif()

+ 9 - 0
Tests/RunCMake/CompileFeatures/ExtensionsStandardDefault.cmake

@@ -0,0 +1,9 @@
+enable_language(@lang@)
+
+# Make sure the compile command is not hidden.
+string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}")
+string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}")
+
+set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@)
+set(CMAKE_@lang@_STANDARD @standard_default@)
+add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@")

+ 0 - 0
Tests/RunCMake/CompileFeatures/UnsetStandard-build-check.cmake → Tests/RunCMake/CompileFeatures/ExtensionsStandardUnset-build-check.cmake


+ 0 - 0
Tests/RunCMake/CompileFeatures/UnsetStandard.cmake → Tests/RunCMake/CompileFeatures/ExtensionsStandardUnset.cmake


+ 11 - 5
Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake

@@ -36,7 +36,7 @@ endif()
 
 configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt" "${RunCMake_BINARY_DIR}/CMakeLists.txt" COPYONLY)
 
-macro(test_build)
+function(test_build)
   set(test ${name}-${lang})
 
   configure_file("${RunCMake_SOURCE_DIR}/${name}.cmake" "${RunCMake_BINARY_DIR}/${test}.cmake" @ONLY)
@@ -52,7 +52,7 @@ macro(test_build)
   run_cmake(${test})
   set(RunCMake_TEST_NO_CLEAN 1)
   run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . ${ARGN})
-endmacro()
+endfunction()
 
 # Mangle flags such as they're in verbose build output.
 macro(mangle_flags variable)
@@ -68,7 +68,7 @@ macro(mangle_flags variable)
   list(APPEND flags "${result}")
 endmacro()
 
-function(test_unset_standard)
+function(test_extensions_opposite)
   if(extensions_opposite)
     set(flag_ext "_EXT")
   endif()
@@ -81,9 +81,15 @@ function(test_unset_standard)
 
   mangle_flags(flag)
 
-  set(name UnsetStandard)
+  # Make sure we enable/disable extensions when:
+  # 1. LANG_STANDARD is unset.
+  set(name ExtensionsStandardUnset)
   set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW)
   test_build(--verbose)
+
+  # 2. LANG_STANDARD matches CMAKE_LANG_STANDARD_DEFAULT.
+  set(name ExtensionsStandardDefault)
+  test_build(--verbose)
 endfunction()
 
 function(test_no_unnecessary_flag)
@@ -138,7 +144,7 @@ function(test_lang lang ext)
     set(extensions_opposite ON)
   endif()
 
-  test_unset_standard()
+  test_extensions_opposite()
   test_no_unnecessary_flag()
   test_cmp0128_warn_match()
   test_cmp0128_warn_unset()