diff --git a/CMakeLists.txt b/CMakeLists.txt index de3e41e15a..25941468c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,32 @@ if(CCACHE_FOUND) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) endif(CCACHE_FOUND) +# Precompiled headers (opt-in, default OFF). When ON, the heaviest libraries +# (chain, protocol, wallet) precompile a curated set of stable third-party +# headers (Boost.MultiIndex, FC reflection/serialization, std) once per target +# instead of re-parsing them in every translation unit. See each library's +# pch.hpp for the header list and rationale. +# +# Left OFF by default so it cannot affect existing/CI builds until a maintainer +# opts in and measures. If ccache is in use, PCH only helps when ccache is told +# not to hash the (large, stable) PCH timestamp: export +# CCACHE_SLOPPINESS=pch_defines,time_macros +# before building, otherwise ccache conservatively disables its own cache for +# PCH-using compilations and you lose the ccache win without gaining the PCH one. +option(ENABLE_PCH "Enable precompiled headers for heavy libraries" OFF) +if(ENABLE_PCH) + message(STATUS "ENABLE_PCH: ON (precompiling stable third-party headers for chain/protocol/wallet)") + if(CCACHE_FOUND AND NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines") + message(WARNING + "ENABLE_PCH is ON and ccache is active, but CCACHE_SLOPPINESS does not " + "include pch_defines,time_macros. ccache will likely disable caching for " + "PCH-using compilations. Export " + "CCACHE_SLOPPINESS=pch_defines,time_macros before building.") + endif() +else() + message(STATUS "ENABLE_PCH: OFF") +endif() + if(WIN32) message(STATUS "Configuring VIZ on WIN32") diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index b4c8d3aa18..86b9f6d3d2 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -154,6 +154,10 @@ add_dependencies(graphene_chain graphene_protocol graphene_utilities build_hardf target_link_libraries(graphene_chain graphene_protocol graphene_utilities fc chainbase appbase ${PATCH_MERGE_LIB}) target_include_directories(graphene_chain PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/../../") +if(ENABLE_PCH) + target_precompile_headers(graphene_chain PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/pch.hpp") +endif() + if(WITH_COVERAGE) target_compile_options(graphene_chain PRIVATE --coverage) target_link_options(graphene_chain PUBLIC --coverage) diff --git a/libraries/chain/pch.hpp b/libraries/chain/pch.hpp new file mode 100644 index 0000000000..23de8af663 --- /dev/null +++ b/libraries/chain/pch.hpp @@ -0,0 +1,41 @@ +// Precompiled header for graphene_chain. +// +// Opt-in via -DENABLE_PCH=ON. Lists only *stable* third-party headers (Boost, +// FC, C++ standard library) that are pulled in — directly or transitively — by +// most translation units in this library. Project headers are intentionally +// excluded: they change often, and putting a churning header in the PCH forces +// a full-library rebuild on every edit, defeating the purpose. +// +// Chosen from an include-frequency scan of libraries/chain/*.{hpp,cpp}; the +// dominant cost here is Boost.MultiIndex plus FC serialization/reflection. +#pragma once + +// Boost.MultiIndex — the chainbase object indexes instantiate these heavily. +#include +#include +#include +#include +#include +#include + +// Boost misc used across the library. +#include +#include + +// FC framework — serialization, reflection, exceptions, primitives. +#include +#include +#include +#include +#include +#include +#include + +// C++ standard library. +#include +#include +#include +#include +#include +#include +#include diff --git a/libraries/protocol/CMakeLists.txt b/libraries/protocol/CMakeLists.txt index b35c204b2b..ea1a513a68 100644 --- a/libraries/protocol/CMakeLists.txt +++ b/libraries/protocol/CMakeLists.txt @@ -56,6 +56,10 @@ target_link_libraries(graphene_${CURRENT_TARGET} fc) target_include_directories(graphene_${CURRENT_TARGET} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include") +if(ENABLE_PCH) + target_precompile_headers(graphene_${CURRENT_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/pch.hpp") +endif() + if(WITH_COVERAGE) target_compile_options(graphene_${CURRENT_TARGET} PRIVATE --coverage) target_link_options(graphene_${CURRENT_TARGET} PUBLIC --coverage) diff --git a/libraries/protocol/pch.hpp b/libraries/protocol/pch.hpp new file mode 100644 index 0000000000..82094de261 --- /dev/null +++ b/libraries/protocol/pch.hpp @@ -0,0 +1,28 @@ +// Precompiled header for graphene_protocol. +// +// Opt-in via -DENABLE_PCH=ON. See libraries/chain/pch.hpp for the rationale: +// only stable third-party headers, no project headers. Selected from an +// include-frequency scan of libraries/protocol/*.{hpp,cpp}; the dominant cost +// here is FC reflection / static_variant plus the operation type machinery. +#pragma once + +// FC framework — reflection, serialization, primitives, crypto. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// C++ standard library. +#include +#include +#include +#include +#include diff --git a/libraries/wallet/CMakeLists.txt b/libraries/wallet/CMakeLists.txt index b1c42f093d..9ceaf4cf6c 100644 --- a/libraries/wallet/CMakeLists.txt +++ b/libraries/wallet/CMakeLists.txt @@ -50,6 +50,10 @@ target_link_libraries( ) target_include_directories( graphene_${CURRENT_TARGET} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") +if(ENABLE_PCH) + target_precompile_headers(graphene_${CURRENT_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/pch.hpp") +endif() + if(MSVC) set_source_files_properties(wallet.cpp PROPERTIES COMPILE_FLAGS "/bigobj") endif(MSVC) diff --git a/libraries/wallet/pch.hpp b/libraries/wallet/pch.hpp new file mode 100644 index 0000000000..c887e888c4 --- /dev/null +++ b/libraries/wallet/pch.hpp @@ -0,0 +1,34 @@ +// Precompiled header for graphene_wallet. +// +// Opt-in via -DENABLE_PCH=ON. See libraries/chain/pch.hpp for the rationale: +// only stable third-party headers, no project headers. Selected from an +// include-frequency scan of libraries/wallet/*.{hpp,cpp}; the cost here is +// Boost.MultiIndex, Boost.Range/algorithm, and FC's api/reflection headers. +#pragma once + +// Boost.MultiIndex. +#include +#include +#include +#include + +// Boost string / range algorithms used through the wallet. +#include +#include +#include + +// FC framework. +#include +#include +#include +#include + +// C++ standard library. +#include +#include +#include +#include +#include +#include +#include +#include