CheckIPOSupported: Compile check using flags of calling project

Forward `CMAKE_<LANG>_FLAGS` and `CMAKE_<LANG>_FLAGS_DEBUG` from the
calling project into the test project.  The set of flags may affect the
availability of IPO support.  Since this may change the result of the
check for existing projects, add a policy for compatibility.

This was discovered after commit 5fcadc481e (MSVC: Default to -ZI
instead of /Zi for x86 and x64, 2022-05-24) introduced policy CMP0138 to
switch our default for MSVC's debug info flag.  The `-ZI` flag is
incompatible with the `-GL` flag used for IPO, so CMP0138 was reverted
pending future work on an alternative solution.  Re-use the CMP0138
policy number for this change to CheckIPOSupported instead.

Fixes: #23607
This commit is contained in:
Brad King
2022-06-09 12:23:42 -04:00
parent 7d73e88d3a
commit ec08bc1752
14 changed files with 90 additions and 3 deletions

View File

@@ -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>

View File

@@ -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.

View File

@@ -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

View File

@@ -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)

View File

@@ -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, \

View File

@@ -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()

View File

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

View File

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

View File

@@ -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])*
--

View File

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

View File

@@ -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])*
--

View File

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

View File

@@ -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}\")
")

View File

@@ -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()