CMake:如何判断传递依赖来自哪里?

0x5*_*453 10 cmake

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

在我的测试中,我发现了一些示例,其中新构建中的目标将链接到旧构建不会链接到的库。我没有明确链接到它,所以我知道这是来自目标的依赖项,但为了找到哪个(s)我必须递归查看项目的所有CMakeLists.txts,跟踪依赖关系层次直到我找到一个拉入有问题的图书馆。我们有几十个库,所以这不是一个简单的过程。

CMake 是否提供任何方法来查看每个目标明确添加了哪些依赖项,以及通过传递依赖项传播了哪些依赖项?

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

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

Man*_*lva 6

您可以解析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]))
Run Code Online (Sandbox Code Playgroud)

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