CMake: Run configure tests lazily

qt_config_compile_test doesn't run the compile test immediately anymore
but just defines the test. Compile tests defined with this function are
run only if their value TEST_${name} is requested in a feature's
condition variable (EMIT_IF, CONDITION, ENABLE, ...).

If you need the TEST_${name} variable regardless of any feature
conditions, call qt_run_config_compile_test right after
qt_config_compile_test.

This avoids having e.g. Windows-specific compile tests on Linux (and
vice versa) and speeds configuration up a bit.

Fixes: QTBUG-115705
Task-number: QTBUG-107248
Change-Id: I38c4d2a48b1e5dc2f5133e0ad507ede0520ca3b8
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Joerg Bornemann 2024-10-31 14:36:56 +01:00
parent 1731d8af74
commit 605913f9d7
3 changed files with 51 additions and 4 deletions

View File

@ -27,6 +27,26 @@ function(qt_print_feature_summary)
endif() endif()
endif() endif()
# Print debug information about which tests were not run.
get_property(known_compile_tests GLOBAL PROPERTY _qtfeature_known_compile_tests)
list(REMOVE_DUPLICATES known_compile_tests)
set(tests_not_run "")
foreach(test_name IN LISTS known_compile_tests)
if(NOT DEFINED "TEST_${test_name}")
list(APPEND tests_not_run "${test_name}")
endif()
endforeach()
if(tests_not_run STREQUAL "")
message(DEBUG "All known compile tests were run.")
else()
message(DEBUG
"The following compile tests were not run, because their values were not requested."
)
foreach(test_name IN LISTS tests_not_run)
message(DEBUG "The compile test '${test_name}' was not run.")
endforeach()
endif()
# Show which packages were found. # Show which packages were found.
feature_summary(INCLUDE_QUIET_PACKAGES feature_summary(INCLUDE_QUIET_PACKAGES
WHAT PACKAGES_FOUND WHAT PACKAGES_FOUND

View File

@ -127,6 +127,7 @@ function(qt_internal_evaluate_config_expression resultVar outIdx startIdx)
set(result "") set(result "")
set(expression "${ARGN}") set(expression "${ARGN}")
list(LENGTH expression length) list(LENGTH expression length)
get_property(known_compile_tests GLOBAL PROPERTY _qtfeature_known_compile_tests)
math(EXPR memberIdx "${startIdx} - 1") math(EXPR memberIdx "${startIdx} - 1")
math(EXPR length "${length}-1") math(EXPR length "${length}-1")
@ -177,8 +178,13 @@ function(qt_internal_evaluate_config_expression resultVar outIdx startIdx)
string(COMPARE EQUAL "${lhs}" "${rhs}" stringCompareResult) string(COMPARE EQUAL "${lhs}" "${rhs}" stringCompareResult)
list(APPEND result ${stringCompareResult}) list(APPEND result ${stringCompareResult})
else() else()
string(FIND "${member}" "QT_FEATURE_" idx) if(member MATCHES "^TEST_")
if(idx EQUAL 0) # Remove the TEST_ prefix
string(SUBSTRING "${member}" 5 -1 test_name)
if(test_name IN_LIST known_compile_tests)
qt_run_config_compile_test("${test_name}")
endif()
elseif(member MATCHES "^QT_FEATURE_")
# Remove the QT_FEATURE_ prefix # Remove the QT_FEATURE_ prefix
string(SUBSTRING "${member}" 11 -1 feature) string(SUBSTRING "${member}" 11 -1 feature)
qt_evaluate_feature(${feature}) qt_evaluate_feature(${feature})
@ -949,13 +955,33 @@ endfunction()
# #
# Sets a TEST_${name}_OUTPUT variable with the build output, to the scope of the calling function. # Sets a TEST_${name}_OUTPUT variable with the build output, to the scope of the calling function.
# Sets a TEST_${name} cache variable to either TRUE or FALSE if the build is successful or not. # Sets a TEST_${name} cache variable to either TRUE or FALSE if the build is successful or not.
function(qt_config_compile_test name) #
# The test is only run if a feature condition needs to evaluate the TEST_${name} variable. If you
# need the test result regardless of any feature conditions, call
# qt_run_config_compile_test right after qt_config_compile_test.
macro(qt_config_compile_test name)
set_property(GLOBAL APPEND PROPERTY _qtfeature_known_compile_tests ${name})
set_property(GLOBAL PROPERTY _qtfeature_compile_test_args_${name} ${ARGN})
if(QT_RUN_COMPILE_TESTS_IMMEDIATELY)
qt_run_config_compile_test(${name})
endif()
endmacro()
# Runs a compile test that was defined with qt_config_compile_test.
function(qt_run_config_compile_test name)
if(DEFINED "TEST_${name}") if(DEFINED "TEST_${name}")
return() return()
endif() endif()
get_property(test_args GLOBAL PROPERTY _qtfeature_compile_test_args_${name})
if("${test_args}" STREQUAL "")
message(FATAL_ERROR
"Can't find definition for compile test '${name}'. "
"The test probably wasn't defined with qt_config_compile_test."
)
endif()
cmake_parse_arguments(arg "" "LABEL;PROJECT_PATH;C_STANDARD;CXX_STANDARD" cmake_parse_arguments(arg "" "LABEL;PROJECT_PATH;C_STANDARD;CXX_STANDARD"
"COMPILE_OPTIONS;LIBRARIES;CODE;PACKAGES;CMAKE_FLAGS" ${ARGN}) "COMPILE_OPTIONS;LIBRARIES;CODE;PACKAGES;CMAKE_FLAGS" ${test_args})
if(arg_PROJECT_PATH) if(arg_PROJECT_PATH)
message(STATUS "Performing Test ${arg_LABEL}") message(STATUS "Performing Test ${arg_LABEL}")

View File

@ -241,6 +241,7 @@ macro(defstub name)
endmacro() endmacro()
defstub(qt_add_qmake_lib_dependency) defstub(qt_add_qmake_lib_dependency)
defstub(qt_run_config_compile_test)
defstub(qt_config_compile_test) defstub(qt_config_compile_test)
defstub(qt_config_compile_test_armintrin) defstub(qt_config_compile_test_armintrin)
defstub(qt_config_compile_test_machine_tuple) defstub(qt_config_compile_test_machine_tuple)