CMake дозволяє швидко і зручно писати складальні скрипти для кроссплатформенной збірки програмних проектів. Під Windows генеруються проекти для Visual Studio, під Linux - Makefiles. Підтримуються і інші середовища розробки.
Але CMake дозволяє також зручно підключати залежності (сторонні бібліотеки) до проекту. І тут CMake надає ряд можливостей, які я хочу коротко розглянути.
Пошук бібліотек
Для підключення зовнішньої бібліотеки потрібно як мінімум вказати компілятору шлях до заголовним файлів і Лінкер - до самої бібліотеці (.lib. So). CMake може спробувати знайти ці шляхи за допомогою команд find_path і find_library. які в простій формі виглядають так:
Якщо файл з ім'ям імя_заголовочного_файла буде знайдений, то в змінну ПЕРЕМЕННАЯ1 буде записаний повний шлях до директорії, де цей файл лежить. Якщо файл з ім'ям імя_бібліотекі буде знайдений, то в змінну ПЕРЕМЕННАЯ2 буде записаний повний шлях до цього файлу.
Після цього ці змінні можна буде підключити до мети збирання:
Але ось тільки де CMake буде проводити пошук? Можна вказати кілька стандартних шляхів, наприклад так:
Це добре працює під Лінукс, де все бібліотеки зазвичай лежать за кількома стандартними шляхами. Під Windows гірше: потрібна бібліотека може розташовуватися, де завгодно.
Можна домовитися, що при установці бібліотеки на комп'ютер шлях до неї буде прописуватися в змінну оточення ПЕРЕМЕННАЯ_ОКРУЖЕНІЯ. тоді CMake зможе це використовувати:
Якщо нічого не допомогло, то користувачеві доведеться вручну вводити в інтерфейсі CMake потрібні шляху.
спрощення пошуку
Для складних сторонніх бібліотек з купою модулів і версій може знадобитися велике нагромадження команд find_path і find_library. Для зручності ці команди можна виділити в окремий скрипт з ім'ям FindБІБЛІОТЕКА.cmake.
Після цього можна викликати скрипт командою find_package:
(І не забути прописати в змінної CMAKE_MODULE_PATH шлях до папки зі скриптами).
Це серйозно спрощує структуру кореневого файлу CMakeLists.txt. Також для популярних бібліотек вже існують скрипти для пошуку, які встановлюються разом з CMake. Під Лінукс такі скрипти лежать в папці / usr / share / cmake / Modules. а під Windows в папці C: \ Program Files (x86) \ CMake \ share \ cmake-3.2 \ Modules.
Також деякі бібліотеки надають такі скрипти для пошуку самих себе. В цьому випадку його потрібно скопіювати собі в проект зі сховищ сторонньої бібліотеки.
Імпорт цілей складання
Крім шляхів до заголовним файлів і бібліотекам буває необхідна інформація про опції компілятора, про визначеннях препроцесора, про залежності залежностей і т.д. Було б зручно працювати зі сторонніми бібліотеками як зі звичайними цілями збірки.
CMake дозволяє це. Для цього необхідно створити «віртуальну» мета збірки і описати її властивості. У термінології CMake така мета збірки називається імпортована.
Створити і описати імпортовану мета збірки можна за допомогою ключового слова IMPORTED. приклад:
Після цього можна підключити цю зовн мета збірки до нашої мети:
При збірки нашого проекту автоматично будуть прописані шляхи до заголовним файлів і бібліотеці, визначення препроцесора. Цей спосіб є альтернативним використання функцій find_library і find_path.
Опис імпортованої цілі збірки зручно винести в окремий скрипт. Але краще, якщо сама зовнішня бібліотека згенерує цей скрипт за нас. Тут описано як генерувати такий скрипт автоматично.
Тоді нашим проектом достатньо буде підключити готовий скрипт:
збірка залежностей
Але що, якщо в системі не встановлена потрібна залежність? Можна попросити користувача встановити її, або доручити це CMake-скрипту.
Є 2 основні стратегії в залежності від розміру зовнішньої бібліотеки.
Вихідний код маленької бібліотеки можна просто додати в дерево початкових кодів нашого проекту, наприклад, в підпапку 3rdParty. Далі бібліотеку можна підключити в зкореневого файлу CMakeLists.txt за допомогою команди add_subdirectory:
Тоді ця бібліотека буде скомпільована разом з нашим проектом, і будуть доступні її цілі збірки.
Якщо зовнішня бібліотека занадто велика, то можна використовувати команду ExternalProject_Add. наприклад:
Команда має безліч параметрів. Вона дозволяє завантажити архів з інтернету і розпакувати його, або клонувати репозиторій, викликати окремий екземпляр CMake для створення проектів Visual Studio або Makefiles. Такий багатофункціональний комбайн.
Однак, команда має і недоліки. Справа в тому, що конфігурація та збірка зовнішньої бібліотеки відбуваються не під час ExternalProject_Add. Вони відбуваються одночасно зі складанням нашого проекту, а значить до початку збирання ні самих бібліотек, ні заголовків файлів, ні скриптів не існує. А це означає, що команди find_library. find_path видаватимуть помилки при конфігуруванні в CMake. Цілі складання зовнішньої бібліотеки будуть недоступні ...
Тому команда ExternalProject_Add не є панацеєю і її потрібно використовувати обережно.
Суперсборка
В обговореннях в інтернеті зустрів підхід до складання проекту, заснований на ExternalProject_Add. який назвали «суперсборкой».
Ідея в тому, що і сторонні бібліотеки, і наш проект збирати за допомогою ExternalProject_Add. Кореневої CMakeLists.txt просто містить виклики цієї команди і все.
В цьому випадку скачування і конфігурація відбувається в процесі побудови. Коли ми викликаємо команду make під Лінукс або запускаємо збірку в Visual Studio під Windows, то відбувається наступне:
- Скачується зовнішня бібліотека, конфігурується, збирається, встановлюється.
- Конфігурується наш проект (тепер find_library. Find_path спрацьовують без помилок, тому що зовнішня бібліотека вже фізично існує) і збирається.