Check*: Refactor variable handling

Commit 5abaf65154 (Check*: Restore toleration of `;-W...` in
CMAKE_REQUIRED_FLAGS, 2026-06-24, v4.4.0-rc3~2^2) introduced logic to
prevent `-W*` arguments in `CMAKE_REQUIRED_FLAGS` from being passed as
CMake arguments. It was never the intent of `CMAKE_REQUIRED_FLAGS` to
support such usage; however, since older versions of CMake would
silently accept such arguments, some users were unintentionally passing
compiler warnings as CMake arguments. Although this usage is incorrect,
it was silently tolerated until CMake 4.4, which began treating unknown
`-W*` as an error.

Because it turns out that modules besides `CheckSource{Compiles,Runs}`
are affected, we are going to need the logic added by that commit in
many more places. As a first step toward accommodating that need, move
the logic to a new internal helper. While we're at it, try to generally
consolidate the common logic for handling the various variables that the
`Check*` family of modules uses for injecting arguments into the
ultimate `try_compile` calls.
This commit is contained in:
Matthew Woehlke
2026-07-20 15:57:32 -04:00
committed by Brad King
parent 6a5e95f6c5
commit 7644d557df
3 changed files with 133 additions and 128 deletions

View File

@@ -0,0 +1,119 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file LICENSE.rst or https://cmake.org/licensing for details.
# Do NOT include this module directly into any of your code. It is meant as
# a library for Check*CompilerFlag.cmake and Check*LinkerFlag.cma modules.
# It's content may change in any way between releases.
include_guard(GLOBAL)
macro(CMAKE_CHECK_COMMON_INIT_COMPILE_FLAGS _PREFIX)
set(${_PREFIX}_EXTRA_CMAKE_ARGUMENTS)
string(REPLACE "\\;" "\\\\;" CMAKE_REQUIRED_FLAGS
"${CMAKE_REQUIRED_FLAGS}")
#[[
cmake_polify(GET CMP0999 ${_PREFIX}_CMP0999)
if(${_PREFIX}_CMP0999 STREQUAL "NEW")
# Join multiple list arguments into the space-separated string that we
# want. This ensures that the entirety of the value gets passed as
# compile arguments, which is what the user almost surely intended.
#
# FIXME(#27901): This needs a policy to be implemented. This will be
# available in a future version of CMake.
list(JOIN CMAKE_REQUIRED_FLAGS " " CMAKE_REQUIRED_FLAGS)
else()
#]]
# If CMAKE_REQUIRED_FLAGS contains an unescaped semicolon, anything after
# gets passed as flags to 'cmake' itself. This is probably not intended,
# but we preserve it for compatibility.
set(${_PREFIX}_EXTRA_CMAKE_ARGUMENTS "${CMAKE_REQUIRED_FLAGS}")
list(POP_FRONT ${_PREFIX}_EXTRA_CMAKE_ARGUMENTS CMAKE_REQUIRED_FLAGS)
if(NOT ${_PREFIX}_EXTRA_CMAKE_ARGUMENTS STREQUAL "")
# cmake_policy(ISSUE_WARNING CMP0999) TODO
# There are known instances of users accidentally passing '-W' arguments
# intended for the compiler as arguments to CMake. Since CMake complains
# about unknown '-W' arguments starting with CMake 4.4, we need to strip
# these for compatibility.
string(REPLACE "\\;" "\\\\;" ${_PREFIX}_EXTRA_CMAKE_ARGUMENTS
"${${_PREFIX}_EXTRA_CMAKE_ARGUMENTS}")
list(FILTER ${_PREFIX}_EXTRA_CMAKE_ARGUMENTS EXCLUDE REGEX "^-W")
endif()
#endif()
endmacro()
macro(CMAKE_CHECK_COMMON_INIT_INCLUDE_DIRECTORIES _PREFIX)
if(CMAKE_REQUIRED_INCLUDES)
if(${ARGC} GREATER 1)
set(${_PREFIX}_INCLUDE_DIRECTORIES
"-DINCLUDE_DIRECTORIES:STRING=${ARGN};${CMAKE_REQUIRED_INCLUDES}")
else()
set(${_PREFIX}_INCLUDE_DIRECTORIES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
endif()
elseif(${ARGC} GREATER 1)
set(${_PREFIX}_INCLUDE_DIRECTORIES
"-DINCLUDE_DIRECTORIES:STRING=${ARGN}")
else()
set(${_PREFIX}_INCLUDE_DIRECTORIES)
endif()
endmacro()
macro(CMAKE_CHECK_COMMON_INIT_LINK_OPTIONS _PREFIX)
if(CMAKE_REQUIRED_LINK_OPTIONS OR ${ARGC} GREATER 1)
set(${_PREFIX}_ADD_LINK_OPTIONS
LINK_OPTIONS ${ARGN} ${CMAKE_REQUIRED_LINK_OPTIONS})
else()
set(${_PREFIX}_ADD_LINK_OPTIONS)
endif()
endmacro()
macro(CMAKE_CHECK_COMMON_INIT_LINK_LIBRARIES _PREFIX)
if(CMAKE_REQUIRED_LIBRARIES OR ${ARGC} GREATER 1)
set(${_PREFIX}_ADD_LINK_LIBRARIES
LINK_LIBRARIES ${ARGN} ${CMAKE_REQUIRED_LIBRARIES})
else()
set(${_PREFIX}_ADD_LINK_LIBRARIES)
endif()
endmacro()
macro(CMAKE_CHECK_COMMON_INIT_LINK_DIRECTORIES _PREFIX)
if(CMAKE_REQUIRED_LINK_DIRECTORIES)
if(${ARGC} GREATER 1)
set(${_PREFIX}_LINK_DIRECTORIES
"-DLINK_DIRECTORIES:STRING=${ARGN};${CMAKE_REQUIRED_LINK_DIRECTORIES}")
else()
set(${_PREFIX}_LINK_DIRECTORIES
"-DLINK_DIRECTORIES:STRING=${CMAKE_REQUIRED_LINK_DIRECTORIES}")
endif()
elseif(${ARGC} GREATER 1)
set(${_PREFIX}_LINK_DIRECTORIES
"-DLINK_DIRECTORIES:STRING=${ARGN}")
else()
set(${_PREFIX}_LINK_DIRECTORIES)
endif()
endmacro()
macro(CMAKE_CHECK_COMMON_INIT_COMPILE_ARGS _PREFIX)
cmake_check_common_init_compile_flags(${_PREFIX})
cmake_check_common_init_include_directories(${_PREFIX})
endmacro()
macro(CMAKE_CHECK_COMMON_INIT_LINK_ARGS _PREFIX)
cmake_check_common_init_link_options(${_PREFIX})
cmake_check_common_init_link_libraries(${_PREFIX})
cmake_check_common_init_link_directories(${_PREFIX})
endmacro()
macro(CMAKE_CHECK_COMMON_INIT_ARGS _PREFIX)
cmake_check_common_init_compile_args(${_PREFIX})
cmake_check_common_init_link_args(${_PREFIX})
endmacro()
macro(CMAKE_CHECK_COMMON_CLEANUP _PREFIX)
unset(${_PREFIX}_ADD_LINK_OPTIONS)
unset(${_PREFIX}_ADD_LINK_LIBRARIES)
unset(${_PREFIX}_LINK_DIRECTORIES)
unset(${_PREFIX}_INCLUDE_DIRECTORIES)
unset(${_PREFIX}_EXTRA_CMAKE_ARGUMENTS)
endmacro()

View File

@@ -2,6 +2,7 @@
# file LICENSE.rst or https://cmake.org/licensing for details.
include_guard(GLOBAL)
include(Internal/CheckCommon)
function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var)
if(NOT DEFINED "${_var}")
@@ -71,65 +72,7 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var)
set(_SRC_EXT ${_lang_ext})
endif()
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
else()
set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
endif()
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
else()
set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES)
endif()
if(CMAKE_REQUIRED_LINK_DIRECTORIES)
set(_CSC_LINK_DIRECTORIES
"-DLINK_DIRECTORIES:STRING=${CMAKE_REQUIRED_LINK_DIRECTORIES}")
else()
set(_CSC_LINK_DIRECTORIES)
endif()
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else()
set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES)
endif()
set(_CSC_EXTRA_CMAKE_ARGUMENTS)
string(REPLACE "\\;" "\\\\;" CMAKE_REQUIRED_FLAGS
"${CMAKE_REQUIRED_FLAGS}")
#[[
cmake_polify(GET CMP0999 _CSC_CMP0999)
if(_CSC_CMP0999 STREQUAL "NEW")
# Join multiple list arguments into the space-separated string that we
# want. This ensures that the entirety of the value gets passed as
# compile arguments, which is what the user almost surely intended.
#
# FIXME(#27901): This needs a policy to be implemented. This will be
# available in a future version of CMake.
list(JOIN CMAKE_REQUIRED_FLAGS " " CMAKE_REQUIRED_FLAGS)
else()
#]]
# If CMAKE_REQUIRED_FLAGS contains an unescaped semicolon, anything after
# gets passed as flags to 'cmake' itself. This is probably not intended,
# but we preserve it for compatibility.
set(_CSC_EXTRA_CMAKE_ARGUMENTS "${CMAKE_REQUIRED_FLAGS}")
list(POP_FRONT _CSC_EXTRA_CMAKE_ARGUMENTS CMAKE_REQUIRED_FLAGS)
#[[
if(NOT CMAKE_REQUIRED_FLAGS STREQUAL "")
cmake_policy(ISSUE_WARNING CMP0999) TODO
endif()
#]]
# There is at least one known instance of users accidentally passing
# '-W' arguments intended for the compiler as arguments to CMake. Since
# CMake complains about unknown '-W' arguments starting with CMake 4.4,
# we need to strip these for compatibility.
string(REPLACE "\\;" "\\\\;" _CSC_EXTRA_CMAKE_ARGUMENTS
"${_CSC_EXTRA_CMAKE_ARGUMENTS}")
list(FILTER _CSC_EXTRA_CMAKE_ARGUMENTS EXCLUDE REGEX "^-W")
#endif()
cmake_check_common_init_args(_CSC)
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_START "Performing Test ${_var}")
@@ -138,15 +81,14 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var)
try_compile(${_var}
SOURCE_FROM_VAR "${_lang_filename}.${_SRC_EXT}" _source
COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES}
${_CSC_ADD_LINK_OPTIONS}
${_CSC_ADD_LINK_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
${_CSC_EXTRA_CMAKE_ARGUMENTS}
"${CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES}"
"${_CSC_LINK_DIRECTORIES}"
"${_CSC_INCLUDE_DIRECTORIES}"
"${_CSC_LINK_DIRECTORIES}"
OUTPUT_VARIABLE OUTPUT)
unset(_CSC_LINK_DIRECTORIES)
foreach(_regex ${_FAIL_REGEX})
if("${OUTPUT}" MATCHES "${_regex}")

View File

@@ -2,6 +2,7 @@
# file LICENSE.rst or https://cmake.org/licensing for details.
include_guard(GLOBAL)
include(Internal/CheckCommon)
function(CMAKE_CHECK_SOURCE_RUNS _lang _source _var)
if(NOT DEFINED "${_var}")
@@ -63,64 +64,7 @@ function(CMAKE_CHECK_SOURCE_RUNS _lang _source _var)
set(_SRC_EXT ${_lang_ext})
endif()
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
else()
set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
endif()
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
else()
set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES)
endif()
if(CMAKE_REQUIRED_LINK_DIRECTORIES)
set(_CSR_LINK_DIRECTORIES
"-DLINK_DIRECTORIES:STRING=${CMAKE_REQUIRED_LINK_DIRECTORIES}")
else()
set(_CSR_LINK_DIRECTORIES)
endif()
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else()
set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES)
endif()
set(_CSR_EXTRA_CMAKE_ARGUMENTS)
string(REPLACE "\\;" "\\\\;" CMAKE_REQUIRED_FLAGS
"${CMAKE_REQUIRED_FLAGS}")
#[[
cmake_polify(GET CMP0999 _CSR_CMP0999)
if(_CSR_CMP0999 STREQUAL "NEW")
# Join multiple list arguments into the space-separated string that we
# want. This ensures that the entirety of the value gets passed as
# compile arguments, which is what the user almost surely intended.
#
# FIXME(#27901): This needs a policy to be implemented. This will be
# available in a future version of CMake.
list(JOIN CMAKE_REQUIRED_FLAGS " " CMAKE_REQUIRED_FLAGS)
else()
#]]
# If CMAKE_REQUIRED_FLAGS contains an unescaped semicolon, anything after
# gets passed as flags to 'cmake' itself. This is probably not intended,
# but we preserve it for compatibility.
set(_CSR_EXTRA_CMAKE_ARGUMENTS "${CMAKE_REQUIRED_FLAGS}")
list(POP_FRONT _CSR_EXTRA_CMAKE_ARGUMENTS CMAKE_REQUIRED_FLAGS)
#[[
if(NOT CMAKE_REQUIRED_FLAGS STREQUAL "")
cmake_policy(ISSUE_WARNING CMP0999) TODO
endif()
#]]
# There is at least one known instance of users accidentally passing
# '-W' arguments intended for the compiler as arguments to CMake. Since
# CMake complains about unknown '-W' arguments starting with CMake 4.4,
# we need to strip these for compatibility.
string(REPLACE "\\;" "\\\\;" _CSR_EXTRA_CMAKE_ARGUMENTS
"${_CSR_EXTRA_CMAKE_ARGUMENTS}")
list(FILTER _CSR_EXTRA_CMAKE_ARGUMENTS EXCLUDE REGEX "^-W")
#endif()
cmake_check_common_init_args(_CSR)
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_START "Performing Test ${_var}")
@@ -129,16 +73,16 @@ function(CMAKE_CHECK_SOURCE_RUNS _lang _source _var)
try_run(${_var}_EXITCODE ${_var}_COMPILED
SOURCE_FROM_VAR "src.${_SRC_EXT}" _source
COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
${CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES}
${_CSR_ADD_LINK_OPTIONS}
${_CSR_ADD_LINK_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
${_CSR_EXTRA_CMAKE_ARGUMENTS}
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
"${CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES}"
"${_CSR_LINK_DIRECTORIES}"
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
"${_CSR_INCLUDE_DIRECTORIES}"
"${_CSR_LINK_DIRECTORIES}"
)
unset(_CSR_LINK_DIRECTORIES)
# if it did not compile make the return value fail code of 1
if(NOT ${_var}_COMPILED)
set(${_var}_EXITCODE 1)