Mamy wiele repozytoriów Git, niektóre zawierają nasz własny kod, a niektóre zawierają nieco zmodyfikowany kod biblioteki strony trzeciej. Uproszczony wykres zależność wygląda następująco:Jak radzić sobie z przejściowym konfliktem zależności za pomocą modułów podrzędnych Git i CMake?
executable_A
| |
| v
| library_B
| |
v v
library_C
Więc wykonywalny ma dwie współzależności na library_C
jeden bezpośredni i jeden przechodni. Mam nadzieję związać to wszystko razem za pomocą submodules Git i CMake, więc uproszczona struktura katalogów wygląda następująco:
executable_A/
CMakeListst.txt
library_B/
CMakeLists.txt
library_C/
CMakeLists.txt
library_C/
CMakeLists.txt
Jak widać, repozytorium library_C
jest włączone jako modułem dwukrotnie. Załóżmy, że oba submoduły wskazują na ten sam commit (wszelkie pomysły na egzekwowanie, które byłyby mile widziane, ale nie są tematem tego pytania).
Używamy add_subdirectory
, target_link_libraries
i target_include_directories
do zarządzania tymi współzależnościami. Całkiem standardowe.
Problemem jest to, że CUpewnij nie lubi go, jeśli utworzyć cel o tej samej nazwie dwa razy, tak narzeka:
CUpewnij Błąd w library_C/CMakeLists.txt: 13 (add_library):
add_library nie można utworzyć obiektu docelowego "library_C", ponieważ inny obiekt docelowy o tej samej nazwie już istnieje. Istniejącym celem jest statyczna biblioteka utworzona w katalogu źródłowym ".../library_B/library_C".
Zobacz dokumentację zasad CMP0002, aby uzyskać więcej informacji.
Wolałbym nie usunąć bezpośrednią zależność executable_A
na library_C
, ponieważ fakt, że jest wciągany przez library_B
jest szczegółowo realizacja library_B
że nie powinno się powoływać. Co więcej, takie podejście zostanie przerwane, gdy tylko dodamy kolejną zależność, taką jak executable_A --> library_D --> library_C
.
(This question jest najbliżej udało mi się znaleźć, ale jest nieco bardziej ogólny i pozostaje bez odpowiedzi i tak.)
Dzięki. Mój mózg zrobił tam zły ruch. Edytowane. – Thomas
Powszechnym podejściem jest sprawdzenie, czy istnieje jakiś cel specyficzny dla projektu ('if (TARGET library_C)') przed wkroczeniem do projektu za pomocą 'add_subdirectory()'. – Tsyvarev
@Tsyvarev 'if (NOT TARGET library_c)', oczywiście.Brzmi jak realistyczne podejście. Chcesz umieścić go jako odpowiedź? – Thomas