diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2022-09-27 18:20:49 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2022-11-29 12:43:46 +0100 |
commit | 6847a19e3edc76cce6ca0f0c25e520db591cedb9 (patch) | |
tree | 977a9b30bb615c2ed506d3ea18ba1515a3ea4892 /cmake | |
parent | 7f4aa1a3fa4610642976df549dec40364176babe (diff) | |
download | qtbase-6847a19e3edc76cce6ca0f0c25e520db591cedb9.tar.gz |
CMake: Reconfigure faster by not looking for missing packages
Instead of constantly trying to find packages by calling
qt_find_package on each reconfiguration, record which packages were
found during initial configuration. Then on a second reconfiguration,
skip looking for packages that were not found on the initial
configuration.
This speeds up reconfiguration on certain platforms and repos.
Here are some stats for my macOS qtbase build.
not skip 3.69s user 4.96s system 98% cpu 8.750 total
skip 2.69s user 1.00s system 97% cpu 3.792 total
Top-level build with -submodules=qtquick3d
not skip 15.03s user 10.58s system 97% cpu 26.334 total
skip 13.87s user 5.16s system 96% cpu 19.724 total
Note this is a behavior change from how find_package is used in most
CMake projects, where if a package was previously missing, the
developer can just install the package and reconfigure to pick it up.
With this change, they will first have to remove their CMakeCache.txt
file and configure from scratch, or remove the
QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES cache variable and reconfigure.
For this reason, we enable this behavior by default only in
-developer-builds.
Builders can also opt in or out by setting the
QT_INTERNAL_SAVE_PREVIOUSLY_FOUND_PACKAGES variable to either ON or
OFF.
Note this behavior does not apply to user projects, or direct
find_package calls (as opposed to qt_find_package).
Fixes: QTBUG-107251
Change-Id: Iee9c5d120eb09e2a94eebb059a2174ef6b241e03
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
Reviewed-by: Amir Masoud Abdol <amir.abdol@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/QtBuildInformation.cmake | 4 | ||||
-rw-r--r-- | cmake/QtBuildInternals/QtBuildInternalsConfig.cmake | 4 | ||||
-rw-r--r-- | cmake/QtFindPackageHelpers.cmake | 46 |
3 files changed, 54 insertions, 0 deletions
diff --git a/cmake/QtBuildInformation.cmake b/cmake/QtBuildInformation.cmake index 51a0315bc9..3d4e9cdaf6 100644 --- a/cmake/QtBuildInformation.cmake +++ b/cmake/QtBuildInformation.cmake @@ -101,6 +101,10 @@ from the build directory \n") endif() set(QT_INTERNAL_BUILD_INSTRUCTIONS_SHOWN "TRUE" CACHE STRING "" FORCE) + + if(QT_SUPERBUILD) + qt_internal_save_previously_found_packages() + endif() endfunction() function(qt_configure_print_summary_helper summary_reports force_show) diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake index 8b3e583144..d547ffe4b6 100644 --- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake +++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake @@ -527,6 +527,10 @@ macro(qt_build_repo_end) "List of the synced modules. Prevents running syncqt.cpp after the first configuring.") endif() + if(NOT QT_SUPERBUILD) + qt_internal_save_previously_found_packages() + endif() + list(POP_BACK CMAKE_MESSAGE_CONTEXT) endmacro() diff --git a/cmake/QtFindPackageHelpers.cmake b/cmake/QtFindPackageHelpers.cmake index 98617a7b5a..407e41b833 100644 --- a/cmake/QtFindPackageHelpers.cmake +++ b/cmake/QtFindPackageHelpers.cmake @@ -34,6 +34,17 @@ macro(qt_find_package) # qt_find_package(PNG PROVIDED_TARGET PNG::PNG) still needs to succeed and register the provided # targets. To enable the debugging behavior, set QT_DEBUG_QT_FIND_PACKAGE to 1. set(_qt_find_package_skip_find_package FALSE) + + # Skip looking for packages that were not found on initial configuration, because they likely + # won't be found again, and only waste configuration time. + # Speeds up reconfiguration configuration for certain platforms and repos. + # Due to this behavior being different from what general CMake projects expect, it is only + # done for -developer-builds. + if(QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES AND + NOT "${ARGV0}" IN_LIST QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES) + set(_qt_find_package_skip_find_package TRUE) + endif() + if(QT_DEBUG_QT_FIND_PACKAGE AND ${ARGV0}_FOUND AND arg_PROVIDED_TARGETS) set(_qt_find_package_skip_find_package TRUE) foreach(qt_find_package_target_name ${arg_PROVIDED_TARGETS}) @@ -141,6 +152,11 @@ macro(qt_find_package) endif() endif() + if(${ARGV0}_FOUND) + # Record that the package was found, so that future reconfigurations can be sped up. + set_property(GLOBAL APPEND PROPERTY _qt_previously_found_packages "${ARGV0}") + endif() + if(${ARGV0}_FOUND AND arg_PROVIDED_TARGETS AND NOT _qt_find_package_skip_find_package) # If package was found, associate each target with its package name. This will be used # later when creating Config files for Qt libraries, to generate correct find_dependency() @@ -200,6 +216,36 @@ macro(qt_find_package) endif() endmacro() +# Save found packages in the cache. They will be read on next reconfiguration to skip looking +# for packages that were not previously found. +# Only applies to -developer-builds by default. +# Can also be opted in or opted out via QT_INTERNAL_SAVE_PREVIOUSLY_FOUND_PACKAGES. +# Opting out will need two reconfigurations to take effect. +function(qt_internal_save_previously_found_packages) + if(DEFINED QT_INTERNAL_SAVE_PREVIOUSLY_FOUND_PACKAGES) + set(should_save "${QT_INTERNAL_SAVE_PREVIOUSLY_FOUND_PACKAGES}") + else() + if(FEATURE_developer_build OR QT_FEATURE_developer_build) + set(should_save ON) + else() + set(should_save OFF) + endif() + endif() + + if(NOT should_save) + # When the value is flipped to OFF, remove any previously saved packages. + unset(QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES CACHE) + return() + endif() + + get_property(_qt_previously_found_packages GLOBAL PROPERTY _qt_previously_found_packages) + if(_qt_previously_found_packages) + list(REMOVE_DUPLICATES _qt_previously_found_packages) + set(QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES "${_qt_previously_found_packages}" CACHE INTERNAL + "List of CMake packages found during configuration using qt_find_package.") + endif() +endfunction() + # Return qmake library name for the given target, e.g. return "vulkan" for "Vulkan::Vulkan". function(qt_internal_map_target_to_qmake_lib target out_var) set(${out_var} "${QT_QMAKE_LIB_OF_TARGET_${target}}" PARENT_SCOPE) |