CMake: Wie kann man feststellen, woher die transitive Abhängigkeit kommt?

10

Ich bin gerade dabei, ein altes CMake-Setup neu zu schreiben, um moderne Funktionen wie die automatische Weitergabe von Abhängigkeiten zu verwenden. (dh mit Dingen wie target_include_directories(<target> PUBLIC <dir>)anstelle von include_directories(<dir>).) Derzeit verarbeiten wir alle Projektabhängigkeitsinformationen manuell, indem wir eine Reihe globaler Verzeichniseigenschaften festlegen.

Bei meinen Tests habe ich einige Beispiele gefunden, bei denen ein Ziel im neuen Build mit einer Bibliothek verknüpft wird, die im alten Build nicht vorhanden ist. Ich verlinke nicht explizit darauf, daher weiß ich, dass dies von den Abhängigkeiten des Ziels herrührt, aber um herauszufinden, welche davon ich rekursiv durch alle Projekte schauen muss, verfolge ich CMakeLists.txtdie Abhängigkeitshierarchie, bis ich sie finde eine, die in die fragliche Bibliothek zieht. Wir haben Dutzende von Bibliotheken, daher ist dies kein trivialer Prozess.

Bietet CMake eine Möglichkeit, für jedes Ziel zu sehen, welche seiner Abhängigkeiten explizit hinzugefügt wurden und welche durch transitive Abhängigkeiten weitergegeben wurden?

Es sieht aus wie der --graphvizAusgang macht diesen Unterschied zeigen, so klar CMake kennt den intern Kontext. Ich möchte jedoch ein treeähnliches Skript schreiben , um Abhängigkeitsinformationen in der Befehlszeile anzuzeigen, und das Parsen von Graphviz-Dateien klingt sowohl nach einem Albtraum als auch nach einem Hack.

Soweit ich das beurteilen kann, cmake-file-apiist nicht enthalten diese Informationen. Ich dachte, das codemodel/target/dependenciesFeld könnte funktionieren, aber es listet sowohl lokale als auch transitive Abhängigkeiten auf, die miteinander vermischt sind. Und das backtraceFeld jeder Abhängigkeit ist nur mit dem add_executable/ add_librarycall für das aktuelle Ziel verknüpft.

0x5453
quelle
1
Wie --graphizbeantwortet Option Ihre Frage nicht? Warum fühlt sich das Parsen von Punktdateien wie ein Albtraum an? Punktdateien sind die einfachste, gebräuchlichste und flexibelste Methode, um von Menschen lesbare verbundene Punkte darzustellen. Mit dem gvprDienstprogramm können Sie alles im awk-artigen Stil tun und sie in andere Sprachen importieren. Warum ist eine Punktdatei, die buchstäblich eine baumartige Struktur von Abhängigkeiten zwischen Zielen darstellt, keine "Möglichkeit, das zu sehen", wonach Sie fragen?
KamilCuk
@ KamilCuk Fair genug. Ich hoffte auf ein standardisierteres Format wie JSON, das ich lesen konnte, ohne zusätzliche Pakete zu installieren und ohne meinen eigenen Parser zu schreiben. Ich ging davon aus, dass das Abhängigkeitsdiagramm in mehreren Formaten verfügbar sein würde (ich muss beispielsweise noch mit der CMake-Server-API experimentieren ). Aber wenn Punktedateien der einfachste (oder einzige) Weg sind, diese Informationen zu erhalten, ist das in Ordnung.
0x5453
1
Ich würde nicht zu viele Wetten auf Graphviz setzen, die diese anders zeigen. Der Code, der es unterscheidet, ist hier verlinkt , es ist nicht sehr ausgefeilt.
kert

Antworten:

4

Sie können dotdie von generierte Datei analysieren graphvizund die gewünschten Details extrahieren. Unten finden Sie ein Beispiel für ein Python-Skript.

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

Sie können dieses Skript auch hinzufügen, um es von cmake als benutzerdefiniertes Ziel auszuführen, sodass Sie es von Ihrem Build-System aus aufrufen können. Ein Beispiel für ein cmake-Projekt finden Sie hier

Manthan Tilva
quelle
Danke für das Beispiel, ich muss mich darum kümmern pydot.
0x5453