Cmake как пользоваться linux

Cmake как пользоваться linux

На первом шаге проект нужно сконфигурировать, то есть создать финальный скрипт сборки, запустив cmake в будущем каталоге сборки.

На втором шаге нужно запустить финальный скрипт. Не вызывайте make ! Утилита cmake сделает это сама:

Структура CMakeLists.txt

В начале главного файла CMakeLists.txt ставят метаинформацию о минимальной версии CMake и названии проекта:

Затем следует список инструкций, служащих для вычисления различных переменных, создания целей сборки, подключения проектов из подкаталогов и так далее. Например, подключить дополнительный CMakeLists.txt из подкаталога можно так:

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

Целью также может быть библиотека, статическая или динамическая.

Автогенерация проекта для Visual Studio (Windows)

Если используется Visual C++, то путь немного другой: на шаге конфигурирования создаётся проект для Visual Studio, который затем можно собрать из IDE либо так же из командной строки.

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

Если проект был сконфигурирован успешно, то в каталоге ../myapp-build появятся автоматически сгенерированный BUILD_ALL.sln и проекты для Visual Studio. Их можно открыть к IDE, либо собрать из командной строки с помощью cmake. Названия опций говорят сами за себя:

Зависимости между библиотеками и приложениями

Не используйте директивы include_directories , add_definitions , add_compile_options ! Они меняют глобальные настройки для всех целей, это создаёт проблемы при масштабировании.

  • Используйте target_link_libraries для добавления статических и динамических библиотек, от которых зависит цель
  • Используйте target_include_directories вместо include_directories для добавления путей поиска заголовков, от которых зависит цель
  • Используйте target_compile_definitions вместо add_definitions для добавления макросов, с которыми собирается цель
  • Используйте target_compile_options для добавления специфичных флагов компилятора, с которыми собирается цель

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

  • PUBLIC делает настройку видимой для текущей цели и для всех зависящих от неё целей
  • PRIVATE делает настройку видимой только для текущей цели
  • INTERFACE делает настройку видимой только для всех зависящих от неё целей

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

Схема зависимостей условного проекта:

Выбор стандарта и диалекта C++

Для настройки стандарта и флагов языка C++ не добавляйте флаги напрямую!

В CMake версии 3.8+ вы можете прямо потребовать включить нужный стандарт:

В CMake версии до 3.7 включительно можно использовать set_target_properties (если не работает, то у вас слишком старый CMake):

Для разработчиков библиотек есть более тонкий контроль над возможностями языка:

Функции в CMake

CMake позволяет объявлять функции командами function(name) / endfunction() и макросы командами macro(name) / endmacro() . Предпочитайте функции, а не макросы, т.к. у функций есть своя область видимости переменных, а у макросов — нет.

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

Лучше добавлять специфичные исходники с помощью target_sources, а не с помощью дополнительных переменных.

Интерфейс к утилитам командной строки

Функция find_package

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

Пример подключения Boost, вызывающего встроенный в CMake скрипт FindBoost:

Пример подключения библиотеки Bullet с помощью встроенного скрипта FindBullet и компоновки с приложением my_app:

Источник

Личный опыт разработки ПО

Сборка проектов с CMake. Введение

Для автоматизации сборки проектов традиционно используют системы сборки, такие как make на Unix подобных системах и nmake для компилятора Microsoft. Также традиционно написание файлов для сборки проекта под эти системы является задачей нетривиальной. Конечно в пользуясь только Mictosoft Visual Studio можно даже не подозревать о существовании этих файлов, так как интегрированная среда разработки достаточно удобно скрывает всю кухню, оставляя снаружи несколько диалоговых окон и кнопку Build. Но для сложных проектов использующих массу сторонних библиотек и кроссплатформенных проектов такой подход часто оказывается неприемлемым.

Читайте также:  Asus k52j перевернутое изображение камеры windows 10

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

Что нужно сделать?

Собрать программу hello_world.

Как ее делать?

Взять файлы hello_world.h и hello_world.cpp и запустить компилятор передав их в качестве параметров.

Что делать когда компилятор закончит работать?

Взять получившийся в результате работы компилятора объектный файлы hello_world.o и запустить линковщик передав ему этот файл.

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

Выглядит все просто, проблемы возникают дальше и проблем несколько:

  1. Разрешение зависимостей возникающих между частями проекта
  2. Синтаксическая сложность и неоднозначность классических make-файлов
  3. Привязка к конкретной утилите автоматической сборки и как следствие непереносимость на другие платформы

Для решения части этих проблем или всех сразу были созданы следующие инструменты: Automake (http://sourceware.org/automake/) , CMake (http://www.cmake.org/), SCons (http://www.scons.org/). Список далеко не полный.

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

Сам CMake не осуществляет сборку проекта, он лишь генерирует из своего файла сборки make-файл для конкретной платформы. Это может быть проект Microsoft Visual Studio, NMake makefile, проект XCode для MacOS, Unix makefile, Watcom makefile, проект Eclipse или CodeBlocks. Более того файлы CMake открывает как проект набирающая популярность среда разработки QtCreator.

Данный файл обычно называется CMakeLists.txt и содержит команды понятные CMake. Выполнив

Мы получим либо проект который можно открыть в вашей среде разработки, либо makefile по которому можно собрать проект запустив соответствующую систему сборки (make, nmake, wmake). Всегда можно явно указать, что должна генерировать программа, указав ключ –G с нужным параметром (просто запустите cmake, чтобы увидеть доступные варианты).

Где взять CMake?

Дистрибутив CMake можно скачать с официального сайта (http://cmake.org/cmake/resources/software.html) где есть версии для всех популярных платформ или установить из репозитория вашего дистрибутива Linux, скорее всего он там уже есть.

Hello, World!

Предлагаю рассмотреть простой CMake-файл:

Что здесь происходит?

  1. В первой строке просто указана минимальная версия CMake необходимая для успешной интерпретации файла.
  2. В третьей строке определяется переменная PROJECT и ей задается значение hello_world — так будет называться наша программа.
  3. О чем и говорится в пятой строке. Конструкция $ <ИМЯ_ПЕРЕМЕННОЙ>возвращает значение переменной, таким образом проект будет называться hello_world.
  4. В седьмой и десятой строках вводятся переменные содержащие список файлов необходимых для сборки проекта.
  5. И в последней строке идет команда собрать исполняемый файл с именем указанном в переменной PROJECT и из файлов имена которых находятся в переменных HEADERS и SOURCES.

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

Как собрать библиотеку с CMake?

Точно также как и исполняемый файл, но в последней строке вместо команды add_executable, укажите команду add_library. В этом случае будет собрана статическая библиотека, для сборки динамической библиотеки надо указать параметр SHARED после имени библиотеки:

Немного о стиле

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

  • Имена переменных пишутся английскими буквами в верхнем регистре
  • Команды CMake записываются английскими буквами в нижнем регистре
  • Параметры команд CMake пишутся английскими буквами в верхнем регистре
  • Команды CMake отделены пробелом от открывающей скобки

Где должен находится CMakeLists.txt?

Очень удобно в корне каждого проекта иметь директорию build с файлами сборки проекта, причем имя файла во всех директориях должно называться одинаково (название по умолчанию CMakeLists.txt отлично подойдет). Это позволит собирать сложные проекты рекурсивно подключая директории с подпроектами (о подключении подпроектов к проекту можно прочесть в моей заметке).

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

Сборка сложного проекта

Усложним задачу и соберем проект зависящий от библиотеки. Для этого надо сделать следующие вещи:

  1. Собрать библиотеку
  2. Подключить библиотеку к проекту

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

Теперь о том как эту библиотеку подключить. Сделать это можно добавив в CMakeLists.txt проекта три строки:

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

Во второй строке идет указание CMake взять файл из директории build подпроекта, выполнить его и результат работы положить в директорию ./bin/ИМЯ_БИБЛИОТЕКИ.

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

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

Остальные вопросы

Все хорошо, но почему в проекте Microsoft Visual Studio не показаны заголовочные файлы?

Это можно исправить добавив в файл две строки:

На работу CMake при генерации файлы для других систем это никак не повлияет.

Почему я не вижу предупреждений компилятора (warnings)?

Предупреждения можно включить следующим образом (пример для MS VS и GCC):

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

Файл с примером

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

Источник

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

Введение

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

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

Запуск CMake

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

Команды

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

Аргументы

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

Стоит отметить, что аргумент Walk;around;the;forest расширится до списка Walk around the forest , так как любой необрамлённый аргумент автоматически расширяется до списка значений (при условии, что значения изначального аргумента разделены символами точки с запятой), но с обрамлённым в двойные кавычки аргументом такая трансформация не происходит (символы точки с запятой просто исчезают). Об этой особенности упомянули в комментариях.

Комментарии

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

Переменные

Переменные можно определить путём вызова команды set , а удалить вызовом unset . Получить значение переменной можно по конструкции $ . Если переменная ещё не определена и где-то потребовалось получить её значение, то данная переменная обратится в пустую строку. Пример:

Опции

CMake поддерживает задание опций, подлежащих модицификациям пользователей. Опции похожи на переменные и задаются командой option , принимающей всего три аргумента: имя переменной, строковое описание переменной и значение переменной по умолчанию ( ON или OFF ):

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

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

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

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

Циклы

Циклы в CMake подобны циклам других языков программирования. В приведённом примере устанавливается значение переменной VARIABLE в Airport , а затем четыре вложенные команды последовательно исполняются пока значение переменной VARIABLE будет равняться Airport . Последняя четвёртая команда set(VARIABLE «Police station») устанавливает значение проверяемой переменной в Police station , поэтому цикл сразу остановится, не дойдя до второй итерации. Команда endwhile сигнализирует о завершении списка вложенных в цикл команд.

Данный пример цикла foreach работает следующим образом: на каждой итерации данного цикла переменной VARIABLE присваивается следующее значение из списка Give me the sugar please! , а затем исполняется команда message($) , которая выводит текущее значение переменной VARIABLE . Когда значений в списке не остаётся, то цикл завершает своё выполнение. Команда endforeach сигнализирует о завершении списка вложенных в цикл команд.

Существуют ещё 3 формы записи цикла foreach . Первый цикл в данном примере на место списка генерирует целые числа от 0 до 10, второй цикл генерирует в диапазоне от 3 до 15, а третий цикл работает в сегменте от 50 до 90, но с шагом 10.

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

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

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

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

Как отметили в комментариях, макросы в CMake подобны макросам в препроцессоре языка Си: если в тело макроса поместить команду return , то произойдёт выход из вызвавшей функции (или из всего скрипта), что демонстрирует данный пример:

В приведённом выше примере функция demonstrate_func не успеет напечатать сообщение The function was invoked! , так как прежде, на место вызова макроса demonstrate_macro будет подставлена и выполнена команда выхода.

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

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

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

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

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

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

Как упомянули в комментариях, переменные можно определять в «родительской» области видимости с помощью команды set(VARIABLE . PARENT_SCOPE) . Данный пример демонстрирует эту особенность:

Если из определения переменной VARIABLE убрать PARENT_SCOPE , то переменная будет доступна лишь функции demonstrate_variable , а в глобальной области видимости она примет пустое значение.

Заключение

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

Источник

Читайте также:  Windows 10 21h1 download
Оцените статью