Skip to content

Commit

Permalink
CMake: Add detection of FEATURE_foo change by user
Browse files Browse the repository at this point in the history
Unset all QT_FEATURE_foo values for every build.
If any of FEATURE_foo is different of QT_FEATURE_foo, mark whole Qt
build as dirty. Reset FEATURE_foo for dirty builds to the calculated
value if it doesn't meet its condition.

Set Qt module as NOT FOUND if its target was not created during
configuration.

Main issue with this approach are generated files, that became trash
once the related features are disabled. This especially affects features
that enable/disable Qt modules. FooConfig.cmake files are created and
generate lots of warnings if feature was disabled. We may introduce a
module cleanup procedure at some point.

Fixes: QTBUG-85962
Pick-to: 6.0
Change-Id: Id71c1edb4027b24c6793063e40cc9d612c24ebce
Reviewed-by: Joerg Bornemann <[email protected]>
  • Loading branch information
semlanik committed Dec 17, 2020
1 parent a46a723 commit 61943ae
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 32 deletions.
33 changes: 20 additions & 13 deletions cmake/QtFeature.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ function(_qt_internal_dump_expression_values expression_dump expression)
set(${expression_dump} "${${expression_dump}}" PARENT_SCOPE)
endfunction()

function(qt_feature_set_cache_value resultVar feature emit_if calculated label)
function(qt_feature_set_cache_value resultVar feature emit_if condition calculated label)
if (DEFINED "FEATURE_${feature}")
# Must set up the cache
if (NOT (emit_if))
Expand All @@ -236,14 +236,25 @@ function(qt_feature_set_cache_value resultVar feature emit_if calculated label)

# Revisit value:
set(cache "${FEATURE_${feature}}")

# If the build is marked as dirty and the cache value doesn't meet the new condition,
# reset it to the calculated one.
get_property(dirty_build GLOBAL PROPERTY _qt_dirty_build)
if(NOT condition AND cache AND dirty_build)
set(cache "${calculated}")
message(WARNING "Reset FEATURE_${feature} value to ${calculated}, because it doesn't \
meet its condition after reconfiguration.")
endif()

set(bool_values OFF NO FALSE N ON YES TRUE Y)
if ((cache IN_LIST bool_values) OR (cache GREATER_EQUAL 0))
set(result "${cache}")
else()
message(FATAL_ERROR "Sanity check failed: FEATURE_${feature} has invalid value \"${cache}\"!")
endif()

# Fix-up user-provided values
set("FEATURE_${feature}" "${cache}" CACHE BOOL "${label}")
set("FEATURE_${feature}" "${cache}" CACHE BOOL "${label}" FORCE)
else()
# Initial setup:
if (emit_if)
Expand Down Expand Up @@ -271,11 +282,14 @@ macro(qt_feature_set_value feature cache condition label conditionExpression)
message(FATAL_ERROR "Feature ${feature} is already defined when evaluating configure.cmake features for ${target}.")
endif()
set(QT_FEATURE_${feature} "${result}" CACHE INTERNAL "Qt feature: ${feature}")

# Add feature to build feature collection
list(APPEND QT_KNOWN_FEATURES "${feature}")
set(QT_KNOWN_FEATURES "${QT_KNOWN_FEATURES}" CACHE INTERNAL "" FORCE)
endmacro()

function(qt_evaluate_feature feature)
# If the feature was set explicitly by the user to be on or off, in the cache, then
# there's nothing for us to do.
# If the feature was already evaluated as dependency nothing to do here.
if(DEFINED "QT_FEATURE_${feature}")
return()
endif()
Expand All @@ -289,10 +303,6 @@ function(qt_evaluate_feature feature)
"PRIVATE;PUBLIC"
"LABEL;PURPOSE;SECTION;" "AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF" ${_QT_FEATURE_DEFINITION_${feature}})

if(DEFINED QT_FEATURE_${feature})
return()
endif()

if("${arg_ENABLE}" STREQUAL "")
set(arg_ENABLE OFF)
endif()
Expand Down Expand Up @@ -329,10 +339,6 @@ function(qt_evaluate_feature feature)
qt_evaluate_config_expression(emit_if ${arg_EMIT_IF})
endif()

if (NOT (condition) AND (calculated))
message(FATAL_ERROR "Sanity check failed: Feature ${feature} is enabled but condition does not hold true.")
endif()

# If FEATURE_ is not defined trying to use INPUT_ variable to enable/disable feature.
if ((NOT DEFINED "FEATURE_${feature}") AND (DEFINED "INPUT_${feature}")
AND (NOT "${INPUT_${feature}}" STREQUAL "undefined")
Expand All @@ -344,7 +350,8 @@ function(qt_evaluate_feature feature)
endif()
endif()

qt_feature_set_cache_value(cache "${feature}" "${emit_if}" "${result}" "${arg_LABEL}")
qt_feature_set_cache_value(cache "${feature}" "${emit_if}" "${condition}" "${result}"
"${arg_LABEL}")
qt_feature_set_value("${feature}" "${cache}" "${condition}" "${arg_LABEL}"
"${arg_CONDITION}")

Expand Down
42 changes: 23 additions & 19 deletions cmake/QtModuleConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -86,32 +86,36 @@ if (NOT QT_NO_CREATE_TARGETS)
list(REMOVE_DUPLICATES @QT_CMAKE_EXPORT_NAMESPACE@@target@_COMPILE_DEFINITIONS)
endif()

foreach(extra_cmake_include @extra_cmake_includes@)
include("${CMAKE_CURRENT_LIST_DIR}/${extra_cmake_include}")
endforeach()
if (TARGET @QT_CMAKE_EXPORT_NAMESPACE@::@target@)
foreach(extra_cmake_include @extra_cmake_includes@)
include("${CMAKE_CURRENT_LIST_DIR}/${extra_cmake_include}")
endforeach()

include(${_qt_@PROJECT_VERSION_MAJOR@_config_cmake_dir}/QtFeature.cmake)
include(${_qt_@PROJECT_VERSION_MAJOR@_config_cmake_dir}/QtFeature.cmake)

qt_make_features_available(@QT_CMAKE_EXPORT_NAMESPACE@::@target@)
qt_make_features_available(@QT_CMAKE_EXPORT_NAMESPACE@::@target@)

if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
endif()
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
endif()

list(APPEND QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE "@target@")
list(APPEND QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE "@target@")

get_target_property(_qt_module_target_type "@INSTALL_CMAKE_NAMESPACE@::@target@" TYPE)
if(NOT _qt_module_target_type STREQUAL "INTERFACE_LIBRARY")
get_target_property(_qt_module_plugin_types
@INSTALL_CMAKE_NAMESPACE@::@target@ MODULE_PLUGIN_TYPES)
if(_qt_module_plugin_types)
list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE "${_qt_module_plugin_types}")
get_target_property(_qt_module_target_type "@INSTALL_CMAKE_NAMESPACE@::@target@" TYPE)
if(NOT _qt_module_target_type STREQUAL "INTERFACE_LIBRARY")
get_target_property(_qt_module_plugin_types
@INSTALL_CMAKE_NAMESPACE@::@target@ MODULE_PLUGIN_TYPES)
if(_qt_module_plugin_types)
list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE "${_qt_module_plugin_types}")
endif()
endif()
endif()


# Load Module's BuildInternals should any exist
if (@INSTALL_CMAKE_NAMESPACE@BuildInternals_DIR AND
# Load Module's BuildInternals should any exist
if (@INSTALL_CMAKE_NAMESPACE@BuildInternals_DIR AND
EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
endif()
else()
set("@INSTALL_CMAKE_NAMESPACE@@target@_FOUND" FALSE)
endif()
24 changes: 24 additions & 0 deletions cmake/QtSetup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,27 @@ if(QT_USE_CCACHE)
message(WARNING "Ccache use was requested, but the program was not found.")
endif()
endif()

# We need to clean up QT_FEATURE_*, but only once per configuration cycle
get_property(qt_feature_clean GLOBAL PROPERTY _qt_feature_clean)
if(NOT qt_feature_clean)
message(STATUS "Check for feature set changes")
set_property(GLOBAL PROPERTY _qt_feature_clean TRUE)
foreach(feature ${QT_KNOWN_FEATURES})
if(DEFINED "FEATURE_${feature}" AND
NOT "${QT_FEATURE_${feature}}" STREQUAL "${FEATURE_${feature}}")
message(" '${feature}' is changed from ${QT_FEATURE_${feature}} \
to ${FEATURE_${feature}}")
set(dirty_build TRUE)
endif()
unset("QT_FEATURE_${feature}" CACHE)
endforeach()

set(QT_KNOWN_FEATURES "" CACHE INTERNAL "" FORCE)

if(dirty_build)
set_property(GLOBAL PROPERTY _qt_dirty_build TRUE)
message(WARNING "Re-configuring in existing build folder. \
Some features will be re-evaluated automatically.")
endif()
endif()

0 comments on commit 61943ae

Please sign in to comment.