Я пытаюсь управлять своими зависимостями проекта C ++, используя CMake и gitsubmodules. Я следую за макетом, описанным здесь: http://foonathan.net/blog/2016/07/07/cmake-dependency-handling.html и он работал очень хорошо для меня на небольших проектах. Но я начал использовать его в гораздо больших проектах, и у меня возникли некоторые проблемы с CMake.
Все мои внешние зависимости сборки находятся в contrib/
подпапка внутри моего основного проекта. Каждый из них является субмодулем и имеет свой отдельный каталог.
/contrib
- /eigen
- /curl
- /leapserial
- /zlib
- /opencv
etc.
contrib/CMakeListst.txt
просто инициализирует подмодуль и добавляет подкаталог для каждой внешней зависимости
# EIGEN
execute_process(COMMAND git submodule update --recursive --init -- eigen
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# options..
add_subdirectory(eigen EXCLUDE_FROM_ALL)
# CURL
execute_process(COMMAND git submodule update --recursive --init -- curl
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Initialize cache with CMake build options..
add_subdirectory(curl EXCLUDE_FROM_ALL)
# LEAP SERIAL
execute_process(COMMAND git submodule update --recursive --init -- leapserial
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Initialize cache with CMake build options..
add_subdirectory(leapserial EXCLUDE_FROM_ALL)
# ZLIB
execute_process(COMMAND git submodule update --recursive --init -- zlib
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Initialize cache with CMake build options..
add_subdirectory(zlib EXCLUDE_FROM_ALL)
# OPENCV
execute_process(COMMAND git submodule update --recursive --init -- opencv
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Initialize cache with CMake build options..
add_subdirectory(opencv EXCLUDE_FROM_ALL)
Эта установка работала фантастически для меня:
CMakeListst.txt
тривиально. Так как у меня есть цель, у меня просто есть что-то вроде
add_executable(someProjectImWorkingOn
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp )
target_link_libraries(someProjectImWorkingOn
opencv_world
eigen
zlib
etc.)
Подкаталоги будут определять цели с тем же именем. В приведенном мной примере Eigen OpenCV, а также другая библиотека определяют цель удаления
Я пытался обновить
add_subdirectory(blah)
в
add_subdirectory(blah EXCLUDE_FROM_ALL)
но это не решает проблему по какой-то причине
Включение переменной ALLOW_DUPLICATE_CUSTOM_TARGETS
вроде работает .. но это хак, работать только с Make файлами, а библиотеки по сути все еще «перемешиваются», так что это все еще проблема
Вторая проблема появилась в LeapSerial, но иллюстрирует большую проблему. Проект больше не знает своего имени. LeapSerial попытался определить версию LeapSerial, но когда он запрашивает версию проекта, он получает версию корневого проекта. То есть. когда код cmake в подпроекте спрашивает «в каком я проекте», он получает корневой проект, а не непосредственный проект, в котором он находится.
Итак, опять же, родительское «пространство имен» протекает повсюду. Это должно создать все больше и больше проблем в будущем. Мне нужно, чтобы субмодули были автономными
Есть ли более чистое решение?
ExternalProjectAdd может решить некоторые из этих проблем, но имеет много больше собственных проблем. Это настоящий стартер, потому что он не делает большую часть того, что я перечислил. Центральная проблема заключается в том, что он не раскрывает цели подпроекта, а просто выдает переменные, которые вам затем приходится жонглировать.
Задача ещё не решена.
Других решений пока нет …