CMake Build Trees Are Disposable
My KDE 4 build kept compiling code for a library I had just disabled. I checked the option twice, added a loud message to CMakeLists.txt, and still got the old generated header. The compiler was not being stubborn. I was looking at leftovers.
The first clue was CMakeCache.txt: the build directory had been configured against another source checkout. The second was a generated config.h whose timestamp did not move when I reran CMake. An earlier configure had put a copy in the source tree, and that directory appeared first in the include path.
make clean did not help. It removed compiled output known to the generated makefiles; it did not remove the cache, old makefiles, or a header generated by an obsolete rule. That distinction cost me most of the afternoon.
The useful diagnosis was simple. I configured a brand-new build directory from the same checkout and compared the generated command line and config.h. The fresh tree had the option I expected. At that point there was no reason to repair the old tree one cache entry at a time, so I discarded it and configured again.
I also removed the generated header from the source tree and made its destination unambiguous:
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/config.h
)
Now the binary include directory supplies config.h, and a fresh checkout cannot accidentally inherit one. If the clean build disagrees with the old build, I check the old cache’s source path, generated-file timestamps, and include order before blaming CMake detection.
Build trees are cheap. An hour spent negotiating with stale generated CMake files is not.