CMake: Store Qt features in CMake Cache

This is less self-contained than what we have, but significantly speeds
up cmake configure/generate runs.

This patch also warns when a feature is already defined.

Change-Id: I8cab63e208ba98756b47d362a39b462f5ec55e20
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Tobias Hunger 2019-01-14 11:35:53 +01:00
parent 3ec578020c
commit 6a1ee4de07
10 changed files with 34 additions and 108 deletions

View File

@ -272,27 +272,6 @@ function(extend_target target)
list(APPEND dbus_sources "${sources}")
endforeach()
foreach(dep ${arg_FEATURE_DEPENDENCIES} ${arg_LIBRARIES} ${arg_PUBLIC_LIBRARIES})
if("${dep}" MATCHES "^Qt::((.+)(Private)|(.+))$")
if (${CMAKE_MATCH_COUNT} EQUAL 3)
set(depTarget ${CMAKE_MATCH_2})
else()
set(depTarget ${CMAKE_MATCH_4})
endif()
# Fetch features from dependencies and make them available to the
# caller as well as to the local scope for configure.cmake evaluation.
if(NOT TARGET "${dep}")
find_package(Qt${PROJECT_VERSION_MAJOR}${depTarget} REQUIRED)
endif()
if("x${CMAKE_MATCH_3}" STREQUAL "xPrivate")
qt_pull_features_into_current_scope(PRIVATE_FEATURES "Qt::${depTarget}")
endif()
qt_pull_features_into_current_scope(PUBLIC_FEATURES "Qt::${depTarget}")
endif()
endforeach()
set_target_properties("${target}" PROPERTIES
AUTOMOC ON
AUTOMOC_EXECUTABLE "$<TARGET_FILE:Qt::moc>"
@ -309,8 +288,6 @@ function(extend_target target)
target_include_directories("${target}" PUBLIC ${arg_PUBLIC_INCLUDE_DIRECTORIES} PRIVATE ${arg_INCLUDE_DIRECTORIES})
target_compile_definitions("${target}" PUBLIC ${arg_PUBLIC_DEFINES} PRIVATE ${arg_DEFINES})
target_link_libraries("${target}" PUBLIC ${arg_PUBLIC_LIBRARIES} PRIVATE ${arg_LIBRARIES})
qt_push_features_into_parent_scope()
endif()
endfunction()
@ -545,8 +522,6 @@ function(add_qt_module target)
$<INSTALL_INTERFACE:include/${module}/${PROJECT_VERSION}>
$<INSTALL_INTERFACE:include/${module}/${PROJECT_VERSION}/${module}>
)
qt_push_features_into_parent_scope()
endfunction()
@ -611,8 +586,6 @@ function(add_qt_plugin target)
endif()
qt_internal_add_linker_version_script(${target})
qt_push_features_into_parent_scope()
endfunction()
@ -645,8 +618,6 @@ function(add_qt_executable name)
WIN32_EXECUTABLE "${arg_GUI}"
MACOSX_BUNDLE "${arg_GUI}"
)
qt_push_features_into_parent_scope()
endfunction()
@ -671,8 +642,6 @@ function(add_qt_test name)
set_tests_properties("${name}" PROPERTIES RUN_SERIAL "${arg_RUN_SERIAL}")
set_property(TEST "${name}" APPEND PROPERTY ENVIRONMENT "PATH=${path}${QT_PATH_SEPARATOR}${CMAKE_CURRENT_BINARY_DIR}${QT_PATH_SEPARATOR}$ENV{PATH}")
set_property(TEST "${name}" APPEND PROPERTY ENVIRONMENT "QT_PLUGIN_PATH=${PROJECT_BINARY_DIR}/${INSTALL_PLUGINSDIR}")
qt_push_features_into_parent_scope()
endfunction()
@ -680,7 +649,6 @@ endfunction()
# tests launch separate programs to test certainly input/output behavior.
function(add_qt_test_helper name)
add_qt_executable("${name}" OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ${ARGN})
qt_push_features_into_parent_scope()
endfunction()
@ -706,7 +674,6 @@ function(add_qt_tool name)
qt_internal_add_target_aliases("${name}")
install(TARGETS "${name}" EXPORT "Qt${PROJECT_VERSION_MAJOR}ToolsTargets" DESTINATION ${INSTALL_TARGETS_DEFAULT_ARGS})
qt_push_features_into_parent_scope()
endfunction()

View File

@ -180,7 +180,10 @@ macro(qt_feature_set_value feature cache emit_if condition label)
message(SEND_ERROR "Feature \"${feature}\": Forcing to \"${cache}\" breaks its condition.")
endif()
set(QT_FEATURE_${feature} "${result}" PARENT_SCOPE)
if (DEFINED "QT_FEATURE_${feature}")
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}")
endmacro()
function(qt_evaluate_feature feature)
@ -379,8 +382,6 @@ function(qt_feature_module_end target)
unset(__QtFeature_private_extra PARENT_SCOPE)
unset(__QtFeature_public_extra PARENT_SCOPE)
qt_push_features_into_parent_scope()
endfunction()
function(qt_config_compile_test name)
@ -400,55 +401,35 @@ function(qt_config_compile_test_x86simd extension label)
set(TEST_subarch_${extension} "${TEST_X86SIMD_${extension}}" CACHE INTERNAL "${label}" )
endfunction()
function(qt_pull_features_into_current_scope)
cmake_parse_arguments(arg "PUBLIC_FEATURES;PRIVATE_FEATURES" "" "" ${ARGN})
foreach(target IN ITEMS ${arg_UNPARSED_ARGUMENTS})
if(NOT "${target}" MATCHES "^Qt::[a-zA-z][a-zA-Z0-9_]*$")
message(FATAL_ERROR "${target} does not match Qt::[a-zA-z][a-zA-Z0-9_]*. INVALID NAME.")
endif()
if(NOT TARGET ${target})
message(FATAL_ERROR "${target} not found.")
endif()
function(qt_make_features_available target)
if(NOT "${target}" MATCHES "^Qt::[a-zA-z][a-zA-Z0-9_]*$")
message(FATAL_ERROR "${target} does not match Qt::[a-zA-z][a-zA-Z0-9_]*. INVALID NAME.")
endif()
if(NOT TARGET ${target})
message(FATAL_ERROR "${target} not found.")
endif()
get_target_property(target_type "${target}" TYPE)
if("${target_type}" STREQUAL "INTERFACE_LIBRARY")
set(property_prefix "INTERFACE_")
else()
set(property_prefix "")
endif()
foreach(visibility IN ITEMS PUBLIC PRIVATE)
if(NOT ${arg_${visibility}_FEATURES})
get_target_property(target_type "${target}" TYPE)
if("${target_type}" STREQUAL "INTERFACE_LIBRARY")
set(property_prefix "INTERFACE_")
else()
set(property_prefix "")
endif()
foreach(visibility IN ITEMS PUBLIC PRIVATE)
set(value ON)
foreach(state IN ITEMS ENABLED DISABLED)
get_target_property(features "${target}" ${property_prefix}QT_${state}_${visibility}_FEATURES)
if("${features}" STREQUAL "features-NOTFOUND")
continue()
endif()
set(value ON)
foreach(state IN ITEMS ENABLED DISABLED)
get_target_property(features "${target}" ${property_prefix}QT_${state}_${visibility}_FEATURES)
if("${features}" STREQUAL "features-NOTFOUND")
continue()
foreach(feature IN ITEMS ${features})
if (DEFINED "QT_FEATURE_${feature}")
message(FATAL_ERROR "Feature ${feature} is already defined when importing features from ${target}.")
endif()
foreach(feature IN ITEMS ${features})
set(QT_FEATURE_${feature} ${value} PARENT_SCOPE)
endforeach()
set(value OFF)
set(QT_FEATURE_${feature} "${value}" CACHE INTERNAL "Qt feature: ${feature}")
endforeach()
set(value OFF)
endforeach()
endforeach()
endfunction()
macro(qt_push_features_into_parent_scope)
get_cmake_property(_variableNames VARIABLES)
foreach(_var IN ITEMS ${_variableNames})
if(_var MATCHES "^QT_FEATURE_[a-z][a-z0-9_]*$")
set("${_var}" "${${_var}}" PARENT_SCOPE)
endif()
endforeach()
endmacro()
macro(qt_load_global_features)
if(NOT TARGET Qt::GlobalConfig)
find_package(Qt${PROJECT_VERSION_MAJOR}GlobalConfig QUIET)
endif()
qt_pull_features_into_current_scope(PUBLIC_FEATURES PRIVATE_FEATURES Qt::GlobalConfig)
endmacro()

View File

@ -2,8 +2,12 @@
find_package(Qt@PROJECT_VERSION_MAJOR@ QUIET)
include("${CMAKE_CURRENT_LIST_DIR}/@versioned_module_name@Targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@module_versioned@Targets.cmake")
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/@versioned_module_name@Macros.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@versioned_module_name@Macros.cmake")
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/@module_versioned@Macros.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@module_versioned@Macros.cmake")
endif()
include QtFeature
qt_make_features_available(Qt::@module@)

View File

@ -58,7 +58,6 @@ add_subdirectory(tools)
if(QT_FEATURE_gui)
add_subdirectory(gui)
qt_pull_features_into_current_scope(PUBLIC_FEATURES Qt::Gui)
if(QT_FEATURE_widgets)
add_subdirectory(widgets)
if(QT_FEATURE_opengl)

View File

@ -6,8 +6,6 @@ find_library(FWCoreGraphics CoreGraphics)
## Gui Module:
#####################################################################
qt_load_global_features()
if (QT_FEATURE_gui)
if (WINRT)
set(_default_platform "winrt")

View File

@ -1,6 +1,5 @@
# Generated from platformsupport.pro.
qt_pull_features_into_current_scope(PRIVATE_FEATURES Qt::Gui)
add_subdirectory(themes)
add_subdirectory(edid)
add_subdirectory(eventdispatchers)

View File

@ -1,5 +1,3 @@
qt_pull_features_into_current_scope(PRIVATE_FEATURES Qt::Gui)
if(QT_FEATURE_xcb)
add_subdirectory(xcb)
endif()

View File

@ -1,5 +1,2 @@
# Generated from printsupport.pro.
qt_pull_features_into_current_scope(PUBLIC_FEATURES Qt::PrintSupport)
add_subdirectory(dialogs)
add_subdirectory(kernel)

View File

@ -1,5 +1,3 @@
qt_pull_features_into_current_scope(PUBLIC_FEATURES Qt::Gui)
add_qt_test("tst_qmdiarea" RUN_SERIAL SOURCES tst_qmdiarea.cpp
DEFINES
QT_NO_CAST_TO_ASCII
@ -10,5 +8,4 @@ add_qt_test("tst_qmdiarea" RUN_SERIAL SOURCES tst_qmdiarea.cpp
)
extend_target("tst_qmdiarea" CONDITION TARGET Qt::OpenGL LIBRARIES Qt::OpenGL)
extend_target("tst_qmdiarea" CONDITION APPLE_OSX LIBRARIES FWSecurity)

View File

@ -823,23 +823,9 @@ def handle_app_or_lib(scope: Scope, cm_fh: typing.IO[str], *,
scope.currentdir())))
def handle_qt_for_config(scope: Scope, cm_fh: typing.IO[str], *,
indent: int = 0) -> None:
for config in scope.get("QT_FOR_CONFIG") or []:
lib = map_qt_library(config)
if lib.endswith("Private"):
cm_fh.write('{}qt_pull_features_into_current_scope'
'(PRIVATE_FEATURES {})\n'
.format(spaces(indent), lib[:-len("Private")]))
else:
cm_fh.write('{}qt_pull_features_into_current_scope'
'(PUBLIC_FEATURES {})\n'.format(spaces(indent), lib))
def cmakeify_scope(scope: Scope, cm_fh: typing.IO[str], *,
indent: int = 0) -> None:
template = scope.getTemplate()
handle_qt_for_config(scope, cm_fh)
if template == 'subdirs':
handle_subdir(scope, cm_fh, indent=indent)
elif template in ('app', 'lib'):