CMake: Jak stwierdzić, skąd pochodzi zależność przechodnia?

10

Jestem w trakcie przepisywania starszej konfiguracji CMake, aby korzystać z nowoczesnych funkcji, takich jak automatyczne propagowanie zależności. (tj. używając rzeczy takich jak target_include_directories(<target> PUBLIC <dir>)zamiast include_directories(<dir>).) Obecnie ręcznie obsługujemy wszystkie informacje o zależnościach projektu, ustawiając kilka globalnych właściwości katalogu.

Podczas moich testów znalazłem kilka przykładów, w których cel w nowej kompilacji będzie łączył się z biblioteką, której nie zbudowałaby stara kompilacja. Nie łączę się z tym wprost, więc wiem, że wynika to z zależności celu, ale aby znaleźć, które muszę rekurencyjnie przeglądać wszystkie projekty CMakeLists.txt, śledząc hierarchię zależności, aż znajdę taki, który pobiera daną bibliotekę. Mamy dziesiątki bibliotek, więc nie jest to trywialny proces.

Czy CMake umożliwia sprawdzenie, dla każdego celu, które z jego zależności zostały dodane wprost, a które propagowane przez zależności przechodnie?

Wygląda na to --graphvizwyjście ma pokazać tę różnicę, więc wyraźnie CUpewnij zna kontekst wewnętrznie. Chciałbym jednak napisać treepodobny skrypt, aby wyświetlić informacje o zależnościach w wierszu poleceń, a analiza plików Graphviz brzmi zarówno jak koszmar, jak i hack.

O ile mogę powiedzieć, cmake-file-apiczy nie zawierają tej informacji. Myślałem, że to codemodel/target/dependenciespole może działać, ale zawiera zarówno mieszanki lokalne, jak i przechodnie. A backtracepole każdej zależności wiąże się tylko z add_executable/ add_librarycall dla bieżącego celu.

0x5453
źródło
1
Jak --graphizopcja nie odpowiada na twoje pytanie? Dlaczego parsowanie plików kropek wydaje się koszmarem? Pliki kropkowe to najprostszy, powszechny i ​​elastyczny sposób na czytelne dla człowieka reprezentowanie połączonych punktów. Za pomocą gvprnarzędzia możesz robić z nimi wszystko w stylu awk-ish, a także importować je w innych językach. Dlaczego plik kropkowy, który dosłownie przedstawia drzewną strukturę zależności między celami, a nie „sposób zobaczenia” tego, o co prosisz?
KamilCuk,
@KamilCuk Do przyjęcia. Myślę, że liczyłem na bardziej znormalizowany format, taki jak JSON, który mógłbym odczytać bez instalowania dodatkowych pakietów i bez pisania własnego parsera. Zakładałem, że wykres zależności będzie dostępny w wielu formatach (na przykład nadal muszę eksperymentować z interfejsem API serwera CMake ). Ale jeśli pliki kropkowe są najłatwiejszym (lub jedynym) sposobem na uzyskanie tych informacji, nie ma sprawy.
0x5453,
1
Nie postawiłbym zbyt wielu zakładów na Graphviz, pokazując je inaczej. Kod, który odróżnia go od siebie, jest tutaj połączony , nie jest bardzo skomplikowany.
kert

Odpowiedzi:

4

Możesz przeanalizować dotplik wygenerowany przez graphvizi wyodrębnić szczegóły, które chcesz. Poniżej znajduje się przykładowy skrypt Pythona, aby to zrobić.

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

Możesz także dodać ten skrypt, aby uruchamiał się z cmake jako niestandardowy cel, dzięki czemu można go wywoływać z poziomu kompilacji systemu. Można znaleźć przykładowy projekt cmake tutaj

Manthan Tilva
źródło
Dzięki za przykład, będę musiał zajrzeć pydot.
0x5453,