Javier Calzado
Javier Calzado

Reputation: 131

CMake graphviz auto generated

I know the common way to generate a CMake project dependencies graph by the CLI:

cmake --graphviz=[file]

But is there a way for it to be autogenerated by just setting a flag or command within a CMakeList? The idea is for the CMakeLists.txt itself to trigger the graph generation, and not the user through command line.

Upvotes: 13

Views: 15566

Answers (3)

SolomidHero
SolomidHero

Reputation: 178

Comparing to other answers I thought it is more convenient if graphviz generation runs only when it is required. Also I check if graphiz/dot itself exists:

find_program(GRAPHVIZ dot)
if(GRAPHVIZ)
    add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/_graphviz
        COMMAND ${CMAKE_COMMAND} "--graphviz=graphviz/deps.txt" .
        COMMAND dot -Tsvg graphviz/deps.txt -o deps.svg
        COMMAND dot -Tpng graphviz/deps.txt -o deps.png
        COMMENT "Plotting dependencies graph to deps.svg"
        DEPENDS <some_target>
        WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
    add_custom_target(graphviz ALL
        DEPENDS ${CMAKE_BINARY_DIR}/_graphviz)
endif()

When some_target changes it also will try to regenerate OUTPUT _graphviz file, thus plot dependencies.

By default TARGET graphviz target always builds, but it is empty, so plotting itself is not called, if OUTPUT _graphviz is not updated

p.s. found this seeing answer of Alternative to CMake POST_BUILD command when target is in subdirectory

Upvotes: 0

Kevin
Kevin

Reputation: 18361

Not only can you create a CMake custom target for running Graphviz, but you can take it a step further, and have it also generate the image files for you using Dot:

add_custom_target(graphviz ALL
    COMMAND ${CMAKE_COMMAND} "--graphviz=foo.dot" .
    COMMAND dot -Tpng foo.dot -o foo.png
    WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
)

This way, the custom target runs the second command dot -Tpng foo.dot -o foo.png as well. You can output the image files anywhere on your system by pre-pending foo.png with a path of your choosing.

Upvotes: 16

languitar
languitar

Reputation: 6794

You could call CMake inside your script again, e.g. like:

add_custom_target(graphviz ALL
                  "${CMAKE_COMMAND}" "--graphviz=foo" .
                  WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")

Upvotes: 11

Related Questions