CMake: Comment savoir d'où vient la dépendance transitive?

10

Je suis en train de réécrire une configuration CMake héritée pour utiliser des fonctionnalités modernes comme la propagation automatique des dépendances. (c'est-à-dire en utilisant des choses comme target_include_directories(<target> PUBLIC <dir>)au lieu de include_directories(<dir>).) Actuellement, nous traitons manuellement toutes les informations de dépendance du projet en définissant un tas de propriétés de répertoire global.

Lors de mes tests, j'ai trouvé quelques exemples où une cible dans la nouvelle version sera liée à une bibliothèque que l'ancienne version ne ferait pas. Je n'y suis pas lié explicitement, donc je sais que cela vient des dépendances de la cible, mais afin de trouver celles que je dois parcourir récursivement à travers tous les projets CMakeLists.txt, en suivant la hiérarchie des dépendances jusqu'à ce que je trouve celui qui tire dans la bibliothèque en question. Nous avons des dizaines de bibliothèques, ce n'est donc pas un processus trivial.

CMake fournit-il un moyen de voir, pour chaque cible, lesquelles de ses dépendances ont été ajoutées explicitement et lesquelles ont été propagées via des dépendances transitives?

Il semble que la --graphvizsortie ne montre cette distinction, si clairement CMake connaît le contexte interne. Cependant, je voudrais écrire un treescript de type similaire pour afficher les informations de dépendance sur la ligne de commande, et l'analyse des fichiers Graphviz sonne à la fois comme un cauchemar et un hack.

Pour autant que je sache, cmake-file-apine comprend pas ces informations. Je pensais que le codemodel/target/dependencieschamp pourrait fonctionner, mais il répertorie les dépendances locales et transitives mélangées ensemble. Et le backtracechamp de chaque dépendance n'est lié qu'à l' appel add_executable/ add_libraryde la cible actuelle.

0x5453
la source
1
Comment l' --graphizoption ne répond-elle pas à votre question? Pourquoi analyser des fichiers dot ressemble à un cauchemar? Les fichiers de points sont le moyen le plus simple, commun et flexible de représenter des points connectés lisibles par l'homme. Avec l' gvprutilitaire, vous pouvez faire n'importe quoi avec eux dans un style awk-ish, et vous pouvez les importer dans d'autres langues. Pourquoi un fichier de points, qui représente littéralement une structure arborescente de dépendances entre les cibles, pas une "façon de voir" ce que vous demandez?
KamilCuk
@KamilCuk Assez juste. Je pense que j'espérais un format plus standardisé comme JSON que je pourrais lire sans installer de packages supplémentaires et sans écrire mon propre analyseur. J'ai supposé que le graphique de dépendance serait disponible dans plusieurs formats (j'ai encore besoin d'expérimenter avec l' API du serveur CMake , par exemple). Mais si les fichiers dot sont le moyen le plus simple (ou unique) d'obtenir ces informations, c'est bien.
0x5453
1
Je ne miserais pas trop de paris sur Graphviz en les montrant différemment. Le code qui le différencie est lié ici , ce n'est pas très sophistiqué.
kert

Réponses:

4

Vous pouvez analyser le dotfichier généré par graphvizet extraire les détails que vous souhaitez. Voici un exemple de script python pour le faire.

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

Vous pouvez également ajouter ce script à exécuter à partir de cmake en tant que cible personnalisée, afin de pouvoir l'appeler à partir de votre système de génération. Vous pouvez trouver un exemple de projet cmake ici

Manthan Tilva
la source
Merci pour l'exemple, je vais devoir examiner pydot.
0x5453