mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-13 01:54:13 +02:00
Add optional precompiled headers behind QET_ENABLE_PCH (default OFF)
Building QET is dominated by re-parsing Qt's headers. A 214-line source file expands to roughly 198,000 preprocessed lines, and compiling one translation unit costs ~4.1 s, of which only ~0.35 s is optimisation -- switching -O3 to -O0 saves just 8%, so the usual "build Debug for faster compiles" advice does not help here. A precompiled header caches the parsed header state, which is the part that actually costs. Measured on a 24-thread Xeon E5-2650 v4 with Qt 5.15.18 and GCC 15.2, same build tree, only the option differing: compile one translation unit 4.12 s -> 1.21 s edit one .cpp -> linked binary 5.22 s -> 1.65 s Deliberately OFF by default. A PCH satisfies includes that a source file neglected to make for itself, so code written with it enabled can fail to compile for everyone else. Leaving the default off keeps CI and contributors on the strict behaviour; only developers who opt in trade that away for the speed. Two details in the implementation are load-bearing: - The generator expressions are not decoration. This target also compiles the 18 C files of the bundled LZMA decoder, and an unguarded header list applies to every language in the target, so the Qt headers would be fed to the C compiler and fail with "unknown type name 'namespace'". $<ANGLE-R> is needed because a literal '>' would end the generator expression. - target_precompile_headers() requires CMake 3.16 while the project still declares a 3.5 minimum, so the block warns and skips rather than raising the project-wide requirement for an opt-in developer feature. Verified both ways: with the option off no PCH artefacts are generated and the build is byte-for-byte the previous behaviour; with it on, all 18 C files still compile, the generated PCH is C++-only (cmake_pch.hxx, with no cmake_pch.h), the C compile commands carry no PCH, and the resulting binary runs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -145,6 +145,34 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
# Optional precompiled headers -- see QET_ENABLE_PCH in
|
||||
# cmake/developer_options.cmake for what this trades away.
|
||||
#
|
||||
# target_precompile_headers() needs CMake 3.16; the project still declares a
|
||||
# 3.5 minimum, so guard rather than raise it for an opt-in developer feature.
|
||||
#
|
||||
# The generator expressions are load-bearing, not decoration: this target also
|
||||
# compiles the 18 C files of the bundled LZMA decoder
|
||||
# (sources/import/edz/lzma/*.c), and an unguarded list applies to every
|
||||
# language in the target, so the Qt headers would reach the C compiler and fail
|
||||
# with "unknown type name 'namespace'". $<ANGLE-R> is required because a
|
||||
# literal '>' would terminate the generator expression.
|
||||
if(QET_ENABLE_PCH)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.16)
|
||||
message(WARNING
|
||||
"QET_ENABLE_PCH needs CMake 3.16 or newer (found ${CMAKE_VERSION}); "
|
||||
"building without precompiled headers.")
|
||||
else()
|
||||
target_precompile_headers(${PROJECT_NAME} PRIVATE
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:<QtCore/QtCore$<ANGLE-R>>"
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:<QtGui/QtGui$<ANGLE-R>>"
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:<QtWidgets/QtWidgets$<ANGLE-R>>"
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:<QtXml/QtXml$<ANGLE-R>>"
|
||||
)
|
||||
message(STATUS "QET_ENABLE_PCH: precompiled headers enabled")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
PUBLIC
|
||||
|
||||
@@ -33,3 +33,17 @@ add_definitions(-DQT_MESSAGELOGCONTEXT)
|
||||
|
||||
# Build with KF5
|
||||
option(BUILD_WITH_KF5 "Build with KF5" ON)
|
||||
|
||||
# Precompiled headers for the Qt umbrella headers.
|
||||
#
|
||||
# Off by default and intended for local development only. Building QET is
|
||||
# dominated by re-parsing Qt's headers: a 214-line .cpp expands to ~198,000
|
||||
# preprocessed lines, and compiling one translation unit costs ~4.1 s of which
|
||||
# only ~0.35 s is optimisation (-O0 instead of -O3 saves 8%). A PCH caches the
|
||||
# parsed header state and takes that ~4.1 s down to ~1.2 s.
|
||||
#
|
||||
# It is deliberately NOT on by default: a PCH satisfies includes that a source
|
||||
# file forgot to make itself, so code written with it enabled can fail to
|
||||
# compile for everyone else. Leaving it off keeps CI and contributors on the
|
||||
# strict behaviour, and only developers who opt in trade that for the speed.
|
||||
option(QET_ENABLE_PCH "Use precompiled headers (developer build speed; may mask missing #includes)" OFF)
|
||||
|
||||
Reference in New Issue
Block a user