CMake:如何分辨传递依赖从何而来?

时间:2019-12-06 22:07:24

标签: cmake

我正在重写旧的CMake设置,以使用自动依赖项传播等现代功能。 (即使用target_include_directories(<target> PUBLIC <dir>)之类的东西代替include_directories(<dir>)。)当前,我们通过设置一堆全局目录属性来手动处理所有项目依赖项信息。

在测试中,我找到了一些示例,其中新版本中的目标将链接到旧版本中不会的库。我没有明确地链接到它,所以我知道这是来自目标的依赖关系,但是为了找到哪个(一个或多个)我必须递归查看项目的所有CMakeLists.txt,并跟进依赖层次结构,直到我找到一个拉入相关库的库为止。我们有几十个库,所以这不是一个简单的过程。

CMake是否提供任何方式查看每个目标的显式添加了哪些依赖关系,以及通过传递性依赖关系传播了哪些依赖关系?

看起来--graphviz输出确实表现出了这种区别,所以很明显CMake内部知道上下文。但是,我想编写一个类似tree的脚本来在命令行上显示依赖项信息,而解析Graphviz文件听起来既像噩梦,也像黑客一样。

据我所知,cmake-file-api不包含这些信息。我以为codemodel/target/dependencies字段可能有用,但是它列出了混合在一起的本地和传递依赖项。每个依赖项的backtrace字段仅与当前目标的add_executable / add_library调用相关。

1 个答案:

答案 0 :(得分:4)

您可以解析dot生成的graphviz文件并提取所需的详细信息。以下是执行此操作的示例python脚本。

import pydot
import sys

graph = pydot.graph_from_dot_file(sys.argv[1])
result = {}

for g in graph:
    # print(g)
    for node in g.get_node_list():
        if node.get("label") != None:
            result[node.get("label")] = []

    for edge in g.get_edges():
        result[g.get_node(edge.get_source())[0].get("label")].append(g.get_node(edge.get_destination())[0].get("label"))

for r in result:
    print(r+":"+",".join(result[r]))

您还可以添加此脚本以从cmake运行作为自定义目标,因此可以从构建系统中调用它。您可以找到示例cmake项目here