CMake: Como saber de onde vem a dependência transitiva?

10

Estou reescrevendo uma instalação herdada do CMake para usar recursos modernos, como a propagação automática de dependências. (ou seja, usando coisas como em target_include_directories(<target> PUBLIC <dir>)vez de include_directories(<dir>).) Atualmente, lidamos manualmente com todas as informações de dependência do projeto, definindo várias propriedades de diretório global.

Nos meus testes, encontrei alguns exemplos em que um destino na nova compilação será vinculado a uma biblioteca que a compilação antiga não faria. Não estou vinculando-o explicitamente, portanto, sei que isso é proveniente das dependências do destino, mas, para descobrir qual delas, preciso procurar recursivamente todos os projetos CMakeLists.txt, acompanhando a hierarquia de dependências até encontrar um que puxa a biblioteca em questão. Como temos dezenas de bibliotecas, esse processo não é trivial.

O CMake fornece alguma maneira de ver, para cada destino, quais de suas dependências foram adicionadas explicitamente e quais foram propagadas por dependências transitivas?

Parece que a --graphvizsaída não mostrar esta distinção, tão claramente CMake conhece o contexto internamente. No entanto, eu gostaria de escrever um treescript semelhante para mostrar informações de dependência na linha de comando, e analisar os arquivos Graphviz parece um pesadelo e um hack.

Tanto quanto eu posso dizer, cmake-file-apié que não incluem esta informação. Eu pensei que o codemodel/target/dependenciescampo poderia funcionar, mas lista as dependências locais e transitivas misturadas. E o backtracecampo de cada dependência apenas se vincula à chamada add_executable/ add_librarypara o destino atual.

0x5453
fonte
11
Como a --graphizopção não responde à sua pergunta? Por que analisar arquivos de ponto parece um pesadelo? Os arquivos de ponto são a maneira mais simples, comum e flexível de representar pontos conectados, legíveis por humanos. Com o gvprutilitário, você pode fazer qualquer coisa com eles no estilo awk-ish e importá-los para outros idiomas. Por que um arquivo de ponto, que literalmente representa uma estrutura em árvore de dependências entre destinos, não é uma "maneira de ver" o que você pede?
KamilCuk
@KamilCuk Fair suficiente. Eu acho que esperava um formato mais padronizado como JSON que pudesse ler sem instalar pacotes adicionais e sem escrever meu próprio analisador. Supus que o gráfico de dependência estivesse disponível em vários formatos (ainda preciso experimentar a API do servidor CMake , por exemplo). Mas se os dotfiles são a maneira mais fácil (ou única) de obter essas informações, tudo bem.
0x5453
11
Eu não apostaria muitas apostas no Graphviz mostrando isso de forma diferente. O código que o diferencia está vinculado aqui , não é muito sofisticado.
kert

Respostas:

4

Você pode analisar o dotarquivo gerado graphvize extrair os detalhes desejados. Abaixo está um exemplo de script python para fazer isso.

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

Você também pode adicionar esse script para executar a partir do cmake como destino personalizado, para poder chamá-lo do seu sistema de construção. Você pode encontrar um exemplo de projeto cmake aqui

Manthan Tilva
fonte
Obrigado pelo exemplo, vou ter que investigar pydot.
0x5453