I have a huge legacy project which uses cmake as its build system which takes an awful time to run full and partial builds. The long build times are mainly due to a mix of lack of modularity and dragging in too many unnecessary include headers into interface headers.
I would like to start refactoring the project hoping to minimize the time it takes to run partial and full builds, but before that I would like to know where the bottlenecks might be when rebuilding some projects, including checking which files are rebuilt if any specific file is touched.
With this usecase in mind, does anyone know if cmake offers a way to show which targets/translation units will be rebuilt when I explicitly run a target or if I touch any file in the project tree?
This depends on the backend you're using. I think Visual Studio (msbuild) has some features for this, but I find Ninja's
-d explain
debug mode to be the most useful as it's cross-platform (Windows, macOS, and Linux).Here's a toy example:
Where all three
src*.cpp
are just empty files. Now we'll configure the build:and now we'll build it for the first time with
-d explain
:As you can see, all three objects were missing, so it prints that it needed to regenerate all of them.
Now we'll touch the timestamp of
src2.cpp
and run an incremental build, again with-d explain
:And now you can see that it gives an informative message about why, precisely, it believes the
src2
object needs to be rebuilt (the timestamps differ).For another example, let's try changing the build type:
Now you can see that Ninja accurately determined that the command line had changed since the last build, so the object is stale.
This is sometimes useful to combine with either of the following two flags:
-n
-- dry run. print usual output, but don't execute any commands.-v
-- verbose. print full command lines instead of brief descriptions.