When cmake assembles the compiler commands, the final result can be written to a file “compile_commands.json” in the build folder by setting
CMAKE_EXPORT_COMPILE_COMMANDS=ON
either in CMakeLists.txt:
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
or via the command line:
cmake (...) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
This makes it easy to test the compilation of an individual file and quickly fiddle around with the options (e.g. adding or removing an option).
However, it’s often really hard to judge from where a specific compiler flag comes from, e.g. an include directory, as it can be set directly (e.g. target_include_directories) or indirectly from a dependency target (e.g. from target__link_libraries).
In that case on can use the following snippet to have CMake print with the following snippet in CMakeLists.txt:
set(CMAKE_DEBUG_TARGET_PROPERTIES
INCLUDE_DIRECTORIES
COMPILE_DEFINITIONS
POSITION_INDEPENDENT_CODE
CONTAINER_SIZE_REQUIRED
LIB_VERSION
)
which I found here.
Dependency management in huge projects is hard. Want to reuse a component and extract it from a huge workspace? Removing parts of a project (wrappers, GUI, backends) and want to know which dependencies you now can throw out?
Try the –graphviz option of cmake:
cmake .. --graphviz=dependency-graph.dot
This will generate a file dependency-graph.dot that contains all dependencies in the project. The official documentation of this feature can be found at cmake.org
To view this use dot
(if you don’t have it: sudo apt install graphviz) to convert the graph file to some viewable document, e.g. to an pdf:
dot dependency-graph.dot -Tpdf -o dependency-graph.pdf
Replace -Tpdf
(and the filename extension) with -Tpng
to get an image instead.
A neat “trick” to make the hierarchy more readable is to set rankdir="LR";
with the -G option, which changes the layout of the hierarchy to left-to-right:
dot -Grankdir="LR" dependency-tree.dot -Tpdf -o dependency-tree.pdf
This one comes from the fantastic online book An Introduction to Modern CMake, specifically its chapter on debugging. Adding –trace-source=your-cmake-file will log every line that is run to the screen. Example:
cmake .. –trace-source=CMakeLists.txt
Adding --trace-expand
will expand the variables to their values.