CMake: Come capire da dove proviene la dipendenza transitiva?


10

Sto riscrivendo un'installazione CMake legacy per utilizzare funzionalità moderne come la propagazione automatica delle dipendenze. (cioè usando cose come target_include_directories(<target> PUBLIC <dir>)invece di include_directories(<dir>).) Attualmente gestiamo manualmente tutte le informazioni sulla dipendenza del progetto impostando un gruppo di proprietà della directory globale.

Nei miei test, ho trovato alcuni esempi in cui un target nella nuova build si collegherà a una libreria che la vecchia build non avrebbe. Non sto collegando esplicitamente ad esso, quindi so che questo proviene dalle dipendenze del target, ma per trovare quale (i) devo guardare ricorsivamente attraverso tutti i progetti CMakeLists.txt, seguendo la gerarchia delle dipendenze fino a quando non trovo uno che tira dentro la libreria in questione. Abbiamo dozzine di librerie, quindi questo non è un processo banale.

CMake fornisce un modo per vedere, per ciascun target, quali delle sue dipendenze sono state aggiunte esplicitamente e quali sono state propagate attraverso dipendenze transitive?

Sembra che l' --graphvizuscita non mostrare questa distinzione, così chiaramente CMake conosce il contesto internamente. Tuttavia, vorrei scrivere uno treescript simile per mostrare le informazioni sulla dipendenza dalla riga di comando e l'analisi dei file Graphviz sembra sia un incubo che un hack.

Per quanto posso dire, cmake-file-apinon senza includere queste informazioni. Pensavo che il codemodel/target/dependenciescampo potesse funzionare, ma elenca dipendenze sia locali che transitive mescolate insieme. E il backtracecampo di ciascuna dipendenza si ricollega solo alla add_executable/ add_librarycall per l'obiettivo corrente.


1
In che modo l' --graphizopzione non risponde alla tua domanda? Perché analizzare i file di punti sembra un incubo? I file Dot sono il modo più semplice, comune e flessibile per rappresentare i punti collegati leggibili dall'uomo. Con l' gvprutilità puoi fare qualsiasi cosa con loro in stile awk-ish e puoi importarli in altre lingue. Perché un file dot, che rappresenta letteralmente una struttura ad albero di dipendenze tra target, non un "modo di vedere" che quello che chiedi?
KamilCuk,

@KamilCuk Abbastanza giusto. Penso che speravo in un formato più standardizzato come JSON che potessi leggere senza installare pacchetti aggiuntivi e senza scrivere il mio parser. Ho ipotizzato che il grafico delle dipendenze fosse disponibile in più formati (ad esempio, devo ancora sperimentare l' API del server CMake ). Ma se i dotfile sono il modo più semplice (o unico) per ottenere tali informazioni, va bene.
0x5453,

1
Non scommetterei troppe scommesse su Graphviz mostrandole in modo diverso. Il codice che lo distingue è collegato qui , non è molto sofisticato.
kert,

Risposte:


4

È possibile analizzare il dotfile generato da graphvized estrarre i dettagli desiderati. Di seguito è riportato un esempio di script Python per farlo.

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

Puoi anche aggiungere questo script per eseguirlo da cmake come destinazione personalizzata, in modo da poterlo chiamare dal tuo sistema di compilazione. Puoi trovare un esempio di progetto cmake qui


Grazie per l'esempio, dovrò esaminare pydot.
0x5453,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.