Сборка библиотеки cmake linux

Информационные технологии (часть 2)

Программы для сборки

Для сборки под Windows потребуются инструменты Build Tools для Visual Studio 2019, которые можно найти на странице https://visualstudio.microsoft.com/ru/downloads/. Также потребуется программа для конфигурации сборки cmake. Для сборки в командной строке предварительно нужно запустить командный файл для Visual Studio Developer Command Prompt (в 2019 версии это команда C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\vsdevcmd ).

Для сборки под Linux рекомендуется запускать следующий контейнер docker:

Пример программы

В общей папке для компьютеров с операционными системами Linux и Windows (один или оба компьютера – виртуальные машины) создайте папку с проектом и разместите в ней следующие исходные коды:

  • в папке src файлы get_os_name.c и main.c ;
  • в папку include файл get_os_name.h .

Содержимое файла get_os_name.c :

Содержимое файла get_os_name.h :

Содержимое файла main.c :

Соберите пример под Windows:

Проверьте его работоспособность в обеих системах.

Сборка с помощью cmake

Создайте новый каталог для изучения примера сборки с помощью cmake и скопируйте в него папки src и include вместе с файлами.

Добавьте в новый каталог файл CMakeLists.txt :

В первой строчке конфигурации (программы для cmake) мы задаем минимальную версию cmake. Во второй – имя проекта.

Функция add_executable добавляет в проект задачу (target, цель) собрать исполняемый файл (программу). Первым аргументом этой функции является имя задачи, последующие аргументы – файлы исходных кодов.

Функция target_include_directories задает для задачи каталог с включаемыми (include, заголовочными) файлами. Первый аргумент – задача. Далее указывается область действия этой функции ( PRIVATE – только указанная задача, PUBLIC – весь проект). После чего указывается каталог.

В последней строке показано использование переменных cmake. Переменная PROJECT_SOURCE_DIR равна пути к каталогу проекта.

Сборка под Windows

Создайте каталог wbuild и перейдите в него.

Выполните в нем команду:

Программа cmake при запуске требует один аргумент – каталог проекта, в котором должен находиться файл CMakeLists.txt . Двоеточие как в Windows, так и в Linux означает родительский каталог по отношению к текущему.

При выполнении cmake пытается найти в операционной системе средства для сборки программ. После этого найденные средства для сборки тестируются. Далее генерируются конфигурационные файлы для сборки программы с помощью найденных средств сборки. Если на каком-либо этапе произойдет ошибка, то будет выдано соответствующее предупреждение.

При успешном выполнении cmake создаст в каталоге wbuild файл с именем каждой задачи и расширением .vcxproj . В терминах Visual Studio это называется проектом (project).

Также в этом каталоге будет создан файл с именем проекта и расширением .sln . В Visual Studio это называется решением (solution). Оно содержит в себе все проекты, соответствующие задачам в cmake, а также некоторые дополнительные проекты.

Соберите программу с помощью программы:

По умолчанию будет создана отладочная версия программы, которую можно найти в папке Debug . Можно также создать рабочую версию, указав msbuild ключ -p:Configuration=Release (результат будет в папке Release ).

Сборка под Linux

Создайте каталог lbuild и перейдите в него.

Выполните в нем команду:

Соберите программу с помощью программы:

Команда make собирает проект в текущей папки (понятие проекта в make и cmake совпадают). В результате получится готовая программа, имя которой совпадает с именем проекта. Запустите и проверьте правильность ее работы.

Читайте также:  Диск с windows system32 cmd exe

Статические библиотеки

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

Создайте новый каталог для изучения примера со статической библиотекой и скопируйте в него папки src и include вместе с файлами.

Добавьте в новый каталог файл CMakeLists.txt :

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

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

Функция target_include_directories , как и в предыдущем примере, задает каталоги с заголовочным файлами. В отличие от предыдущего примера указывается область действия PUBLIC, чтобы подключить эти заголовочные файлы и ко второй задаче (создание программы).

Функция add_executable используется так же, как и в предыдущем примере.

Функция target_link_libraries подключает ко второй задаче библиотеку, создаваемую в первой задаче.

Соберите пример под Windows и под Linux (используя те же команды, что и в предыдущем примере).

Проверьте правильность работы программ.

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

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

Динамические библиотеки

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

Создайте новый каталог для изучения примера со статической библиотекой и скопируйте в него папки src и include вместе с файлами.

Добавьте в новый каталог файл CMakeLists.txt :

Отличие конфигураций статически и динамически присоединяемых библиотек заключается в использовании ключевых слов STATIC и SHARED в функции add_library . Для Linux отличия заканчиваются.

Если сборка ведется под Windows (что проверяется командой if(WIN32) ), переменную CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS нужно установить в значение ON с помощью функции set . Это указывает cmake сгенерировать дополнительные файлы.

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

Соберите пример под Windows и под Linux (используя те же команды, что и в предыдущем примере).

Проверьте правильность работы программ.

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

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

Источник

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

Основы сборки проектов на С/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.

Читайте также:  Чем крут windows 10

Использование 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 )

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.

Читайте также:  Kali linux нет airmon

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

Источник

Сборка библиотеки 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:

Источник

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