CMake: Bagaimana cara mengetahui dari mana ketergantungan transitif berasal?

10

Saya sedang dalam proses menulis ulang pengaturan CMake lama untuk menggunakan fitur-fitur modern seperti propagasi ketergantungan otomatis. (Yaitu menggunakan hal-hal seperti target_include_directories(<target> PUBLIC <dir>)bukaninclude_directories(<dir>) .) Saat ini, kami secara manual menangani semua informasi ketergantungan proyek dengan mengatur sekelompok properti direktori global.

Dalam pengujian saya, saya telah menemukan beberapa contoh di mana target dalam membangun baru akan menautkan ke perpustakaan yang tidak dibangun oleh yang lama. Saya tidak menghubungkannya secara eksplisit, jadi saya tahu ini berasal dari dependensi target, tetapi untuk menemukan yang mana saya harus secara rekursif melihat semua proyek.CMakeLists.txt , menindaklanjuti hierarki dependensi sampai saya menemukan salah satu yang menarik di perpustakaan yang dimaksud. Kami memiliki lusinan perpustakaan sehingga ini bukan proses yang sepele.

Apakah CMake menyediakan cara untuk melihat, untuk setiap target, mana dari dependensinya yang ditambahkan secara eksplisit, dan mana yang diperbanyak melalui dependensi transitif?

Sepertinya --graphvizoutput memang menunjukkan perbedaan ini, jadi jelas CMake tahu konteksnya secara internal. Namun, saya ingin menulis treeskrip mirip untuk menampilkan informasi ketergantungan pada baris perintah, dan mem-parsing file Graphviz terdengar seperti mimpi buruk dan peretasan.

Sejauh yang saya tahu, cmake-file-apitidak tidak termasuk informasi ini. Saya pikir codemodel/target/dependenciesbidang ini mungkin berfungsi, tetapi daftar dependensi lokal dan transitif dicampur bersama. Dan backtracebidang masing-masing ketergantungan hanya mengikat kembali ke add_executable/ add_librarypanggilan untuk target saat ini.

0x5453
sumber
1
Bagaimana --graphizopsi tidak menjawab pertanyaan Anda? Mengapa parsing file dot terasa seperti mimpi buruk? File dot adalah cara paling sederhana, umum dan fleksibel untuk mewakili titik terhubung yang dapat dibaca manusia. Dengan gvprutilitas Anda dapat melakukan apa saja dengan mereka dalam gaya awk-ish, dan Anda dapat mengimpornya dalam bahasa lain. Mengapa file titik, yang secara harfiah mewakili struktur dependensi mirip pohon di antara target, bukan "cara untuk melihat" yang Anda minta?
KamilCuk
@ KamilCuk Cukup adil. Saya pikir saya berharap untuk format yang lebih standar seperti JSON yang bisa saya baca tanpa menginstal paket tambahan dan tanpa menulis parser saya sendiri. Saya berasumsi bahwa grafik dependensi akan tersedia dalam berbagai format (misalnya, saya masih perlu bereksperimen dengan API server CMake ). Tetapi jika dotfile adalah cara termudah (atau satu-satunya) untuk mendapatkan informasi itu, itu tidak masalah.
0x5453
1
Saya tidak akan mempertaruhkan terlalu banyak taruhan pada Graphviz yang menunjukkan ini secara berbeda. Kode yang membedakannya terhubung di sini , tidak terlalu canggih.
kert

Jawaban:

4

Anda dapat mem-parsing dotfile yang dihasilkan oleh graphvizdan mengekstrak detail yang Anda inginkan. Di bawah ini adalah contoh skrip python untuk melakukan itu.

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

Anda juga dapat menambahkan skrip ini untuk dijalankan dari cmake sebagai target khusus, sehingga Anda dapat memanggilnya dari sistem build Anda. Anda dapat menemukan contoh proyek cmake di sini

Manthan Tilva
sumber
Terima kasih untuk contohnya, saya harus memeriksanya pydot.
0x5453