summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2022-09-27 18:20:49 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2022-11-29 12:43:46 +0100
commit6847a19e3edc76cce6ca0f0c25e520db591cedb9 (patch)
tree977a9b30bb615c2ed506d3ea18ba1515a3ea4892 /cmake
parent7f4aa1a3fa4610642976df549dec40364176babe (diff)
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.cmake4
-rw-r--r--cmake/QtBuildInternals/QtBuildInternalsConfig.cmake4
-rw-r--r--cmake/QtFindPackageHelpers.cmake46
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)