Изоляция проектов gitsubmodule в CMake

Я пытаюсь управлять своими зависимостями проекта 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)

Эта установка работала фантастически для меня:

  1. Это не зависит от системы / менеджера пакетов. Вам не нужно устанавливать какие-либо библиотеки, чтобы начать разработку
  2. Я могу поддерживать точные версии моих зависимостей, устанавливая подмодуль для определенного коммита. Нет ничего удивительного в том, что какая-то внешняя библиотека сломала вашу сборку
  3. Добавление библиотек в мою сборку в корне CMakeListst.txt тривиально. Так как у меня есть цель, у меня просто есть что-то вроде

    add_executable(someProjectImWorkingOn
    ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp )
    target_link_libraries(someProjectImWorkingOn
    opencv_world
    eigen
    zlib
    etc.)
  4. когда вы присоединяете существующую библиотечную цель к своему собственному исполняемому файлу / библиотеке, CMake автоматически (через целевой интерфейс) автоматически добавит в вашу целевую директорию и добавит любые другие необходимые параметры, необходимые для использования библиотечной цели.
  5. Я могу выбрать toolchain / compiler-option / build-type в корне CMakeLists.txt, и он будет распространяться на все подпроекты (мне нужно собрать для нескольких систем. Так что это большая проблема)
  6. Поскольку все это в одном «мегапроекте», очень легко подключиться к rtags / kdevelop / clion для навигации не по собственному коду, а по коду библиотеки.

Некоторые проблемы, которые я не могу решить:

1

Подкаталоги будут определять цели с тем же именем. В приведенном мной примере Eigen OpenCV, а также другая библиотека определяют цель удаления

Я пытался обновить

add_subdirectory(blah)

в

add_subdirectory(blah EXCLUDE_FROM_ALL)

но это не решает проблему по какой-то причине

Включение переменной ALLOW_DUPLICATE_CUSTOM_TARGETS вроде работает .. но это хак, работать только с Make файлами, а библиотеки по сути все еще «перемешиваются», так что это все еще проблема

2

Вторая проблема появилась в LeapSerial, но иллюстрирует большую проблему. Проект больше не знает своего имени. LeapSerial попытался определить версию LeapSerial, но когда он запрашивает версию проекта, он получает версию корневого проекта. То есть. когда код cmake в подпроекте спрашивает «в каком я проекте», он получает корневой проект, а не непосредственный проект, в котором он находится.

Итак, опять же, родительское «пространство имен» протекает повсюду. Это должно создать все больше и больше проблем в будущем. Мне нужно, чтобы субмодули были автономными

Есть ли более чистое решение?

ExternalProjectAdd может решить некоторые из этих проблем, но имеет много больше собственных проблем. Это настоящий стартер, потому что он не делает большую часть того, что я перечислил. Центральная проблема заключается в том, что он не раскрывает цели подпроекта, а просто выдает переменные, которые вам затем приходится жонглировать.

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]