Пишу кроссплатформенный проект на С++. Так как CMake дефакто является стандартом для кроссплатформенных решений, проект использует CMake. Раньше добавлял зависимости - сторонние библиотеки - предварительно собирая их вручную в отдельной папке и потом копируя в структуру проекта либо перенося сторонние исходники в код напрямую. Однако при очередной сборке очередной версии сторонней библиотеки надоело - решил организовать всё по уму, через механизм пакетов (FIND_PACKAGE и иже с ним).
Набросал желаемую структуру проекта в первой итерации:
Структура проектаpackages_test
|-- .git
|-- build // Результат сборки
| |-- details // Папка для сборки, тут всякий временный хлам (make-файлы, .o-файлы, и проч.)
| |-- res.exe // Исполняемый файл
| |-- . . . // Ресурсы (необходимые .dll/.so, контент, и т.д.)
|-- CMakeLists.txt // Конфигурация сборки проекта
|-- main.cpp // Точка входа, main()
|-- . . . // Прочие файлы проекта
|--dependencies // Зависимости (подключаются через механизм submodule)
. |--vendor_package_0 // У каждой зависимости своя внутренняя организация
. |--vendor_package_1
. |-- . . .
Начал писать CMake-файл для проекта, но столкнулся с трудностями. Вот текущий CMake-файл:
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(playrix_entrance_test)
# ------------------------ Настройка зависимостей -----------------------------
# Переменная для хранения пути к папке, в которой лежат зависимости
set(DEPENDENCIES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies")
# - - - - - - - - - - - - - Настройка библиотеки assimp - - - - - - - - - - - - - - -
# Тут может быть любая сторонняя библиотека. Указываю реально
# подключаемую чтобы подчеркнуть, что детали подключения каждой
# зависимости могут отличаться - минимум потому, что нет стандарта
# структуры проектов, использующих CMake
# Добавление папки с find-модулями CMake для assimp
# Это нужно чтобы find_package(...) смог извлечь информацию об assimp
list(APPEND CMAKE_MODULE_PATH "${DEPENDENCIES_DIR}/assimp/cmake-modules")
# Импорт переменных, описывающих пакет assimp. Данная команда
# создаёт всякие переменные с расположением заголовочных файлов пакета,
# расположением самого файла библиотеки ({.dll/.so} + .lib/.a), информацию
# о результате поиска пакета, и проч., однако не выполняет сборку пакета
find_package(assimp REQUIRED)
# Неизвестный код для сборки assimp
# ??? >>> add_subdirectory() <<< ???
# ??? >>> install() <<< ???
# - - - - - - - - - - - - - - - - -
# . . . - тут может быть код для подключения и сборки других сторонних библиотек
# ------------------------ Сборка проекта -----------------------------
add_executable(TestProject
"main.cpp")
# - - - - - - - - - - - - Подключение зависимостей - - - - - - - - - - - - -
# assimp
include_directories("${assimp_INCLUDE_DIR}")
target_link_libraries(TestProject assimp)
Вопрос, собственно, состоит в том, как корректно сконфигурировать сборку стороннего пакета в рамках конфигурации сборки своего проекта - если сторонний пакет не собран заранее. Судя по переменным, которые предоставляет FIND_PACKAGE(...), считается что пакет должен быть уж собран, а переменные могут быть использованы чтобы передать пути для линковки и подключения заголовочных файлов.
Также, возможно, я вообще что-то делаю не так - я пока слабо понимаю CMake. Был бы благодарен тогда если поделитесь как принято организовывать подобные штуки.
P.S.: Вообще, идеальной видится "плоская" структура проекта. Какая-то такая:
CMakeLists.txtpackages_test // Папка, содержащая все создаваемые и используемые пакеты
|-- project_package // Пакет проекта
| |-- .git
| |-- CMakeLists.txt // Конфигурация сборки пакета
| |-- main.cpp // Точка входа, main()
| |-- . . . // Прочие файлы проекта
| |-- product // Результат сборки пакета
| | |-- res.exe // Исходник
| | |-- . . . // Прочие необходимые ресурсы (необходимые .dll/.so, контент, и т.д.)
|--vendor_package_0 // Папка-пакет стороннего проекта
| |-- .git
| |-- product // Результат сборки, готовый к использованию ({.dll/.so} + .a/.lib + headers)
| |-- . . .
|--vendor_package_1
| |-- .git
| |-- product
| |-- . . .
|-- . . .
Но я понимаю что для реализации системы сборки, поддерживающей подобную структуру понадобится потратить слишком много времени - минимум на написание обёрток, подгоняющих конфигурацию сборки сторонних проектов под описанную.
P.P.S.: На всякий случай, платформа, на которой выполняю тестовую сборку - Windows, тулчейн - MinGW, IDE - QtCreator.