使用 GRAPHVIZ_CUSTOM_TARGETS=TRUE 为自定义目标生成依赖关系图

Generate dependency graph for custom targets with GRAPHVIZ_CUSTOM_TARGETS=TRUE

(在底部更新工作解决方案)

据我所知,从 CMake 3.17 开始支持使用自定义目标生成依赖关系图。但是,当尝试这样做时,我的目标之间没有依赖关系映射,并且收到此警告:

CMake Warning:
  Manually-specified variables were not used by the project:

    GRAPHVIZ_CUSTOM_TARGETS

我偶然发现这个 answer, but it hasn't helped much. The next-closest thing I could find was an incomplete Merge Request 来支持一些不同的用例。

我在 Windows 上 运行,但我不知道这是否是问题所在。

所以,在我针对 KitWare 提出问题之前,我很困惑并且可以使用一些帮助...因为我认为我遗漏了一些非常明显的东西。任何帮助将不胜感激。

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
)

来自控制台的命令 运行,输出:

控制台输出:

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

最后,group.dot 文件:

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;
}
}

工作解决方案:

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")

文件列表输出:

group.dot
group.dot.bar
group.dot.foo
group.dot.bar.dependers
group.dot.bar.dependers

现在,我遇到的唯一问题是它似乎没有通过文件输出 link 依赖性,但这超出了这个问题的范围:)

在链接的 documentation 中,它指出:

The look and content of the generated graphs can be controlled using the file CMakeGraphVizOptions.cmake. This file is first searched in CMAKE_BINARY_DIR, and then in CMAKE_SOURCE_DIR. If found, the variables set in it are used to adjust options for the generated Graphviz files.

因此,不要在 cmake 命令行中设置 GRAPHVIZ_CUSTOM_TARGETS,而是将其设置在一个名为 CMakeGraphVizOptions.cmake 的文件中,并将此文件添加到您的 top-level 源目录中.

一个例子CMakeGraphVizOptions.cmake:

# This file sets some options to control GraphViz graphs.
set(GRAPHVIZ_GRAPH_NAME "MyGraph")
set(GRAPHVIZ_CUSTOM_TARGETS TRUE)