我正在重写旧的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
调用相关。
答案 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