From 2cf0ba1fba9293b3265a186527dbc90d395dfd20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 5 Jul 2019 10:47:26 +0200 Subject: Use pre-compiled headers when building Qt with cmake Some modules define their own manually-maintained lists, and we can rely on the headers generated by each module to include in the pch as well e.g. QtCore/QtCore. There's also e.g. QtWidgetDepends for QtWidgets, but this only works for modules, not for tools, examples or other applications. For now we'll use the Qt/Qt headers for the modules we depend on. Building with PCH can be disabled with -DBUILD_WITH_PCH=NO, and it only works for versions of CMake newer than 3.15.20190829. Change-Id: Iae52bd69acfdfd58f4cd20d3cfa3c7f42775f732 Reviewed-by: Qt CMake Build Bot Reviewed-by: Alexandru Croitor --- CMakeLists.txt | 3 ++ cmake/QtBuild.cmake | 45 ++++++++++++++++++++-- qmake/CMakeLists.txt | 3 +- src/concurrent/CMakeLists.txt | 4 +- src/corelib/CMakeLists.txt | 5 +++ src/gui/CMakeLists.txt | 4 ++ src/network/CMakeLists.txt | 2 + src/platformsupport/edid/CMakeLists.txt | 3 +- src/platformsupport/eglconvenience/CMakeLists.txt | 3 +- .../eventdispatchers/CMakeLists.txt | 3 +- src/platformsupport/fbconvenience/CMakeLists.txt | 3 +- src/platformsupport/fontdatabases/CMakeLists.txt | 3 +- src/platformsupport/input/CMakeLists.txt | 3 +- src/platformsupport/input/xkbcommon/CMakeLists.txt | 3 +- .../linuxaccessibility/CMakeLists.txt | 3 +- src/platformsupport/services/CMakeLists.txt | 3 +- src/platformsupport/vkconvenience/CMakeLists.txt | 3 +- src/sql/CMakeLists.txt | 3 +- src/widgets/CMakeLists.txt | 2 + src/xml/CMakeLists.txt | 1 - util/cmake/pro2cmake.py | 12 ++++++ 21 files changed, 95 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a45098efbf..a52bed4658 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,9 @@ set(QT_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) ## Should this Qt be built with Werror? option(WARNINGS_ARE_ERRORS "Build Qt with warnings as errors" ${FEATURE_developer_build}) +## Should Qt be built using PCH? +option(BUILD_WITH_PCH "Build Qt using precompiled headers?" ON) + ## Decide whether tools will be built. qt_check_if_tools_will_be_built() diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index d12ddc06b7..4ce9ad9b43 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -915,6 +915,33 @@ function(qt_register_target_dependencies target public_libs private_libs) set_target_properties("${target}" PROPERTIES _qt_target_deps "${target_deps}") endfunction() +function(qt_update_precompiled_header target precompiled_header) + if (precompiled_header AND BUILD_WITH_PCH) + set_property(TARGET "${target}" APPEND PROPERTY "PRECOMPILE_HEADERS" "${precompiled_header}") + endif() +endfunction() + +function(qt_update_precompiled_header_with_library target library) + if (TARGET "${library}") + get_target_property(TARGET_TYPE "${library}" TYPE) + if (NOT TARGET_TYPE STREQUAL "INTERFACE_LIBRARY") + get_target_property(HEADER "${library}" MODULE_HEADER) + qt_update_precompiled_header("${target}" "${HEADER}") + endif() + endif() +endfunction() + +function(qt_update_ignore_pch_source target sources) + if (sources) + set_source_files_properties(${sources} PROPERTIES SKIP_PRECOMPILE_HEADERS ON) + endif() +endfunction() + +function(qt_ignore_pch_obj_c_sources target sources) + list(FILTER sources INCLUDE REGEX "\\.mm$") + qt_update_ignore_pch_source("${target}" "${sources}") +endfunction() + # This function can be used to add sources/libraries/etc. to the specified CMake target # if the provided CONDITION evaluates to true. function(extend_target target) @@ -927,8 +954,8 @@ function(extend_target target) if (NOT TARGET "${target}") message(FATAL_ERROR "Trying to extend non-existing target \"${target}\".") endif() - qt_parse_all_arguments(arg "extend_target" "HEADER_MODULE" "" - "CONDITION;${__default_public_args};${__default_private_args};COMPILE_FLAGS" ${ARGN}) + qt_parse_all_arguments(arg "extend_target" "HEADER_MODULE" "PRECOMPILED_HEADER" + "CONDITION;${__default_public_args};${__default_private_args};COMPILE_FLAGS;NO_PCH_SOURCES" ${ARGN}) if ("x${arg_CONDITION}" STREQUAL x) set(arg_CONDITION ON) endif() @@ -950,6 +977,7 @@ function(extend_target target) endforeach() foreach(lib ${arg_PUBLIC_LIBRARIES} ${arg_LIBRARIES}) + qt_update_precompiled_header_with_library("${target}" "${lib}") string(REGEX REPLACE "_nolink$" "" base_lib "${lib}") if(NOT base_lib STREQUAL lib) qt_create_nolink_target("${base_lib}" ${target}) @@ -1034,6 +1062,11 @@ function(extend_target target) ENABLE_AUTOGEN_TOOLS ${arg_ENABLE_AUTOGEN_TOOLS} DISABLE_AUTOGEN_TOOLS ${arg_DISABLE_AUTOGEN_TOOLS}) + qt_update_precompiled_header("${target}" "${arg_PRECOMPILED_HEADER}") + qt_update_ignore_pch_source("${target}" "${arg_NO_PCH_SOURCES}") + ## Ignore objective-c files for PCH (not supported atm) + qt_ignore_pch_obj_c_sources("${target}" "${arg_SOURCES}") + else() if(QT_CMAKE_DEBUG_EXTEND_TARGET) message("extend_target(${target} CONDITION ${arg_CONDITION} ...): Skipped") @@ -1218,8 +1251,8 @@ function(add_qt_module target) # Process arguments: qt_parse_all_arguments(arg "add_qt_module" "NO_MODULE_HEADERS;STATIC;DISABLE_TOOLS_EXPORT;EXCEPTIONS;INTERNAL_MODULE;NO_SYNC_QT;NO_PRIVATE_MODULE;HEADER_MODULE" - "CONFIG_MODULE_NAME" - "${__default_private_args};${__default_public_args};QMAKE_MODULE_CONFIG;EXTRA_CMAKE_FILES;EXTRA_CMAKE_INCLUDES" ${ARGN}) + "CONFIG_MODULE_NAME;PRECOMPILED_HEADER" + "${__default_private_args};${__default_public_args};QMAKE_MODULE_CONFIG;EXTRA_CMAKE_FILES;EXTRA_CMAKE_INCLUDES;NO_PCH_SOURCES" ${ARGN}) if(NOT DEFINED arg_CONFIG_MODULE_NAME) set(arg_CONFIG_MODULE_NAME "${module_lower}") @@ -1275,6 +1308,8 @@ function(add_qt_module target) set_property(TARGET "${target}" APPEND PROPERTY PUBLIC_HEADER "${module_headers_public}") set_property(TARGET "${target}" APPEND PROPERTY PUBLIC_HEADER "${module_include_dir}/${module}Depends") set_property(TARGET "${target}" APPEND PROPERTY PRIVATE_HEADER "${module_headers_private}") + set_property(TARGET "${target}" PROPERTY MODULE_HEADER "${module_include_dir}/${module}") + if(module_headers_qpa) qt_install(FILES ${module_headers_qpa} DESTINATION ${INSTALL_INCLUDEDIR}/${module}/${PROJECT_VERSION}/${module}/qpa) endif() @@ -1369,6 +1404,8 @@ function(add_qt_module target) MOC_OPTIONS ${arg_MOC_OPTIONS} ENABLE_AUTOGEN_TOOLS ${arg_ENABLE_AUTOGEN_TOOLS} DISABLE_AUTOGEN_TOOLS ${arg_DISABLE_AUTOGEN_TOOLS} + PRECOMPILED_HEADER ${arg_PRECOMPILED_HEADER} + NO_PCH_SOURCES ${arg_NO_PCH_SOURCES} ) if(NOT ${arg_EXCEPTIONS} AND NOT ${arg_HEADER_MODULE}) diff --git a/qmake/CMakeLists.txt b/qmake/CMakeLists.txt index fce7e536bd..e1e4b113c6 100644 --- a/qmake/CMakeLists.txt +++ b/qmake/CMakeLists.txt @@ -116,12 +116,13 @@ add_qt_tool(qmake # special case library $ # special case ${CMAKE_BINARY_DIR}/src/corelib/global # special case: for qconfig.cpp + PRECOMPILED_HEADER + "qmake_pch.h" ) qt_internal_add_target_aliases(Bootstrap) # special case #### Keys ignored in scope 1:.:.:qmake.pro:: -# PRECOMPILED_HEADER = "qmake_pch.h" # _OPTION = "host_build" ## Scopes: diff --git a/src/concurrent/CMakeLists.txt b/src/concurrent/CMakeLists.txt index b0d90e40ba..f330f10a1f 100644 --- a/src/concurrent/CMakeLists.txt +++ b/src/concurrent/CMakeLists.txt @@ -29,11 +29,11 @@ add_qt_module(Concurrent Qt::CorePrivate PUBLIC_LIBRARIES Qt::Core + PRECOMPILED_HEADER + "../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:concurrent.pro:: -# CONFIG = "exceptions" -# PRECOMPILED_HEADER = "../corelib/global/qt_pch.h" # _LOADED = "qt_module" ## Scopes: diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 2959939458..47ba9ce7fc 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -250,6 +250,11 @@ add_qt_module(Core PUBLIC_LIBRARIES # special case: Qt::Platform # special case: DISABLE_TOOLS_EXPORT # special case: + PRECOMPILED_HEADER + global/qt_pch.h + NO_PCH_SOURCES + text/qstring_compat.cpp + tools/qvector_msvc.cpp # special case begin # Generated in QtBaseGlobalTargets EXTRA_CMAKE_FILES ${QT_CORE_RESOURCE_GENERATED_FILE_PATH} diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index b5297cad62..1702f0f9d3 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -264,6 +264,10 @@ add_qt_module(Gui ZLIB::ZLIB PUBLIC_LIBRARIES Qt::Core + NO_PCH_SOURCES + "painting/qdrawhelper.cpp" + PRECOMPILED_HEADER + "kernel/qt_gui_pch.h" ) # Resources: diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 85ee368df5..7e392d393c 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -60,6 +60,8 @@ add_qt_module(Network ZLIB::ZLIB PUBLIC_LIBRARIES Qt::Core + PRECOMPILED_HEADER + "../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:network.pro:: diff --git a/src/platformsupport/edid/CMakeLists.txt b/src/platformsupport/edid/CMakeLists.txt index 948cb7e091..adb2d43cc0 100644 --- a/src/platformsupport/edid/CMakeLists.txt +++ b/src/platformsupport/edid/CMakeLists.txt @@ -15,10 +15,11 @@ add_qt_module(EdidSupport Qt::CorePrivate PUBLIC_LIBRARIES Qt::Core + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:edid.pro:: # CONFIG = "static" "internal_module" # MODULE = "edid_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" diff --git a/src/platformsupport/eglconvenience/CMakeLists.txt b/src/platformsupport/eglconvenience/CMakeLists.txt index a6a6633d03..e2cb21521b 100644 --- a/src/platformsupport/eglconvenience/CMakeLists.txt +++ b/src/platformsupport/eglconvenience/CMakeLists.txt @@ -19,12 +19,13 @@ add_qt_module(EglSupport Qt::CorePrivate Qt::GuiPrivate EGL::EGL # special case + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:eglconvenience.pro:: # CONFIG = "static" "internal_module" "egl" # MODULE = "egl_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" ## Scopes: diff --git a/src/platformsupport/eventdispatchers/CMakeLists.txt b/src/platformsupport/eventdispatchers/CMakeLists.txt index 5e88450023..a85af287a0 100644 --- a/src/platformsupport/eventdispatchers/CMakeLists.txt +++ b/src/platformsupport/eventdispatchers/CMakeLists.txt @@ -17,12 +17,13 @@ add_qt_module(EventDispatcherSupport PUBLIC_LIBRARIES Qt::Core Qt::Gui + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:eventdispatchers.pro:: # CONFIG = "static" "internal_module" # MODULE = "eventdispatcher_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" ## Scopes: diff --git a/src/platformsupport/fbconvenience/CMakeLists.txt b/src/platformsupport/fbconvenience/CMakeLists.txt index 05ee44b967..51bbdfe176 100644 --- a/src/platformsupport/fbconvenience/CMakeLists.txt +++ b/src/platformsupport/fbconvenience/CMakeLists.txt @@ -21,10 +21,11 @@ add_qt_module(FbSupport PUBLIC_LIBRARIES Qt::Core Qt::Gui + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:fbconvenience.pro:: # CONFIG = "static" "internal_module" # MODULE = "fb_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" diff --git a/src/platformsupport/fontdatabases/CMakeLists.txt b/src/platformsupport/fontdatabases/CMakeLists.txt index 2e42a71cb2..d6e92bb2f2 100644 --- a/src/platformsupport/fontdatabases/CMakeLists.txt +++ b/src/platformsupport/fontdatabases/CMakeLists.txt @@ -18,12 +18,13 @@ add_qt_module(FontDatabaseSupport PUBLIC_LIBRARIES Qt::Core Qt::Gui + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:fontdatabases.pro:: # CONFIG = "static" "internal_module" # MODULE = "fontdatabase_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" ## Scopes: diff --git a/src/platformsupport/input/CMakeLists.txt b/src/platformsupport/input/CMakeLists.txt index 859d2d33ad..681d103a82 100644 --- a/src/platformsupport/input/CMakeLists.txt +++ b/src/platformsupport/input/CMakeLists.txt @@ -22,12 +22,13 @@ add_qt_module(InputSupport Qt::Core Qt::DeviceDiscoverySupport Qt::Gui + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 3:.:.:input-support.pro:: # CONFIG = "static" "internal_module" # MODULE = "input_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" ## Scopes: diff --git a/src/platformsupport/input/xkbcommon/CMakeLists.txt b/src/platformsupport/input/xkbcommon/CMakeLists.txt index 1a96d5eafe..50c86bb5b8 100644 --- a/src/platformsupport/input/xkbcommon/CMakeLists.txt +++ b/src/platformsupport/input/xkbcommon/CMakeLists.txt @@ -19,12 +19,13 @@ add_qt_module(XkbCommonSupport Qt::Core Qt::Gui XKB::XKB + PRECOMPILED_HEADER + "../../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:xkbcommon.pro:: # CONFIG = "static" "internal_module" # MODULE = "xkbcommon_support" -# PRECOMPILED_HEADER = "../../../corelib/global/qt_pch.h" # _LOADED = "qt_module" ## Scopes: diff --git a/src/platformsupport/linuxaccessibility/CMakeLists.txt b/src/platformsupport/linuxaccessibility/CMakeLists.txt index af48f9d57d..023f17197b 100644 --- a/src/platformsupport/linuxaccessibility/CMakeLists.txt +++ b/src/platformsupport/linuxaccessibility/CMakeLists.txt @@ -39,10 +39,11 @@ add_qt_module(LinuxAccessibilitySupport Qt::Core Qt::DBus Qt::Gui + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:linuxaccessibility.pro:: # CONFIG = "static" "internal_module" # MODULE = "linuxaccessibility_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" diff --git a/src/platformsupport/services/CMakeLists.txt b/src/platformsupport/services/CMakeLists.txt index b926030e12..52b96aff24 100644 --- a/src/platformsupport/services/CMakeLists.txt +++ b/src/platformsupport/services/CMakeLists.txt @@ -17,12 +17,13 @@ add_qt_module(ServiceSupport PUBLIC_LIBRARIES Qt::Core Qt::Gui + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:services.pro:: # CONFIG = "static" "internal_module" # MODULE = "service_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" ## Scopes: diff --git a/src/platformsupport/vkconvenience/CMakeLists.txt b/src/platformsupport/vkconvenience/CMakeLists.txt index 325da3f8f8..feee14dafc 100644 --- a/src/platformsupport/vkconvenience/CMakeLists.txt +++ b/src/platformsupport/vkconvenience/CMakeLists.txt @@ -20,10 +20,11 @@ add_qt_module(VulkanSupport PUBLIC_LIBRARIES Qt::Core Qt::Gui + PRECOMPILED_HEADER + "../../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:vkconvenience.pro:: # CONFIG = "static" "internal_module" # MODULE = "vulkan_support" -# PRECOMPILED_HEADER = "../../corelib/global/qt_pch.h" # _LOADED = "qt_module" diff --git a/src/sql/CMakeLists.txt b/src/sql/CMakeLists.txt index 8e9345765f..4f420afb99 100644 --- a/src/sql/CMakeLists.txt +++ b/src/sql/CMakeLists.txt @@ -27,11 +27,12 @@ add_qt_module(Sql Qt::CorePrivate PUBLIC_LIBRARIES Qt::Core + PRECOMPILED_HEADER + "../corelib/global/qt_pch.h" ) #### Keys ignored in scope 1:.:.:sql.pro:: # MODULE_PLUGIN_TYPES = "sqldrivers" -# PRECOMPILED_HEADER = "../corelib/global/qt_pch.h" # SQL_P = "sql" # _LOADED = "qt_module" diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index f3abc16550..2d4299dedc 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -63,6 +63,8 @@ add_qt_module(Widgets PUBLIC_LIBRARIES Qt::Core Qt::Gui + PRECOMPILED_HEADER + "kernel/qt_widgets_pch.h" ) add_dependencies(Widgets ${QT_CMAKE_EXPORT_NAMESPACE}::uic) # special case diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index 6c7ad3489e..d31f092e5d 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -19,7 +19,6 @@ add_qt_module(Xml ) #### Keys ignored in scope 1:.:.:xml.pro:: -# PRECOMPILED_HEADER = # _LOADED = "qt_module" ## Scopes: diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py index e2ac9ef4b0..22e1b4b574 100755 --- a/util/cmake/pro2cmake.py +++ b/util/cmake/pro2cmake.py @@ -1534,6 +1534,18 @@ def write_sources_section(cm_fh: typing.IO[str], scope: Scope, *, for mo in moc_options: cm_fh.write('{} "{}"\n'.format(ind, mo)) + precompiled_header = scope.get('PRECOMPILED_HEADER') + if precompiled_header: + cm_fh.write('{} PRECOMPILED_HEADER\n'.format(ind)) + for header in precompiled_header: + cm_fh.write('{} "{}"\n'.format(ind, header)) + + no_pch_sources = scope.get('NO_PCH_SOURCES') + if no_pch_sources: + cm_fh.write('{} NO_PCH_SOURCES\n'.format(ind)) + for source in no_pch_sources: + cm_fh.write('{} "{}"\n'.format(ind, source)) + def is_simple_condition(condition: str) -> bool: return ' ' not in condition \ -- cgit v1.2.3