CMake: Как определить, откуда приходит транзитивная зависимость?

10

Я переписываю устаревшую настройку CMake, чтобы использовать современные функции, такие как автоматическое распространение зависимостей. (т.е. используя такие вещи, как target_include_directories(<target> PUBLIC <dir>)вместо include_directories(<dir>).) В настоящее время мы вручную обрабатываем всю информацию о зависимостях проекта, устанавливая набор глобальных свойств каталога.

В моем тестировании я обнаружил несколько примеров, когда цель в новой сборке будет ссылаться на библиотеку, а старая сборка - нет. Я не ссылаюсь на него явно, поэтому я знаю, что это происходит из зависимостей цели, но для того, чтобы выяснить, какие из них мне нужно рекурсивно просмотреть все проекты CMakeLists.txt, следуя иерархии зависимостей, пока не найду тот, который тянет в рассматриваемой библиотеке. У нас есть десятки библиотек, так что это не тривиальный процесс.

Предоставляет ли CMake какой-либо способ увидеть для каждой цели, какие из ее зависимостей были добавлены явно, а какие были распространены через транзитивные зависимости?

Похоже , что --graphvizвыход делает показать это различие, так ясно CMake знает контекст внутри. Тем не менее, я хотел бы написать treeподобный скрипт для отображения информации о зависимостях в командной строке, и анализ файлов Graphviz звучит как кошмар и взлом.

Насколько я могу судить, cmake-file-apiэто не включает эту информацию. Я думал, что codemodel/target/dependenciesполе может работать, но в нем перечислены как локальные, так и транзитивные зависимости, смешанные вместе. И backtraceполе каждой зависимости связывается только с вызовом add_executable/ add_libraryдля текущей цели.

0x5453
источник
1
Как --graphizвариант не ответить на ваш вопрос? Почему при разборе файлов с точками кажется кошмаром? Точечные файлы - это самый простой, распространенный и гибкий способ восприятия человеком связанных точек. С помощью gvprутилиты вы можете делать с ними все что угодно в стиле awk-ish и импортировать их на других языках. Почему точечный файл, который буквально представляет древовидную структуру зависимостей между целями, а не «способ увидеть» то, что вы просите?
KamilCuk
@ KamilCuk Справедливо достаточно. Я думаю, что надеялся на более стандартизированный формат, такой как JSON, который я мог бы читать без установки дополнительных пакетов и без написания собственного анализатора. Я предполагал, что граф зависимостей будет доступен в нескольких форматах (мне все еще нужно поэкспериментировать с API сервера CMake , например). Но если точечные файлы - это самый простой (или единственный) способ получить эту информацию, это нормально.
0x5453
1
Я бы не стал ставить слишком много ставок на Графвиз, показывающий это по-другому. Код, который рассказывает об этом отдельно , связан здесь , он не очень сложен.
Керт

Ответы:

4

Вы можете анализировать dotсгенерированный файл graphvizи извлекать детали, которые вы хотите. Ниже приведен пример скрипта Python для этого.

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

Вы также можете добавить этот скрипт для запуска из cmake как пользовательскую цель, чтобы вы могли вызывать его из вашей системы сборки. Вы можете найти образец проекта cmake здесь

Мантан Тилва
источник
Спасибо за пример, мне нужно разобраться pydot.
0x5453