【问题标题】:CMake: How to tell where transitive dependency is coming from?CMake:如何判断传递依赖的来源?
【发布时间】:2019-12-18 15:42:55
【问题描述】:

我正在重写旧版 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 调用相关联。

【问题讨论】:

  • --graphiz 选项怎么不能回答你的问题?为什么解析点文件感觉就像一场噩梦?点文件是人类可读的表示连接点的最简单、通用和灵活的方法。使用 gvpr 实用程序,您可以以 awk 风格对它们进行任何操作,并且可以将它们导入其他语言。为什么是一个点文件,它从字面上表示目标之间依赖关系的树状结构,而不是您所要求的“查看方式”?
  • @KamilCuk 够公平的。我想我希望有一种更标准化的格式,比如 JSON,我可以在不安装额外包和编写自己的解析器的情况下读取它。我假设依赖关系图将以多种格式提供(例如,我仍然需要尝试CMake server API)。但是,如果点文件是获取该信息的最简单(或唯一)方法,那很好。
  • 我不会在 Graphviz 上押太多赌注来显示这些不同。区分它的代码is linked here,不是很复杂。

标签: cmake


【解决方案1】:

您可以解析graphviz 生成的dot 文件并提取您想要的详细信息。下面是执行此操作的示例 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

【讨论】:

  • 谢谢你的例子,我得看看pydot
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 2020-03-30
  • 1970-01-01
  • 2017-01-15
  • 1970-01-01
  • 2018-07-06
相关资源
最近更新 更多