Saya penggemar berat sub-modul Git . Saya ingin dapat melacak dependensi bersama dengan versinya, sehingga Anda dapat memutar kembali ke versi sebelumnya dari proyek Anda dan memiliki versi dependensi yang sesuai untuk dibangun dengan aman dan bersih. Selain itu, lebih mudah untuk merilis perpustakaan kami sebagai proyek sumber terbuka karena sejarah untuk perpustakaan terpisah dari aplikasi yang bergantung padanya (dan yang tidak akan bersumber terbuka).
Saya sedang menyiapkan alur kerja untuk beberapa proyek di tempat kerja, dan saya bertanya-tanya bagaimana jadinya jika kita mengambil pendekatan ini sedikit ekstrem daripada memiliki proyek monolitik tunggal. Saya segera menyadari ada potensi cacing dalam benar - benar menggunakan sub-modul.
Misalkan sepasang aplikasi: studio
dan player
, dan perpustakaan bergantung core
, graph
dan network
, di mana dependensi adalah sebagai berikut:
core
adalah standalonegraph
tergantung padacore
(sub-modul di./libs/core
)network
depdends oncore
(sub-module at./libs/core
)studio
tergantung padagraph
dannetwork
(sub-modul di./libs/graph
dan./libs/network
)player
tergantung padagraph
dannetwork
(sub-modul di./libs/graph
dan./libs/network
)
Misalkan kita menggunakan CMake dan masing-masing proyek ini memiliki unit test dan semua pekerjaan. Setiap proyek (termasuk studio
dan player
) harus dapat dikompilasi mandiri untuk melakukan metrik kode, pengujian unit, dll.
Masalahnya adalah, rekursif git submodule fetch
, maka Anda mendapatkan struktur direktori berikut:
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/graph/
studio/libs/graph/libs/ (sub-module depth: 2)
studio/libs/graph/libs/core/
studio/libs/network/
studio/libs/network/libs/ (sub-module depth: 2)
studio/libs/network/libs/core/
Perhatikan bahwa core
dikloning dua kali dalam studio
proyek. Selain dari pemborosan ruang disk ini, saya memiliki masalah sistem pembangunan karena saya membangun core
dua kali dan saya berpotensi mendapatkan dua versi yang berbeda core
.
Pertanyaan
Bagaimana saya mengatur sub-modul sehingga saya mendapatkan dependensi versi dan pembuatan mandiri tanpa mendapatkan banyak salinan sub-modul bersarang yang umum?
Solusi yang mungkin
Jika ketergantungan perpustakaan agak dari saran (yaitu dalam mode "diketahui bekerja dengan versi X" atau "hanya versi X yang didukung secara resmi") dan aplikasi atau perpustakaan yang bergantung pada potensial bertanggung jawab untuk membangun dengan versi apa pun yang mereka sukai, maka Saya bisa membayangkan skenario berikut:
- Siapkan sistem build untuk
graph
dannetwork
beri tahu mereka di mana menemukannyacore
(mis. Via path compiler include). Tetapkan dua target build, "standalone" dan "dependency", di mana "standalone" didasarkan pada "dependency" dan tambahkan path include untuk menunjuk kecore
sub-modul lokal . - Memperkenalkan ketergantungan ekstra:
studio
padacore
. Kemudian,studio
buildcore
, atur path include ke salinancore
sub-modulnya sendiri, kemudian buildgraph
dannetwork
dalam mode "dependensi".
Struktur folder yang dihasilkan terlihat seperti:
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/core/
studio/libs/graph/
studio/libs/graph/libs/ (empty folder, sub-modules not fetched)
studio/libs/network/
studio/libs/network/libs/ (empty folder, sub-modules not fetched)
Namun, ini memerlukan beberapa keajaiban sistem bangun (saya cukup yakin ini dapat dilakukan dengan CMake) dan sedikit pekerjaan manual pada bagian pembaruan versi (pembaruan graph
mungkin juga memerlukan pembaruan core
dan network
untuk mendapatkan versi yang kompatibel core
di semua proyek) .
Ada pemikiran tentang ini?
sumber
Jawaban:
Saya sangat terlambat ke pesta ini, tetapi pertanyaan Anda sepertinya belum memiliki jawaban yang lengkap, dan ini adalah hit yang cukup menonjol dari google.
Saya memiliki masalah yang sama persis dengan C ++ / CMake / Git / Submodules dan saya memiliki masalah yang sama dengan MATLAB / Git / Submodules, yang mendapat beberapa keanehan ekstra karena MATLAB tidak dikompilasi. Saya menemukan video ini baru-baru ini, yang tampaknya mengusulkan "solusi". Saya tidak suka solusinya, karena pada dasarnya itu berarti membuang submodula, tetapi itu menghilangkan masalah. Ini seperti yang direkomendasikan @errordeveloper. Setiap proyek tidak memiliki submodula. Untuk membangun proyek, buat proyek super untuk membangunnya, dan sertakan itu sebagai saudara kandung dari ketergantungannya.
Jadi proyek Anda untuk pengembangan
graph
mungkin terlihat seperti:dan kemudian proyek Anda untuk studio dapat:
Super-proyek hanya utama
CMakeLists.txt
dan banyak submodul. Tetapi tidak ada proyek yang memiliki submodula sendiri.Satu-satunya biaya yang saya lihat untuk pendekatan ini adalah proliferasi "proyek super" sepele yang hanya didedikasikan untuk membangun proyek nyata Anda. Dan jika seseorang menguasai salah satu proyek Anda, tidak ada cara mudah untuk mengetahui tanpa menemukan proyek super juga, apa dependensinya. Itu mungkin membuatnya duduk sangat jelek di Github, misalnya.
sumber
Saya kira ketika Anda mengintegrasikan keduanya
graph
dannetwork
submodul ke dalamstudio
, Anda harus selalu memiliki versi yang samacore
pada waktu tertentu dalam sejarahstudio
. Saya akan simlinkstudio/libs/core
submodule kestudio/libs/{graph,network}/libs
.Memperbarui:
Saya membuat beberapa repositori dengan dependensi yang Anda nyatakan:
v1
danv2
dua versi berbedacore
.graph
menangani versi 2, sedangkannetwork
membutuhkan beberapa pekerjaan dan terjebak pada versi 1. Dalamstudio
, versi lokal yang disematkancore
kedua titikv1
untuk memiliki program yang berfungsi. Sekarang, terlepas dari perspektif build, semuanya bekerja dengan baik dengan submodul.Sekarang saya dapat menghapus direktori berikut:
Dan ganti dengan tautan simbolis:
Saya melakukan perubahan ini secara lokal dan kehilangan kemampuan untuk memiliki dua versi
core
di dalam yang terpisahstudio
, tetapi saya hanya membanguncore
satu kali. Ketika saya siap untuk meningkatkanv2
, saya dapat melakukan:... di dalam studio / libs / jaringan.
sumber
graph/libs/core
luar, Anda tidak menggunakan submodule. Jika Anda menautkan daristudio/libs/core
ke salah satu perpustakaan sub-modul itu sendiri, lalu yang mana yang Anda pilih,graph
ataunetwork
? Selain itu, apa yang terjadi ketika kedalamannya tiga atau lebih? Akhirnya, bagaimana jikacore
bisa berbagai revisi. Tidak jelas bahwa Anda ingin menautkan ke salah satu versicore
itugraph
dannetwork
menggunakan.core
akan menjadi submodule yang diambil daricore
perpustakaan asli , diperbarui ke versi yang kompatibel untuk keduanyagraph
dannetwork
(Anda harus memutuskan mana yang baik). Tautan simbolis akan ditambahkan di lokalgraph
dannetwork
submodula (tidak dibuat).graph
dannetwork
akan menunjukkan di luar repositori mereka sendiri (misalnya di tempat lain dalamstudio
proyek). Bagaimana mereka tahu kapan harus menggunakan sub-modul mereka sendiri versus kapan harus menggunakan tautan simbolik? Mungkin Anda harus menambahkan contoh untuk menunjukkan cara berpikir Anda.Saya akan meratakannya untuk memiliki kedalaman sub-modul hanya satu dan memiliki repositori yang akan menampung semua modul sebagai sub-modul dan tidak ada yang lain selain dari README dan skrip build. Akan ada skrip build terpisah untuk setiap paket yang menghubungkan dependensinya. Kalau tidak, Anda dapat memiliki repo terpisah untuk suatu paket.
sumber
Saya tidak akan menggunakan submodula.
Ini menggoda, sama seperti dulu dengan svn-eksternal. Namun, dapatkah Anda yakin semua proyek yang Anda tautkan masih berada di tempat yang sama dalam setahun? Bagaimana dengan lima?
Oleh karena itu, saya hanya menyalin semua dependensi yang diperlukan ke proyek saya. Ini berarti bahwa selama repo saya valid, saya dapat memeriksa keadaan yang sebenarnya.
Pada dasarnya, saya memiliki struktur folder sebagai berikut:
Meskipun ini tidak terlalu bagus dari perspektif ruang disk, saya menghargai jaminan bahwa saya dapat memeriksa setiap negara yang tercatat selama repo tersedia jauh lebih tinggi.
Selain itu, ada banyak masalah dengan submodul seperti yang dijelaskan di sini
sumber
Menghadapi masalah yang sama persis di sini. Salah satu solusi bisa memiliki beberapa repo
libs
yang akan teruscore
,network
,graph
sebagai submodul dan hanya CMakeLists yang akan memberitahu setiap libs di mana untuk menemukan dependensinya. Setiap aplikasi sekarang akan memilikilibs
submodule dan hanya menggunakan lib yang diperlukan.Pengujian setiap lib dapat diatur dalam 2 cara:
sumber
graph
tidak perlu tahu tentangnetwork
- jangannetwork
lewatkan hal-hal yang berhubungan dengangraph
subdir