Подтвердить что ты не робот

CMake: как лучше построить несколько (необязательных) подпроектов?

Представьте общий проект с несколькими компонентами:

  • Основной
  • ю
  • Веб
  • приложение-а
  • приложение-б
  • приложение-с

Теперь скажем, что сеть зависит от io, которая зависит от базового, и все эти вещи находятся в одном репо и имеют CMakeLists.txt для их создания в виде разделяемых библиотек.

Как мне настроить все, чтобы я мог создавать три приложения, если каждый из них является необязательным и может отсутствовать во время сборки?

Одна идея состоит в том, чтобы иметь пустой каталог "apps" в основном репо, и мы можем клонировать любое приложение, которое мы хотим в этом. Наш основной файл CMakeLists.txt может использовать GLOB для поиска всех каталогов приложений и их создания (не зная заранее, сколько из них будет). Проблемы с этим подходом включают:

  • Очевидно, что CMake не повторяет глобус, когда вы просто говорите make, поэтому, если вы добавляете новое приложение, вы должны снова запустить cmake.
  • Он налагает определенную структуру на человека, делающего сборку.
  • Не очевидно, как можно сделать два клона одного приложения и построить их как отдельно, так и с помощью одной и той же сборки библиотеки.

Общая концепция похожа на традиционный рекурсивный проект CMake, но там, где модули нижнего уровня не обязательно заранее знают, какие более высокоуровневые будут использовать их. Тем не менее, я не хочу требовать от пользователя устанавливать библиотеки нижнего уровня в фиксированном месте (например, /usr/local/lib). Однако я хочу, чтобы один вызов make замещал измененные зависимости по всему проекту, поэтому, если я создаю приложение, но изменил одну из низкоуровневых библиотек, все будет правильно перекомпилировано.

4b9b3361

Ответ 1

Я закончил тем, что я изложил в своем вопросе, который должен проверить пустой каталог (содержащий файл .gitignore, который игнорирует все), и сообщить CMake GLOB файлам любые каталоги (которые помещены туда пользователем), Тогда я могу просто сказать cmake myrootdir, и он найдет все различные компоненты. Это работает более или менее нормально. У этого есть некоторые побочные недостатки, хотя, например, некоторые сторонние инструменты, такие как BuildBot, ожидают более традиционную структуру проекта, которая упрощает интеграцию других инструментов с подобным расположением.

Ответ 2

Моя первая мысль заключалась в том, чтобы использовать функцию CMake импорт/экспорт цели.

Имейте CMakeLists.txt для basic, io и web и один файл CMakeLists.txt, который ссылается на них. Затем вы можете использовать функцию CMake экспорт для экспорта этих целей, а проекты приложений могут затем импортировать цели CMake.

Когда вы сначала создаете проект библиотеки, проекты приложений должны иметь возможность автоматически находить скомпилированные библиотеки (без того, чтобы библиотеки были установлены на /usr/local/lib), в противном случае всегда можно настроить правильную переменную CMake, чтобы указать правильный каталог.

В этом случае make в проекте приложения не будет делать make в проекте библиотеки, вам придется позаботиться об этом самостоятельно.

Ответ 3

У вас есть несколько CMakeLists.txt.

Многие проекты с открытым исходным кодом принимают эту оценку (LibOpenJPEG, LibPNG, poppler & etc). Взгляните на их CMakeLists.txt, чтобы узнать, как они это сделали.

В принципе, вы можете просто переключать функции по мере необходимости.

Ответ 4

Я вижу два дополнительных подхода. Один из них состоит в том, чтобы просто иметь базовые, io и web подмодули каждого приложения. Да, есть дублирование кода и потерянное пространство на диске, но его очень просто реализовать и гарантирует, что разные настройки компилятора для каждого приложения не будут мешать друг другу в общих библиотеках. Я полагаю, это делает библиотеки более не разделяемыми, но, возможно, это не должно быть большой проблемой в 2011 году. ОЗУ и диск стали дешевле, но времени на разработку нет, а обмен источниками, возможно, более переносим, ​​чем совместное использование двоичные файлы.

Другой подход - иметь макет, указанный в вопросе, и иметь файлы CMakeLists.txt в каждом подкаталоге. Файлы CMakeLists.txt в базовых, io и web генерируют автономные разделяемые библиотеки. Файлы CMakeLists.txt в каждом каталоге приложения вставляют в каждую общую библиотеку команду add_subdirectory(). Затем вы можете удалить все каталоги библиотек и любые нужные приложения и инициировать сборку из каждого каталога приложений.

Ответ 5

Инструмент CMake BASIS предоставляет утилиты, в которых вы можете создавать независимые модули проекта и выборочно включать и отключать их с помощью команды ccmake.

Полное раскрытие: Я разработчик проекта.