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:
cmake_minimum_required(VERSION 3.18)
project(test)
add_library(example src1.cpp src2.cpp src3.cpp)
Where all three src*.cpp
are just empty files. Now we'll configure the build:
$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
....
and now we'll build it for the first time with -d explain
:
$ cmake --build build/ -- -d explain
ninja explain: deps for 'CMakeFiles/example.dir/src1.cpp.o' are missing
ninja explain: CMakeFiles/example.dir/src1.cpp.o is dirty
ninja explain: deps for 'CMakeFiles/example.dir/src2.cpp.o' are missing
ninja explain: CMakeFiles/example.dir/src2.cpp.o is dirty
ninja explain: deps for 'CMakeFiles/example.dir/src3.cpp.o' are missing
ninja explain: CMakeFiles/example.dir/src3.cpp.o is dirty
ninja explain: libexample.a is dirty
[4/4] Linking CXX static library libexample.a
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
:
$ touch src2.cpp
$ cmake --build build/ -- -d explain
ninja explain: output CMakeFiles/example.dir/src2.cpp.o older than most recent input ../src2.cpp (1657545617908948058 vs 1657545747611703486)
ninja explain: CMakeFiles/example.dir/src2.cpp.o is dirty
ninja explain: libexample.a is dirty
[2/2] Linking CXX static library libexample.a
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:
$ cmake build/ -DCMAKE_BUILD_TYPE=Debug
...
$ cmake --build build/ -- -d explain
ninja explain: command line changed for CMakeFiles/example.dir/src1.cpp.o
ninja explain: CMakeFiles/example.dir/src1.cpp.o is dirty
ninja explain: command line changed for CMakeFiles/example.dir/src2.cpp.o
ninja explain: CMakeFiles/example.dir/src2.cpp.o is dirty
ninja explain: command line changed for CMakeFiles/example.dir/src3.cpp.o
ninja explain: CMakeFiles/example.dir/src3.cpp.o is dirty
ninja explain: libexample.a is dirty
[4/4] Linking CXX static library libexample.a
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.