Для чего нужен cmake

CMake Tutorial

Содержание

Что это и зачем нужно [ править ]

CMake — кроссплатформенная автоматизированная система сборки проектов. Непосредственно сборкой она не занимается, а только генерирует Makefile, который потом будет выполнен утилитой make.

CMake может проверять наличие необходимых библиотек и подключать их, собирать проекты под разными компиляторами и операционными системами. Т.е. у вас есть куча кода и файлик, содержащий информацию для cmake, и чтобы скомпилить это дело где-нибудь еще, вам нужно просто запустить там cmake, который сделает всё сам. Удобно, полезно, просто.

Краткое описание [ править ]

Если нет желания/времени/сил читать весь туториал и Вы используете какой-нибудь QtCreator (или любая другая IDE, умеющая работать с cmake), то:

Про подключение библиотек рекомендуется все-таки прочитать целиком.

Старт [ править ]

Предполагается, что найти и скачать сам cmake ты, %username%, в состоянии. //а если нет?

Предположим, у Вас есть исходничек «test.cpp» (// а если нет?)(А если нет, то CMake тебе трогать рано). Для начала нужно создать файлик для cmake, который обычно называют «CMakeLists.txt», и написать туда вот это:

Теперь запускаем (из консоли) в этой папке команду «cmake CMakeLists.txt» (аргументом можно передавать не только файл, но и директорию, в которой он лежит, тогда cmake найдет его сам).

А у Вас в папочке появится исполняемый файл «test». Запустите, убедитесь, что это действительно то, что ожидается от компиляции файла «test.cpp».

Подробное описание [ править ]

Поразбираемся с различными возможностями cmake.

Указание необходимой версии cmake [ править ]

Название проекта [ править ]

Указывает, что этот cmake-файл является корневым для некоторого проекта. С проектами связаны определенные переменные и поведение cmake (читайте документацию).

Переменные [ править ]

В cmake можно создавать текстовые переменные. Команда

Чтобы добавить к переменной некий текст, можно сделать так:

Пример коше’гного проекта со списком сорцов в отдельной переменной:

Устанавливаем команды компилятору [ править ]

Эта команда используется для установки дефайнов, которыe можно проверить в коде через, например, #ifdef SOME_IMPORTANT_DEFINITION.

Кто не знает: «-std=c++11» включает в gcc поддержку стандарта c++11, «-Wall» говорит gcc выводить все предупреждения (очень советую, помогает отловить много глупых багов и писать аккуратный код).

Папка с хедерами [ править ]

Допустим, Вы хотите, чтобы хедеры (файлики, подключаемые через #include) искались еще и в каталогах «headers/» и «more_headers/»:

Надеюсь, и это понятно.

Научимся искать и подключать библиотеки при помощи cmake на примере Boost. Для начала установим переменные для буста:

Итак, мы установили флаги. Давайте найдем буст!

Допустим, нам нужны компоненты буста под названием chrono (библиотека для работы со временем) и filesystem (библиотека для работы с файловой системой):

Win, будут искаться только нужные библиотеки, и их расположение будет записано в переменную Boost_LIBRARIES.

Добавим директории с хедерами буста для поиска в них хедеров:

Итак, осталось найденные библиотеки подключить к исполняемому файлу.

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

Заметим, что эту команду нужно вызывать после того, как создан target сборки (через add_executable).

Пример хорошего CMakeLists.txt и где он будет лежать [ править ]

Итак, полный пример использования всего этого. У нас есть некая директория (отныне считаем ее «/sources»), и в ней лежат исходники

В корне «/» лежит файл «/CMakeLists.txt»:

Таким образом, в корне у нас есть:

Все разделено, автоматизировано и удобно.

Как создать библиотеку в поддиректории и слинковать ее с основной программой [ править ]

Теперь можно в файлах основного проекта делать #include «lib.h» (см. документацию по target_include_directories).

Как использовать CMake в связке с QtCreator [ править ]

Интеграция с cmake у QtCreator не очень тесная, тем не менее, работать с ним можно.

Создаем новый проект без использования Qt, выбираем «Проект на С++ с использованием CMake». Создастся дефолтный файл сборки, который просто добавляет все исходники в директории проекта и компилирует их в один бинарник.

Как добавить header в проект, чтобы его было видно в списке файлов [ править ]

Если вы создали файл header.h в директорию проекта, просто строчку

Источник

Полное руководство по CMake. Часть первая: Синтаксис

Для чего нужен cmake. Смотреть фото Для чего нужен cmake. Смотреть картинку Для чего нужен cmake. Картинка про Для чего нужен cmake. Фото Для чего нужен cmake

Введение

CMake — это открытый и кросс-платформенный набор утилит, предназначенных для автоматизации тестирования, компиляции и создания пакетов проектов на C/C++. Написав однажды небольшой и понятный всем скрипт, Вы тем самым обеспечите одинаковую сборку Вашего проекта на любых платформах, где доступен CMake.

Язык CMake, будучи транслированным в нативный файл сборки (например, Makefile или Ninja), определяет процесс всего управления проектом. В Вашем распоряжении, с функциональной стороны, есть лишь команды, которые могут образовываться в довольно сложные конструкции. С них мы и начнём.

Запуск CMake

Ниже приведены примеры использования языка CMake, по которым Вам следует попрактиковаться. Экспериментируйте с исходным кодом, меняя существующие команды и добавляя новые. Чтобы запустить данные примеры, установите CMake с официального сайта.

Команды

Команды в CMake подобны функциям во многих языках программирования. Чтобы вызвать команду, необходимо написать её имя, а затем передать ей обрамлённые в круглые скобки аргументы, отделённые символами пробелов. В приведённом примере команде message передаются шесть аргументов для вывода в консоль:

Аргументы

Аргументы, обрамлённые в двойные кавычки, позволяют внутри себя совершать экранирование и подстановку переменных. Необрамлённые аргументы не позволяют производить подобных вещей и не могут включать в себя символы ()#»\ и пробелы, однако более удобны для использования. Пример:

Комментарии

Комментарии начинаются с символа решётки и заканчиваются в конце той строки, где они были напечатаны. Текст, заключённый в комментариях, игнорируется системой сборки и не оказывает никакого эффекта на её работу. Примеры выше также демонстрируют использование комментариев.

Переменные

Опции

Логические выражения

Прежде чем приступать к изучению условных операторов и циклических конструкций, необходимо понимать работу логических выражений. Логические выражения используются при проверки условий и могут принимать одно из двух значений: правда или ложь. Например, выражение 52 LESS 58 обратится в правду, так как 52 88 EQUAL 88 обратится в правду, 63 GREATER 104 обратится в ложь. Сравнивать можно не только числа, но и строки, версии, файлы, принадлежность к списку и регулярные выражения. Полный список логических выражений можно посмотреть тут.

Условные операторы

Условные операторы в CMake работают в точности как в других языках программирования. В данном примере сработает лишь первый условный оператор, который проверяет, что 5 > 1. Второе и третье условия ложны, так как 5 не может быть меньше или равняться одному. Блоки команд elseif и else необязательны, а endif обязательна и сигнализирует о завершении предыдущих проверок.

Циклы

Функции и макросы

Синтаксис CMake позволяет определять собственные команды, которые можно будет вызывать в точности как встроенные. Приведённый ниже пример демонстрирует использование функций и макросов: сначала определяются функция и макрос со своими собственными командами, а при их вызове их команды исполняются последовательно.

Команда function первым аргументов принимает имя будущей функции, а остальные аргументы — это имена параметров, с которыми можно работать как с обычными переменными. Параметры видимы лишь определяемой функции, значит вне функции доступ к её параметрам мы получить не можем. Более того, все другие переменные, определяемые и переопределяемые внутри функции, видны лишь ей самой.

Макросы аналогичны функциям за тем исключением, что они не имеют собственной области видимости: все переменные внутри макросов рассматриваются как глобальные. Более подробно о различиях макросов и функций Вы можете почитать здесь.

Разбор аргументов

Как отметили в комментариях, Мощный механизм cmake_parse_arguments позволяет производить разбор аргументов, переданных в функцию или макрос.

Данная команда принимает префикс, используемый в определении переменных (смотреть следующий абзац), список опций, используемых без последующих значений, список ключевых слов, после которых следует одно значение, список ключевых слов, после которых следуют множества значений и список всех значений, переданных в функцию или макрос.

Работа механизма разбора аргументов заключается в преобразовании полученных аргументов в значения переменных. Таким образом, рассмотренная команда для каждой опции и ключевого слова определяет собственную переменную вида

Области видимости

В предыдущем разделе Вы узнали о том, что некоторые конструкции в CMake могут определять собственные области видимости. На самом деле, все переменные по умолчанию считаются глобальными (доступ к ним есть везде), за исключением тех, которые были определены и переопределены в функциях. Также имеются кэш-переменные, у которых своя собственная область видимости, но они применяются не столь часто.

Заключение

На этом синтаксис языка CMake заканчивается. Следующая статья выйдет примерно через пару дней и будет вводить в использование системы сборки CMake. До скорых встреч!

Источник

Полное руководство по CMake. Часть вторая: Система сборки

Для чего нужен cmake. Смотреть фото Для чего нужен cmake. Смотреть картинку Для чего нужен cmake. Картинка про Для чего нужен cmake. Фото Для чего нужен cmake

Введение

В данной статье рассмотрено использование системы сборки CMake, применяемой в колоссальном количестве проектов на C/C++. Строго рекомендуется прочитать первую часть руководства во избежание непонимания синтаксиса языка CMake, явным образом фигурирующего на протяжении всей статьи.

Запуск CMake

Ниже приведены примеры использования языка CMake, по которым Вам следует попрактиковаться. Экспериментируйте с исходным кодом, меняя существующие команды и добавляя новые. Чтобы запустить данные примеры, установите CMake с официального сайта.

Принцип работы

Система сборки CMake представляет из себя оболочку над другими платформенно зависимыми утилитами (например, Ninja или Make). Таким образом, в самом процессе сборки, как бы парадоксально это ни звучало, она непосредственного участия не принимает.

Система сборки CMake принимает на вход файл CMakeLists.txt с описанием правил сборки на формальном языке CMake, а затем генерирует промежуточные и нативные файлы сборки в том же каталоге, принятых на Вашей платформе.

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

Проверка версии CMake

Команда cmake_minimum_required проверяет запущенную версию CMake: если она меньше указанного минимума, то CMake завершает свою работу фатальной ошибкой. Пример, демонстрирующий типичное использование данной команды в начале любого CMake-файла:

Как подметили в комментариях, команда cmake_minimum_required выставляет все флаги совместимости (смотреть cmake_policy ). Некоторые разработчики намеренно выставляют низкую версию CMake, а затем корректируют функционал вручную. Это позволяет одновременно поддерживать древние версии CMake и местами использовать новые возможности.

Оформление проекта

В начале любого CMakeLists.txt следует задать характеристики проекта командой project для лучшего оформления интегрированными средами и прочими инструментами разработки.

Запуск скриптовых файлов

Команда include заменяет строку своего вызова кодом заданного файла, действуя аналогично препроцессорной команде include языков C/C++. Этот пример запускает скриптовый файл MyCMakeScript.cmake описанной командой:

Компиляция исполняемых файлов

Компиляция библиотек

Добавление исходников к цели

Повторяющиеся вызовы команды target_sources добавляют исходные файлы к цели в том порядке, в каком они были вызваны, поэтому нижние два блока кода являются функционально эквивалентными:

Генерируемые файлы

Важно подметить, что «DLL-платформами» считаются все платформы, основанные на Windows, в том числе и Cygwin.

Компоновка с библиотеками

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

Работа с целями

Как упомянули в комментариях, цели в CMake тоже подвержены ручному манипулированию, однако весьма ограниченному.

Имеется возможность управления свойствами целей, предназначенных для задания процесса сборки проекта. Команда get_target_property присваивает предоставленной переменной значение свойства цели. Данный пример выводит значение свойства C_STANDARD цели MyTarget на экран:

Пример выше задал цели MyTarget свойства, влияющие на процесс компиляции, а именно: при компиляции цели MyTarget CMake затребует компилятора о использовании стандарта C11. Все известные именования свойств целей перечисляются на этой странице.

Также имеется возможность проверки ранее определённых целей с помощью конструкции if(TARGET ) :

Добавление подпроектов

Команда add_subdirectory побуждает CMake к незамедлительной обработке указанного файла подпроекта. Пример ниже демонстрирует применение описанного механизма:

Стоит отметить, что все переменные из родительской области видимости унаследуются добавленным каталогом, а все переменные, определённые и переопределённые в данном каталоге, будут видимы лишь ему (если ключевое слово PARENT_SCOPE не было определено аргументом команды set ). Данную особенность упомянули в комментариях к предыдущей статье.

Поиск пакетов

Команда find_package находит и загружает настройки внешнего проекта. В большинстве случаев она применяется для последующей линковки внешних библиотек, таких как Boost и GSL. Данный пример вызывает описанную команду для поиска библиотеки GSL и последующей линковки:

В общем случае, команда find_package имеет две разновидности запуска: модульную и конфигурационную. Пример выше применял модульную форму. Это означает, что во время вызова команды CMake ищет скриптовый файл вида Find

Способы включения заголовков

Команда target_include_directories влияет лишь на указанную первым аргументом цель, а на другие цели никакого воздействия не оказывается. Пример ниже демонстрирует разницу между этими двумя командами:

Установка проекта

Команда install генерирует установочные правила для Вашего проекта. Данная команда способна работать с целями, файлами, папками и многим другим. Сперва рассмотрим установку целей.

После завершения обработки CMake всех Ваших файлов Вы можете выполнить установку всех описанных объектов командой sudo checkinstall (если CMake генерирует Makefile ), или же выполнить данное действие интегрированной средой разработки, поддерживающей CMake.

Наглядный пример проекта

Данное руководство было бы неполным без демонстрации реального примера использования системы сборки CMake. Рассмотрим схему простого проекта, использующего CMake в качестве единственной системы сборки:

Заключение

Теперь Вы способны писать свои и понимать чужие CMake-файлы, а подробно прочитать про остальные механизмы Вы можете на официальном сайте.

Следующая статья данного руководства будет посвящена тестированию и созданию пакетов с помощью CMake и выйдет через неделю. До скорых встреч!

Источник

Введение в CMake

Для чего нужен cmake. Смотреть фото Для чего нужен cmake. Смотреть картинку Для чего нужен cmake. Картинка про Для чего нужен cmake. Фото Для чего нужен cmakeCMake — кроcсплатформенная утилита для автоматической сборки программы из исходного кода. При этом сама CMake непосредственно сборкой не занимается, а представляет из себя front-end. В качестве back-end`a могут выступать различные версии make и Ninja. Так же CMake позволяет создавать проекты для CodeBlocks, Eclipse, KDevelop3, MS VC++ и Xcode. Стоит отметить, что большинство проектов создаются не нативных, а всё с теми же back-end`ами.

Для того что бы собрать проект средствами CMake, необходимо в корне дерева исходников разместить файл CMakeLists.txt, хранящий правила и цели сборки, и произвести несколько простых шагов.
Разберёмся на примерах.

Пример 1. Hello, World:

Синтаксис CMake похож на синтаксис bash, всё что после символа «#» является комментарием и обрабатываться программой не будет. CMake позволяет не засорять дерево исходных кодов временными файлами — очень просто и без лишних телодвижений сборка производится «Out-of-Source».

Создадим пустую директорию для временных файлов и перейдём туда.

$ mkdir tmp
fshp@panica-desktop:

$ cd tmp/
fshp@panica-desktop:

/cmake/example_1/

— Build files have been written to: /home/fshp/tmp
fshp@panica-desktop:

/tmp$ ls
CMakeCache.txt CMakeFiles cmake_install.cmake Makefile
fshp@panica-desktop:

/tmp$ make
Scanning dependencies of target main
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
Linking CXX executable main
[100%] Built target main
fshp@panica-desktop:

Итак, наша программа собралась.
Папку tmp можно очищать\удалять без риска поломать исходники. Если CMakeLists.txt был изменен, то вызов make автоматически запустит cmake. Если исходники были перемещены, то нужно очистить временную директорию и запустить cmake вручную.

Пример 2. Библиотеки:

Переменные могут хранить списки значений, разделённых пробелами\табуляциями\переносами:

Оба варианта правильные
Что бы получить значение переменной ипользуем конструкцию:

Итак, эта версия нашего проекта включает в себя одну статическую библиотеку, собираемую из исходников. Если заменить «STATIC» на «SHARED», то получим библиотеку динамическую. Если тип библиотеки не указать, по умолчанию она соберётся как статическая.
При линковке указываются все необходимые библиотеки:

Как и при ручной компиляции, имена библиотек указываются без стандартного префикса «lib».
Итак, сборка библиотек с CMake не вызывает проблем, при этом тип библиотеки статическая\динамическая меняется лишь одним параметром.

Пример 3. Подпроекты:

В файле подпроекта ничего нового для вас нет. А вот в основном файле новые команды:

main.cpp мы не меняли, а foo.h перенесли. Команда указывает компилятору, где искать заголовочные файлы. Может быть вызвана несколько раз. Хидеры будут искаться во всех указаных директориях.

Указываем директорию с подпроектом, который будет собран как самостоятельный.
Вывод: проекты на CMake можно объединять в довольно сложные иерархические структуры, причем каждый подпроект в реальности является самостоятельным проектом, который в свою очередь может сам состоять из подпроектов. Это позволяет легко разбить вашу программу на необходимое количество отдельных модулей. Примером такого подхода может служить KDE.

Пример 4. Поиск библиотек:

CMake обладает достаточно развитыми средствами поиска установленых библиотек, правда они не встроеные, а реализованы в виде отдельных модулей. В стандартной поставке довольно много модулей, но некоторые проекты (например Ogre) поставляют свои. Они позволяют системе автоматически определить наличие необходимых для линковки проекта библиотек.
На debian модули располагаются в /usr/share/cmake-2.8/Modules/ (у вас версия может отличаться). За поиск библиотек отвечают модули, называющиеся FindNAME.cmake, где NAME — имя библиотеки.

Думаю, смысл должен быть понятен. Первый и второй блок — поиск библиотеки. Если в системе её нет, выведется сообщение об ошибке и завершается выполнение cmake. Третий блок похож, только он ищет не целый пакет библиотек, а лишь необходимый компонент. Каждый такой автоматизированый поиск определяет после выполнения как минимум 3 переменные:
SDL_FOUND, LIBXML2_FOUND, Boost_FOUND — признак присутствия бибилиотеки;
SDL_LIBRARY, LIBXML2_LIBRARIES, Boost_LIBRARIES — имена библиотек для линковки;
SDL_INCLUDE_DIR, LIBXML2_INCLUDE_DIR, Boost_INCLUDE_DIRS — пути к заголовочным файлам.
Если с первыми более или менее понятно, то вторые и третьи мне доставили много хлопот — половина имеет имена в единственном числе, половина — во множественном. Но оказалось, это легко отследить. В каждом модуле вначале есть коментарии, там описаны определяемые переменные. Посмотрите, например, /usr/share/cmake-2.8/Modules/FindLibXml2.cmake
Как видите, CMake способен сам определить наличие и местоположение необходимых библиотек и заголовочных файлов. В принципе, это должна уметь любая система автоматической сборки, иначе смысл в ней?

Пример 5. Внешние библиотеки и объектные файлы:

Если вы пишите для «дяди», а злой «дядя» любит самописные библиотеки и делиться исходниками не желает, поэтому присылает готовую библиотеку, то вы по адресу.
Объектные файлы в CMake стоят на ряду с исходниками — достаточно включить объектник в список файлов для компиляции.
С библиотеками потуже. Как известно, статическая библиотека это не что иное, как ar-архив, внутри которого лежат обычные объектники, никак не связаные между собой. Вы, наверное, уже догадались, как я поступал сначала. Да, просто потрошил библиотеку. Но потом был найден способ поэлегантнее:

Слово «IMPORTED», указывает, что библиотека берётся извне.
В CMake каждая цель имеет параметры, а set_property позволяет их изменять.
Линкуется такая библиотека стандартно:

Для динамических библиотек все аналогично, только тип «SHARED», расширение — «.so».
К сожалению, поддержка несистемных библиотек реализована немного костыльно. Возможно, я просто не знаю правильного варианта, поэтому буду рад, если «ткнете мордочкой». С другой стороны это не навороченый экзоскелет с системой жизнеобеспечения, а простейший костыль из двух строк.

Генераторы:

Заключение:

Это не перевод мануала, а результат использования CMake в одном коммерческом проекте. Буду рад, если статья поможет хотя бы одному человеку — на русском языке подобной документации довольно мало.

Источник

Что есть что в CMake 3.10+ и как это использовать

Вступление

Популярность CMake растёт. Многие крупные проекты переходят с собственных инструментов для сборки на CMake. Проект Conan предлагает интеграцию с CMake для управления зависимостями.

Разработчики CMake активно развивают инструмент и добавляют новые функции, решающие общие проблемы, возникающие при сборке проектов. Переход с CMake 2 на CMake 3 был достаточно болезнен. Документация не покрывает все аспекты использования. Функционал крайне обширен, а возникающие трудности различаются от проекта к проекту. В статье я расскажу о инструментах, которые предлагает CMake 3.10 и выше. В каждой новой версии появляются новые детали или улучшаются старые. Об актуальном состоянии лучше проанализировать Changelog, так как многие улучшения последних версий весьма специфичны для отдельных проектов, как например улучшение поддержки Cuda компиляторов. Я же сфокусируюсь на общих понятиях, которые помогут организовать проект на С++ оптимальным образом с точки зрения использования CMake как основной системы сборки.

CMake предлагает широкий набор инструментов. Чтобы не потеряться в определениях, в статье сперва будут определены сущности, через которые будут объяснены конкретные примеры. Названия сущностей я продублирую на английском. Некоторые термины не имеют однозначного перевода на русский язык.

Обзор демонстрационного проекта

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

Структура файлов и папок проекта с именем ‘neuon’ следующая:

Используемые сущности и понятия

Приложения в комплекте поставки (CMake, CPack, CTest, CDash)

Предопределенные и ожидаемые файлы и их назначение

Свойства, переменные, аргументы и параметры.

Приложения в комплекте поставки (CMake, CPack, CTest, CDash)

CMake поставляет в комплекте с несколькими приложениями, предназначенными для дополнения процесса сборки проекта. За саму сборку отвечает cmake, который работает с файлом, описывающим проект. Использование cmake состоит из нескольких шагов: шаг генерации(generation), шаг сборки(build) и шаг установки(install).

Первым этапом при сборке проекта необходимо сгенерировать скрипты сборки, используя описание проекта(CMakeLists.txt) на языке CMake. Результатом генерации является скрипт или набор файлов, необходимый для запуска нижележащей системы сборки(например Makefile или VIsual Studio Solution). CMake не выполняет запуск компилятора сам, хотя может быть использован как прокси для обобщения вызовов нижележащих инструментов.

Следующим шагом происходит непосредственно сборка проекта из исходного кода. Результатом являются бинарные файлы и другие артефакты, являющиеся частью конечного продукта для потребителя. Все артефакты, несмотря на свою доступность, находятся в специальном состоянии, контролируемом CMake и как правило непригодны к перемещению или распространению, однако, могут быть использованы для отладки локально.

Финальным шагом использования СMake является шаг установки. Установка подразумевает пересборку либо по необходимости перелинковку бинарных артефактов с целью сделать их пригодными к использованию на целевой системе. Как правило, при установке также происходит перемещение артефактов в желаемые расположения и создании желаемой раскладки по директориям. Установка на этом этапе не имеет ничего общего с установкой дистрибутива или распаковкой архива, но при некорректной конфигурации сборки может установить свежесобранные артефакты в локальную систему. При использовании шаг установки не выполняется вручную.

Предопределенные и ожидаемые файлы и их назначение.

CMake использует некоторые предопределённые имена или части имени файла, наделяя эти файлы особенным смыслом.

В папке сборки после генерации можно найти файл CMakeCache.txt. Этот файл содержит полное представление всего проекта, которое CMake смог разобрать и сгенерировать. Этот файл может быть отредактирован вручную, для изменения некоторых параметров и переменных. Однако, при следующей генерации изменения могут быть утеряны, если параметры и аргументы запуска CMake утилиты изменились.

Модули, конфигурации

Конфигурации же напротив, неотъемлемая часть проекта, поставляются вместе с заголовочными файлами и библиотеками импорта, и обеспечивают интеграцию библиотек в другие проекты. Конфигурация проекта не используется при сборке проекта. Конфигурация является результатом сборки проекта и входит в установщик, поддерживаются и разрабатываются авторами проекта.

Конфигурации не должны располагаться в CMAKE_PREFIX_PATH и должны следовать соглашению о местоположении и именовании, описанном в официальной документации. (https://cmake.org/cmake/help/latest/command/find_package.html#full-signature-and-config-mode)

Конфигурации описывают зависимости проекта, с целью облегчить его использование. Конфигурации крайне чувствительны к своей реализации. Следование практикам и рекомендациям поможет делать конфигурации, которые облегчают интеграции проекта заказчикам и пользователям.

Начиная с версии 3 CMake сместил парадигму своих скриптов с процедурно-ориентированной на объекто-ориентированную. В версии 2, описание проекта содержало набор вызовов функций, которые выполняли настройку свойств, необходимых для сборки и использования. В версии 3, на смену переменным и свойствам пришли цели. Цель(target) в контексте CMake, это некоторая сущность, над которой можно выполнять операции, изменять ее свойства, обеспечивать ее доступность и готовность. Целями могут являются, но не ограничиваются, бинарные артефакты и исполняемые файлы проекта, заголовочные файлы проекта, дополнительные файлы, создаваемые при генерации, зависимости целей, внешние библиотеки или файлы и т.д.

Свойства, переменные, аргументы и параметры.

CMake обеспечивает гибкость настройки и использования предоставляя разные способы контроля и управления своим поведением.

Таким образом, управление CMake утилитами выполняется через аргументы командной строки, параметры запуска, переменными в скриптах, и свойствами целей. Аргументы не оказывают влияние на состояние скриптов, параметры превращаются в переменные с тем же именем, свойства целей имеют предустановленное документированное имя и могут быть установлены в произвольные значения через вызов соответствующих функций.

Примеры задач и использование доступных инструментов

У меня в руках проект, который использует CMake. Что с ним делать?

Сгенерировать сборочные файлы в папке сборки, запустить сборку, опционально запустить установку.

Переназначение назначения зависит от собственно системы сборки и не каждая из них умеет такое делать.

Пример сборки под Linux из реального проекта:

Для генерации под Windows, используя Visual Studio:

Как запустить тесты с CTest?

После генерации запустить CTest в папке сборки.

По умолчанию, CTest не выводит ход выполнения тестов. Аргументы вызова помогут достигнуть желаемого поведения.

Как пользоваться целями и свойствами?

И напоследок несколько файлов устанавливаются как есть. Это ресурсы, которые распространяются как часть проекта.

Как использовать файлы конфигурации?

Начиная с CMake 3.0 рекомендуется в файлах конфигурации объявлять цели, которые могут быть использованы потребителем. До CMake 3.0 файлы конфигурации объявляли несколько переменных, именованных по определенным правилам и эти переменные становились доступны потребителю. На настоящий момент, некоторые проект до сих пор используют только старый подход, некоторые проекты используют старый подход как дополнение к новому. Иногда появляются инициативы завернуть старые конфигурации в новые или в CMake модули. В этом примере мы уделяем внимание новому подходу, как рекомендуемому.

Как добавить свои тесты в запуск CTest?

Как конфигурировать CPack?

Подключив требуемые модули расширяющие CPack, необходимо выставить значения задокументированных переменных для каждого конкретного формата установщика или пакета. Некоторые значения берутся из переменных и параметров CMake, некоторые могут быть заполнены автоматически при выполнение упаковки. После выставления переменных следует подключить собственно модуль CPack через include(CPack).

Как написать конфигурацию для своего проекта?

По созданию своего файла конфигурации есть статья здесь.

В общих чертах, файл конфигурации описывает цели, которые пользователь может использовать в своем проекте. Список целей генерируется CMake при создании экспортируемой сущности, привязанной к целям. Версионирование и проверки целостности конфигурации общего назначения реализованы в модуле CMakePackageConfigHelpers.

Шаблон конфигурации может быть похож на:

Как использовать конфигурации других проектов?

Корректно подготовленная конфигурация не требует никаких дополнительных действия для использования.

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

Как использовать стандартные CMake модули?

Несмотря на регламентированное именование модулей использование их в своих проектах двоякое. Многие стандартные модули CMake подключаются через функцию include(), однако многие модули, выполняющие поиск библиотек, не поддерживающих CMake самостоятельно через конфигурацию полагаются на find_package() в режиме модулей.

Библиотека Boost начиная с версии 1.70 обеспечивает поддержку CMake через конфигурации. СMake модуль обладает обратной совместимостью и умеет разрешать местонахождение Boost любой версии, используя конфигурации при наличии и создавая цели-псевдонимы в противном случае.

Как использовать модули из посторонних или личных источников?

При изменении CMAKE_MODULE_PATH в своих конфигурациях, чтобы избежать конфликтов модулей с проектом пользователя, можно использовать функции по работе со списками. После добавления своих путей в переменную и использования, можно удалить эти вхождения из списка.

Как подключать и переиспользовать другие куски CMake скриптов?

CMake позволяет включать части скриптов друг в друга как есть, не выполняя дополнительной работы. Это может быть полезно для переиспользования функционала, когда использование модуля не обосновано, а дублирования хочется избежать. include() включит содержимое указанной файла в использующий файл. Включаемые файлы должны быть реентерабельны, и не изменять глобальное состояние.

Заключение

Глобальные свойства, параметры и переменные управляются CMake. Проект не должен их менять по своем усмотрению. Проект должен подстраиваться под глобальное состояние.

Сборка настраивается и модифицируется не внутри скриптов, а используя параметры и аргументы при запуске CMake. Позвольте будущему себе как автору проекта решать, разделяемая библиотека или статическая, установка в системные папки или в директории пользователя с ограниченными правами, включить максимальную оптимизацию или обеспечить отладочную информацию.

CMake предлагает очень широкий выбор доступных параметров и переменных, не стоит дублировать их в своем проекте.

Использование относительных путей предпочтительнее абсолютных.

CMake проекты могут быть включены друг в друга в произвольном порядке. Один проект не должен разрушать состояние, созданное другим.

CMake распространяется как самодостаточный архив под все популярные платформы. Файл конфигурации ограничен версией CMake потребителя, но для сборки и упаковки проекта можно притащить последнюю версию, развернуть локально как часть окружения сборки и пользоваться наиболее свежим функционалом, которые сделан, чтобы делать жизнь авторов проектов проще.

Полезные ссылки

В чем разница между разными способами включения подпроектов?

CMake предлагает разные способы подключения проектов друг в друга. Если допустить, что проект описывается как минимум одним CMakeLists.txt, то проекты между собой могут быть связаны через add_subdirectory(), include(), ExternalProject_Add().

Основная идея в том, что CMakeLists.txt описывает проект как нечто именованное и версионированное. Директива project() устанавливает некоторые переменные, используемые CMake при генерации и сборке. Как минимум версию проекта.

include() включает содержимое как есть, а в одном CMakeLists.txt не может оказаться две активные директивы project().

ExternalProject_Add() предлагает способ сборки подпроекта из исходного кода, но не делает подпроект частью сборки основного проекта. Через ExternalProject_Add обычно подключаются сторонние зависимости, которые не могут быть удовлетворены окружением сборки или целевой системой.

add_subdirectory() единственный корректный способ подключить проект в проект, создав единое дерево зависимостей и связей между целями, сохранив при этом проектную идентичность и самодостаточность. Помимо непосредственно подключения проекта, CMake выполняет дополнительные операции по изоляции подпроектов и областей видимости.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *