Browse Source

Merge topic 'CheckIPOSupported-honor-flags' into release-3.24

ec08bc1752 CheckIPOSupported: Compile check using flags of calling project

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !7343
Brad King 3 years ago
parent
commit
865bc4a068

+ 1 - 1
Help/manual/cmake-policies.7.rst

@@ -59,7 +59,7 @@ Policies Introduced by CMake 3.24
    :maxdepth: 1
 
    CMP0139: The if() command supports path comparisons using PATH_EQUAL operator. </policy/CMP0139>
-   CMP0138: Placeholder for reverted policy. </policy/CMP0138>
+   CMP0138: CheckIPOSupported uses flags from calling project. </policy/CMP0138>
    CMP0137: try_compile() passes platform variables in project mode. </policy/CMP0137>
    CMP0136: Watcom runtime library flags are selected by an abstraction. </policy/CMP0136>
    CMP0135: ExternalProject ignores timestamps in archives by default for the URL download method. </policy/CMP0135>

+ 19 - 1
Help/policy/CMP0138.rst

@@ -3,7 +3,25 @@ CMP0138
 
 .. versionadded:: 3.24
 
-Placeholder for reverted policy.
+:module:`CheckIPOSupported` uses flags from calling project.
+
+The :module:`CheckIPOSupported` module :command:`check_ipo_supported`
+command compiles a test project to determine whether the toolchain
+supports :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION`.  CMake 3.23 and
+below run the check with the default values of the
+:variable:`CMAKE_<LANG>_FLAGS` and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`
+variables for the current environment and toolchain settings.
+However, some projects may modify these flag variables to add
+flags that affect availability of the toolchain's IPO features.
+CMake 3.24 and above prefer to honor the calling project's values
+for these variables.  This policy provides compatibility for projects
+that have not been updated to expect this behavior.
+
+The ``OLD`` behavior for this policy is to ignore the calling
+project's values of :variable:`CMAKE_<LANG>_FLAGS` and
+:variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`.  The ``NEW`` behavior
+for this policy is to use the values of those variables as
+compiler flags in the test project.
 
 This policy was introduced in CMake version 3.24. Use the
 :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.

+ 5 - 0
Help/release/3.24.rst

@@ -323,6 +323,11 @@ Other Changes
   etc. when enabling the corresponding language during the first CMake run in
   a build directory.  See policy :policy:`CMP0132`.
 
+* The :module:`CheckIPOSupported` module :command:`check_ipo_supported`
+  command now uses the caller's :variable:`CMAKE_<LANG>_FLAGS`
+  and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` values.
+  See policy :policy:`CMP0138`.
+
 * The :generator:`MSYS Makefiles` and :generator:`MinGW Makefiles`
   generators, when a compiler is not explicitly specified, now select
   the first compiler (of any name) found in directories listed by the

+ 21 - 0
Modules/CheckIPOSupported.cmake

@@ -36,6 +36,11 @@ module will return error in this case. See policy :policy:`CMP0069` for details.
 .. versionadded:: 3.13
   Add support for Visual Studio generators.
 
+.. versionadded:: 3.24
+  The check uses the caller's :variable:`CMAKE_<LANG>_FLAGS`
+  and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` values.
+  See policy :policy:`CMP0138`.
+
 Examples
 ^^^^^^^^
 
@@ -117,6 +122,16 @@ macro(_ipo_run_language_check language)
     )
   endforeach()
 
+  if(ipo_CMP0138 STREQUAL "NEW")
+    set(CMAKE_TRY_COMPILE_CONFIGURATION Debug)
+    set(_CMAKE_LANG_FLAGS
+      "-DCMAKE_${language}_FLAGS:STRING=${CMAKE_${language}_FLAGS}"
+      "-DCMAKE_${language}_FLAGS_DEBUG:STRING=${CMAKE_${language}_FLAGS_DEBUG}"
+      )
+  else()
+    set(_CMAKE_LANG_FLAGS "")
+  endif()
+
   try_compile(
       _IPO_LANGUAGE_CHECK_RESULT
       "${bindir}"
@@ -125,6 +140,7 @@ macro(_ipo_run_language_check language)
       CMAKE_FLAGS
       "-DCMAKE_VERBOSE_MAKEFILE=ON"
       "-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON"
+      ${_CMAKE_LANG_FLAGS}
       OUTPUT_VARIABLE output
   )
   set(_IPO_LANGUAGE_CHECK_RESULT "${_IPO_LANGUAGE_CHECK_RESULT}")
@@ -155,6 +171,11 @@ function(check_ipo_supported)
     message(FATAL_ERROR "Policy CMP0069 set to OLD")
   endif()
 
+  # Save policy setting for condition in _ipo_run_language_check.
+  cmake_policy(GET CMP0138 ipo_CMP0138
+    PARENT_SCOPE # undocumented, do not use outside of CMake
+    )
+
   set(optional)
   set(one RESULT OUTPUT)
   set(multiple LANGUAGES)

+ 2 - 1
Source/cmPolicies.h

@@ -415,7 +415,8 @@ class cmMakefile;
   SELECT(POLICY, CMP0137,                                                     \
          "try_compile() passes platform variables in project mode", 3, 24, 0, \
          cmPolicies::WARN)                                                    \
-  SELECT(POLICY, CMP0138, "Placeholder for reverted policy.", 3, 24, 0,       \
+  SELECT(POLICY, CMP0138,                                                     \
+         "CheckIPOSupported uses flags from calling project.", 3, 24, 0,      \
          cmPolicies::WARN)                                                    \
   SELECT(                                                                     \
     POLICY, CMP0139,                                                          \

+ 9 - 0
Tests/RunCMake/CheckIPOSupported/CMP0138-Common.cmake

@@ -0,0 +1,9 @@
+enable_language(C)
+string(APPEND CMAKE_C_FLAGS " -DFOO")
+string(APPEND CMAKE_C_FLAGS_DEBUG " -DBAR")
+check_ipo_supported(RESULT ipo_supported)
+file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/_CMakeLTOTest-C/bin/CMakeCache.txt"
+  cached_flags REGEX "^CMAKE_C_FLAGS(_DEBUG)?:")
+foreach(line IN LISTS cached_flags)
+  message(STATUS "${line}")
+endforeach()

+ 5 - 0
Tests/RunCMake/CheckIPOSupported/CMP0138-NEW-stdout.txt

@@ -0,0 +1,5 @@
+-- CMAKE_C_FLAGS:STRING=[^
+]*-DFOO
+-- CMAKE_C_FLAGS_DEBUG:STRING=[^
+]*-DBAR
+--

+ 2 - 0
Tests/RunCMake/CheckIPOSupported/CMP0138-NEW.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0138 NEW)
+include(CMP0138-Common.cmake)

+ 3 - 0
Tests/RunCMake/CheckIPOSupported/CMP0138-OLD-stdout.txt

@@ -0,0 +1,3 @@
+-- CMAKE_C_FLAGS:STRING=([^-]|-[^D]|-D[^F]|-DF[^O]|-DFO[^O])*
+-- CMAKE_C_FLAGS_DEBUG:STRING=([^-]|-[^D]|-D[^B]|-DB[^A]|-DBA[^R])*
+--

+ 2 - 0
Tests/RunCMake/CheckIPOSupported/CMP0138-OLD.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0138 OLD)
+include(CMP0138-Common.cmake)

+ 3 - 0
Tests/RunCMake/CheckIPOSupported/CMP0138-WARN-stdout.txt

@@ -0,0 +1,3 @@
+-- CMAKE_C_FLAGS:STRING=([^-]|-[^D]|-D[^F]|-DF[^O]|-DFO[^O])*
+-- CMAKE_C_FLAGS_DEBUG:STRING=([^-]|-[^D]|-D[^B]|-DB[^A]|-DBA[^R])*
+--

+ 2 - 0
Tests/RunCMake/CheckIPOSupported/CMP0138-WARN.cmake

@@ -0,0 +1,2 @@
+# (leave CMP0138 unset)
+include(CMP0138-Common.cmake)

+ 5 - 0
Tests/RunCMake/CheckIPOSupported/Inspect.cmake

@@ -0,0 +1,5 @@
+enable_language(C)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "
+set(_CMAKE_C_IPO_SUPPORTED_BY_CMAKE \"${_CMAKE_C_IPO_SUPPORTED_BY_CMAKE}\")
+set(_CMAKE_C_IPO_MAY_BE_SUPPORTED_BY_COMPILER \"${_CMAKE_C_IPO_MAY_BE_SUPPORTED_BY_COMPILER}\")
+")

+ 11 - 0
Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake

@@ -1,5 +1,8 @@
 include(RunCMake)
 
+run_cmake(Inspect)
+include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
+
 run_cmake(unparsed-arguments)
 run_cmake(user-lang-unknown)
 run_cmake(default-lang-none)
@@ -8,6 +11,14 @@ run_cmake(not-supported-by-compiler)
 run_cmake(save-to-result)
 run_cmake(cmp0069-is-old)
 
+if(_CMAKE_C_IPO_SUPPORTED_BY_CMAKE
+    AND _CMAKE_C_IPO_MAY_BE_SUPPORTED_BY_COMPILER
+    AND NOT RunCMake_GENERATOR MATCHES "^Visual Studio 9 ")
+  run_cmake(CMP0138-WARN)
+  run_cmake(CMP0138-OLD)
+  run_cmake(CMP0138-NEW)
+endif()
+
 if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 ")
   run_cmake(not-supported-by-generator)
 endif()