CMake: ¿Cómo saber de dónde viene la dependencia transitiva?

10

Estoy en el proceso de reescribir una configuración CMake heredada para usar características modernas como la propagación automática de dependencias. (es decir, usando cosas como en target_include_directories(<target> PUBLIC <dir>)lugar de include_directories(<dir>)). Actualmente, manejamos manualmente toda la información de dependencia del proyecto estableciendo un conjunto de propiedades de directorio global.

En mis pruebas, encontré algunos ejemplos en los que un destino en la nueva compilación se vinculará a una biblioteca que la compilación anterior no. No me estoy vinculando a él explícitamente, así que sé que esto proviene de las dependencias del objetivo, pero para encontrar cuál (es) tengo que mirar recursivamente a través de todos los proyectos CMakeLists.txt, siguiendo la jerarquía de dependencia hasta que encuentre uno que atrae a la biblioteca en cuestión. Tenemos docenas de bibliotecas, por lo que este no es un proceso trivial.

¿CMake proporciona alguna forma de ver, para cada objetivo, cuáles de sus dependencias se agregaron explícitamente y cuáles se propagaron a través de dependencias transitivas?

Parece que la --graphvizsalida hace mostrar esta distinción, tan claramente CMake conoce el contexto interno. Sin embargo, me gustaría escribir un treescript similar para mostrar información de dependencia en la línea de comando, y analizar archivos Graphviz suena como una pesadilla y un hack.

Por lo que yo puedo decir, cmake-file-apino no incluir esta información. Pensé que el codemodel/target/dependenciescampo podría funcionar, pero enumera las dependencias locales y transitivas mezcladas. Y el backtracecampo de cada dependencia solo se vincula con add_executable/ add_librarycall para el objetivo actual.

0x5453
fuente
1
¿Cómo la --graphizopción no responde a tu pregunta? ¿Por qué analizar archivos dot se siente como una pesadilla? Los archivos de puntos son la forma más simple, común y flexible de representar puntos conectados legibles por humanos. Con la gvprutilidad, puede hacer cualquier cosa con ellos al estilo awk-ish, y puede importarlos en otros idiomas. ¿Por qué es un archivo de puntos, que literalmente representa una estructura de dependencias en forma de árbol entre objetivos, no una "forma de ver" lo que pides?
KamilCuk
@KamilCuk Bastante justo. Creo que esperaba un formato más estandarizado como JSON que pudiera leer sin instalar paquetes adicionales y sin escribir mi propio analizador. Supuse que el gráfico de dependencia estaría disponible en varios formatos (todavía necesito experimentar con la API del servidor CMake , por ejemplo). Pero si los archivos de puntos son la forma más fácil (o única) de obtener esa información, está bien.
0x5453
1
No apostaría demasiadas apuestas en Graphviz mostrando esto de manera diferente. El código que lo distingue está vinculado aquí , no es muy sofisticado.
kert

Respuestas:

4

Puede analizar el dotarchivo generado por graphvizy extraer los detalles que desee. A continuación se muestra un script de Python de muestra para hacer eso.

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

También puede agregar este script para ejecutarlo desde cmake como destino personalizado, para que pueda llamarlo desde su sistema de compilación. Puede encontrar un ejemplo de proyecto cmake aquí

Manthan Tilva
fuente
Gracias por el ejemplo, tendré que investigar pydot.
0x5453