(Update with working solution at bottom)
From what I can tell, generating a dependency graph with custom targets is supported as of CMake 3.17. However, when attempting to do so, I get no dependency mapping between my targets and I get this warning:
CMake Warning:
Manually-specified variables were not used by the project:
GRAPHVIZ_CUSTOM_TARGETS
I stumbled upon this SO answer, but it hasn't helped much. The next-closest thing I could find was an incomplete Merge Request to support some different use cases.
I'm running this on Windows, but I don't know if that could be the issue.
So, I'm stumped and could use some help before I file an issue against KitWare... since I think I am missing something really obvious. Any help would be so appreciated.
CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(
gviz
LANGUAGES NONE
)
add_custom_command(
OUTPUT foo.txt
COMMAND cmake --version > foo.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_command(
OUTPUT bar.txt
COMMAND cmake --version > bar.txt
DEPENDS foo.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_target(
foo
DEPENDS foo.txt
)
add_custom_target(
bar
DEPENDS bar.txt
)
Command ran from console, and output:
Console Output:
cmake_graphviz> cmake --graphviz=group.dot -BNBuild -GNinja . -DGRAPHVIZ_CUSTOM_TARGETS=TRUE
-- Configuring done
-- Generating done
Generate graphviz: cmake_graphviz/group.dot
CMake Warning:
Manually-specified variables were not used by the project:
GRAPHVIZ_CUSTOM_TARGETS
-- Build files have been written to: cmake_graphviz/NBuild
And finally, the group.dot
file:
digraph "gviz" {
node [
fontsize = "12"
];
subgraph clusterLegend {
label = "Legend";
color = black;
edge [ style = invis ];
legendNode0 [ label = "Executable", shape = egg ];
legendNode1 [ label = "Static Library", shape = octagon ];
legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
legendNode3 [ label = "Module Library", shape = tripleoctagon ];
legendNode4 [ label = "Interface Library", shape = pentagon ];
legendNode5 [ label = "Object Library", shape = hexagon ];
legendNode6 [ label = "Unknown Library", shape = septagon ];
legendNode7 [ label = "Custom Target", shape = box ];
legendNode0 -> legendNode1 [ style = solid ];
legendNode0 -> legendNode2 [ style = solid ];
legendNode0 -> legendNode3;
legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
legendNode3 -> legendNode6 [ style = solid ];
legendNode0 -> legendNode7;
}
}
Working solution:
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.18)
project(
gviz
LANGUAGES NONE
)
# Because I don't like cmake files flooding my root directory
file(COPY cmake/CMakeGraphVizOptions.cmake DESTINATION ${CMAKE_BINARY_DIR})
add_custom_command(
OUTPUT foo.txt
COMMAND cmake --version > foo.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_command(
OUTPUT bar.txt
COMMAND cmake --version > bar.txt
DEPENDS foo.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_target(
foo
DEPENDS foo.txt
)
add_custom_target(bar)
add_dependencies(bar foo)
cmake/CMakeGraphVizOptions.cmake
# This file sets some options to control GraphViz graphs.
set(GRAPHVIZ_GRAPH_NAME "MyGraph")
set(GRAPHVIZ_CUSTOM_TARGETS TRUE)
set(GRAPHVIZ_NODE_PREFIX "blah")
File List output:
group.dot
group.dot.bar
group.dot.foo
group.dot.bar.dependers
group.dot.bar.dependers
Now, the only issue I have is it doesn't seem to link dependencies via file outputs, but that is outside of the scope of this question :)
In the linked documentation, it states:
The look and content of the generated graphs can be controlled using the file
CMakeGraphVizOptions.cmake
. This file is first searched inCMAKE_BINARY_DIR
, and then inCMAKE_SOURCE_DIR
. If found, the variables set in it are used to adjust options for the generated Graphviz files.
So, instead of setting GRAPHVIZ_CUSTOM_TARGETS
in the cmake
command line, set it in a file called CMakeGraphVizOptions.cmake
, and add this file to your top-level source directory.
An example CMakeGraphVizOptions.cmake
:
# This file sets some options to control GraphViz graphs.
set(GRAPHVIZ_GRAPH_NAME "MyGraph")
set(GRAPHVIZ_CUSTOM_TARGETS TRUE)