CMake: как лучше создать несколько (необязательных) подпроектов? - PullRequest
20 голосов
/ 23 июня 2011

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

  • basic
  • io
  • web
  • app-a
  • app-b
  • app-c

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

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

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

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

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

Ответы [ 6 ]

4 голосов
/ 15 ноября 2011

Моей первой мыслью было использование функции CMake import / export target .

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

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

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

2 голосов
/ 03 ноября 2011

иметь несколько CMakeLists.txt.

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

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

1 голос
/ 12 июля 2018

Вы можете использовать ADD_SUBDIRECTORY для этого!

https://cmake.org/cmake/help/v3.11/command/add_subdirectory.html

1 голос
/ 22 ноября 2011

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

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

0 голосов
/ 25 февраля 2014

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

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

0 голосов
/ 14 сентября 2012

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

...