Cmake windows cmakelists txt

Знакомство с CMake. Часть 1. Установка, CMakeLists.txt, сборка.

Введение.

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

Установка в Linux.

Для популярных дистрибутивов Linux типа Debian, Gentoo, Fedora и т.д. CMake давно лежит в официальных репозиториях. Нам нужно всего лишь установить пакет cmake с помощью менеджера пакетов. Как правило, он устанавливается в системные директории, и необходимости править переменные окружения нету. Можете проверить её работоспособность, выполнив

Если же в репозитории нет такого пакета, то можно его собрать вручную. Скачиваем Unix/Linux Source, например, cmake-3.5.0-rc3.tar.gz, распаковываем и собираем:

Если нет необходимости устанавливать в системную /usr директорию, можно в аргументе —prefix прописать нужный корень установки. По умолчанию, без явного указания —prefix, установка будет произведена в /usr/local. -j используется для ускорения сборки, например, на 4-х ядерном процессоре можно указать -j4, и сборка будет вестись параллельно в 4 потока.

Установка в Windows.

Для Windows на сайте CMake лежит установочный файл msi. Рекомендую при установке отметить галочку добавления пути в переменные окружения PATH для всех пользователей. Тогда, после перелогинивания, CMake будет доступен из любого места. Проверить можно, открыв cmd и выполнив тот же

Cmake windows cmakelists txt

На первом шаге проект нужно сконфигурировать, то есть создать финальный скрипт сборки, запустив 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 для добавления специфичных флагов компилятора, с которыми собирается цель
Читайте также:  Где хранятся обои windows интересное

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

  • 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:

Записки программиста

Основы сборки проектов на С/C++ при помощи CMake

Некоторое время назад мы с вами познакомились с Autotools. Несмотря на то, что Autotools до сих пор используется во многих известных проектах с открытым исходным кодом, инструмент этот трудно назвать особо удобным. Кроме того, нормально работает он только в *nix системах, а в каком-нибудь Windows пользоваться Autotools, скажем так, весьма непросто. В общем, Autotools — это легаси, и нормальные программисты в наше время пытаются использовать CMake или, например, SCons. В этой заметке мы познакомимся с CMake.

Говоря простыми словами, CMake — это такая штука, в которой вы описываете проект, а она вам генерирует Makefile’ы в *nix системах, проекты Visual Studio под Windows, файлы конкретных редакторов и IDE, например Sublime Text, Code::Blocks, Eclipse или KDevelop, и так далее. Несмотря на спорный в некоторых моментах синтаксис, в последнее время CMake становится стандартом де-факто в мире C/C++. В частности, CMake используется в LLVM, Qt, MariaDB, Blender, KiCad, GNU Radio и ряде других проектов. Кроме того, в CLion, IDE для C/C++ от компании JetBrains, по умолчанию также создаются проекты, основанные на CMake.

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

cmake_minimum_required ( VERSION 3.1 )

# так пишутся комментарии

find_library ( PTHREAD_LIBRARY pthread )
find_library ( PCRE_LIBRARY pcre )

include_directories ( include )
set ( CMAKE_CXX_STANDARD 17 )
set ( CMAKE_CXX_STANDARD_REQUIRED on )
set ( CMAKE_CXX_FLAGS » $ -Wall -Wextra -Werror» )

add_executable ( main src/Main.cpp src/HttpServer.cpp )

Хочется надеяться, какая строчка здесь что означает, пояснять не нужно. Затем исходники складываются в каталог src, а заголовочные файлы — в каталог include. Для сборки проекта говорим:

Просто, не правда ли?

Помимо приведенного выше find_library в CMake есть ряд скриптов для подключения конкретных библиотек. В частности, подключение OpenGL осуществляется как-то так:

find_package ( OpenGL REQUIRED )

Читайте также:  Перенос пользовательской папки windows 10

CMake можно указать конкретный тип Makefile’ов, которые вы хотите получить на выходе:

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

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

Вместо запуска напрямую make или ninja можно сказать что-то вроде:

Можно выбрать конкретный компилятор для сборки проекта

… а также указать дополнительные флаги компиляции:

В мире C/C++ нередко бывает, что сторонние библиотеки, использующие CMake, подключаются к проекту при помощи сабмодулей Git. Подключение таких библиотек к проекту осуществляется довольно просто:

cmake_minimum_required ( VERSION 2.8 )

include_directories ( deps/algorithms/include )
add_subdirectory ( deps/algorithms/src )

add_executable ( rbtree_example rbtree_example.c )
target_link_libraries ( rbtree_example CAlgorithms )

В свою очередь, у библиотеки файл src/CMakeList.txt должен быть примерно таким:

cmake_minimum_required ( VERSION 2.8 )

add_library ( CAlgorithms STATIC
struct/ilist.c
struct/rbtree.c
struct/htable.c
common/utils.c
)

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

Например, в корне библиотеки CMakeList.txt может быть таким:

cmake_minimum_required ( VERSION 2.8 )

add_subdirectory ( src )
add_subdirectory ( test )

Непосредственно тесты добавляются в проект следующим образом:

cmake_minimum_required ( VERSION 2.8 )

set ( CMAKE_C_FLAGS » $ -O0 -g» )

add_executable ( test_htable test_htable.c )
target_link_libraries ( test_htable CAlgorithms )

add_executable ( test_rbtree test_rbtree.c )
target_link_libraries ( test_rbtree CAlgorithms )

add_test ( test_htable «./test_htable» )
add_test ( test_rbtree «./test_rbtree» )

Запуск тестов осуществляется простой командой:

… выполненной в каталоге build. Если вас интересует тема написания модульных тестов на C++, она более подробно раскрыта в заметке Тестирование кода на C++ с помощью Google Test.

Если же вы используете какой-нибудь PyTest, просто допишите в CMakeList.txt что-то вроде:

find_package ( PythonInterp REQUIRED )

add_test ( NAME python_test
COMMAND py.test —capture=no $ /tests/run.py )

Вывод тестов пишется в файл Testing/Temporary/LastTest.log. Кстати, подробности о переменных окружения, доступных в CMake, таких, как CMAKE_SOURCE_DIR, можно найти здесь.

Помимо рассмотренных выше возможностей часто можно встретить поддержку сборки проектов с различными опциями. В частности, это используется в Assimp и LLDB. При сборке проекта опции выбираются так:

Опции обычно описывают в документации, но в крайнем случае их можно посмотреть и через curses-интерфейс:

В рамках одного поста, конечно, не представляется возможным рассмотреть все возможности CMake. Однако представленной выше информации вам должно вполне хватить в 90% случаев. Полноценные рабочие примеры использования CMake вы найдете, например, в этом, этом, а также в этом репозиториях на GitHub. Примеры использования опций и условных операторов можно найти в репозиториях уже упомянутых Assimp и LLDB. Ну и, конечно же, массу полезного вы найдете на официальном сайте CMake.

А пользуетесь ли вы CMake и если да, используете ли какие-то его возможности, о которых не было рассказано выше?

Дневник программиста

вторник, 10 апреля 2012 г.

Пример заготовки CMakeList.txt для простого проекта

Введение в CMake

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

  1. Unix/Linux -> Makefile (для утилиты GNU make)
  2. Windows -> VS Projects/Workspaces
  3. Apple -> Xcode

Процесс сборки проекта, при использовании cmake, состоит из следующих этапов.

  1. Создание файла конфигурации CMakeLists.txt в котором через систему команд, свойств и переменных описываются исходные файлы проекта, цель сборки и все сопутствующие сборке детали.
  2. Выполнение утилиты cmake. При это будет произведена обработка файла конфигурации CMakeLists.txt в процессе которой будет сгенерирован файл традиционного для данной операционной системы сценария сборки. Например, Makefile.
  3. Выполнение традиционных сценариев сборки. Например, утилитой make.

Используя специальные генераторы можно привязать систему CMake к определенным системам сборки, таким как Qt, Borland C++ Builder, MS Visual C++ и пр. Это свойство системы, само по себе интересно, но привязка кроссплатформенной сборки к какому-то конкретному продукту, выглядит, в общем случае, неразумно. Не считая, разумеется, вариант с поддержкой Qt SDK. Здесь особый разговор, так как сборка остается кроссплатформенной, но составляет альтернативу собственной системе сборки для Qt, qmake, которая не лишена некоторых недостатков.

Читайте также:  Что такое syslog server windows

Я вспоминаю о CMake всегда, когда не делаю проект в Qt. Вот почему.

  1. Проект не привязывается к какой-то среде разработке и его можно писать хоть в vim. Для небольших проектов это исключительно удобно. Для тех, кто относится к vim с предубеждением путь представят себе вместо vim любой другой редактор плоского кода с подсветкой синтаксиса, который им кажется удобным. Сейчас таких много под любой платформой.
  2. Проект удобно передавать в виде исходников для сборки у заказчика или какого-то иного лица потребляющего этот код. Удобно в контексте его простой компиляции. Не придется ставить среду разработки. Потребуется только наличие CMake, а это уже может быть много проще. Особенно с этим нет проблем в Linux.
  3. Сборка проекта по Makefile, который был сгенерирован системой CMake достаточно зрелищная. Во-первых, выполняется в цвете, а, во-вторых, с отображением процента исполнения.

Из написанного выше не следует, что CMake удобен только для небольших проектов. Просто большие проекты это дело особого обсуждения. Часто тут решение принимает не один человек и, в некоторых случаях, это решение определяется самой постановкой задачи. Зачем, например, городить огород, если задача заказана в MS Visual Studio и будет использована только там. В случае, если CMake допустим для проекта, то это позволит получить удобства описанные в списке выше.

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

CMakeLists.txt для простого проекта

Итак, мы начали простой проект. Создали каталог my-project и создали в нем подкаталог src для размещения источников кода нашего проекта. Напишем заготовку в файл src/main.cpp и теперь настроим CMake для сборки по этому проекту. Потом мы будем добавлять в сборку новые файлы и, возможно, библиотеки. Отразим все эти возможности в нашей заготовке.

Конфигурационный файл для системы CMake должен называться CMakeLists.txt. Расположим его в каталоге my-project и получим следующую систему файлов.

Представим шаблон файла CMakeLists.txt для простого проекта.

Рассмотрим значение представленных в файле команд.

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

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

_SOURCE_DIR в значение имени каталога проекта.

set — задает значение переменной для дальнейшего использования. Здесь создаем переменную SRC_DIR по значению подставленному из предопределенной переменной PROJECT_SOURCE_DIR и подстроки «/src». Чтобы получить значение переменной, её идентификатор надо поместить в фигурные скобки и предварить знаком доллара — $<. >.

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

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

list с первым аргументом APPEND выполняет добавление к списку, указанному вторым аргументом, элемента заданного третьим аргументом. В нашем случае, к списку под именем SRC добавлено имя файла main.cpp с путем, указанным значением переменной SRC_DIR.

add_executable — для сборки исполняемого файла представленного первым аргументом добавляет компиляционные листы, которые будут образованы по списку файлов источников, заданных вторым аргументом — значением списка SRC.

Оцените статью