This cuts off roughly a third of my total build time, either with -j8
or -j24
.
There are many different ways to go about adding pre-compiled header support with CMake. This is probably the simplest and most naive, but it has a substantial impact.
I used ClangBuildAnalyzer to measure the headers which took the most amount of time to parse while building the kernel library. I did this under the assumption that those are probably the most included files in general, and because they should never be affected by changing defines/flags in different compilation units.
CMake re-generates a new pch file for each target that includes it, so it’s only worth using for libraries/binaries which compile a substantial list of cpp files. I eyeballed the libs/bins which I thought made sense.
I chose to add base_precompiled
as PRIVATE
everywhere so that it’s clear exactly where they’re being used.
Other approaches would involve keeping (or generating) lists of proper headers for each lib/bin, and potentially sharing them around when possible. The approach here (a monolithic interface lib) is unfortunately incompatible with sharing.
There’s an additional (hackish) commit to support ccache + pch. Unfortunately this requires a rather new (4.8+) ccache in order to properly set the variables we need. With the required options turned on as documented by ccache, this combo works fine for me locally.
Overall, I think this is a reasonable approach because it pretty much just works with no fiddling. The main drawback is that over time the headers list will grow stale, so it’ll require some attention now and then.
Results: (-DBUILD_UTIL_CHAINSTATE=ON -DBUILD_FUZZ_BINARY=ON -DBUILD_BENCH=ON
)
Before: **** Time summary: Compilation (1412 times): Parsing (frontend): 2619.3 s Codegen & opts (backend): 1553.3 s
Real make time: 6m20.894s
After: **** Time summary: Compilation (1422 times): Parsing (frontend): 1375.4 s Codegen & opts (backend): 1726.7 s
Real make time: 4m24.634s
pch + ccache 2nd run: 0m10.073s