= CMake: управление проектом v2 :title-separator: {sp}| :category: Программирование :tags: программирование, cmake, qt :icons: font :toc: include::{l10ndir}/{lang}.adoc[] == Полезные ссылки * https://github.com/onqtam/awesome-cmake[Каталог ссылок] * https://cgold.readthedocs.io/en/latest/index.html[CGold: The Hitchhiker’s Guide to the CMake] == Инструментарий В таблице приведён перечень используемых программ. .Программы [cols="2,4",options="header",] |=== |Программа | Назначение |GCC | Компилятор C/C{plus}{plus} |LLVM | Компилятор C/C{plus}{plus} и средства статического анализа |GDB | Отладчик |gcov | Анализатор покрытия кода |lcov | Генератор отчётов для gcov |Qt Creator | Среда разработки |uncrustify | Форматирование исходных текстов на языке C/C{plus}{plus} |git | Система контроля версий |pre-commit | Управление хуками git |CMake | Система управления проектом |cmake-format | Форматирование исходных текстов для CMake |Doxygen | Автоматическая генерация документации |=== При работе в совместимой с Debian операционной системе (Ubuntu, Astra Linux) требуемые программы можно установить командами: [source,sh] ---- sudo apt-get install build-essential gdb clang clang-tidy clang-tools clazy qtcreator sudo apt-get install qt5-default qttools5-dev qtbase5-private-dev qttools5-dev-tools sudo apt-get install cmake cmake-format doxygen lcov git uncrustify ---- Для дальней работы потребуется установка пакетов `myx-dev`, в котором находятся скрипты для выполнения типовых команд, и `myx-cmake` с библиотекой MyxCMake, содержащей дополнительные функции для проекта на CMake. [source,sh] ---- sudo apt-get install myx-dev myx-cmake ---- Если пакеты не доступны для `apt-get`, то установить их можно так: [source,sh] ---- sudo apt-get install wget wget -A ".deb" -c -q -np -nd -r -l 1 https://deb.246060.ru/ubuntu/focal/pool/main/m/myx-cmake/ wget -A ".deb" -c -q -np -nd -r -l 1 https://deb.246060.ru/ubuntu/focal/pool/main/m/myx-dev/ sudo dpkg -i myx-cmake*deb myx-dev*deb sudo apt-get -f install ---- Действия, приведённые в данном руководстве, необходимо выполнять в собственном репозитории. Для каждого раздела из этого документа созданы https://git.246060.ru/f1x1t?sort=oldest&q=myx-cmake[эталонные репозитории], с которыми можно сравнивать свой проект. == Структура каталогов проекта Файлы проекта и результаты компиляции размещаются в каталогах: .... └── project ├── _build │ ├── debug │ │ ├── bin │ │ ├── etc │ │ ├── include │ │ ├── lib │ │ ├── log │ │ ├── share │ │ └── var │ └── release ├── .git ├── cmake ├── doc ├── files │ ├── etc │ ├── log │ ├── share │ └── var ├── l10n ├── src │ ├── app │ └── lib ├── thirdparty └── tools .... Назначение каталогов приведено в таблице. .Назначение каталогов [cols="2,4",options="header",] |=== |Каталог | Назначение |`_build` | Результаты компиляции |`_build/debug` | Результаты компиляции в режиме отладки |`_build/debug/bin` | Исполняемые файлы |`_build/debug/etc` | Символическая ссылка на каталог `files/etc` |`_build/debug/include` | Заголовочные файлы копируемые и генерируемые во время сборки |`_build/debug/lib` | Статические и динамические библиотеки |`_build/debug/log` | Символическая ссылка на каталог `files/log` |`_build/debug/share` | Символическая ссылка на каталог `files/share` |`_build/debug/var` | Символическая ссылка на каталог `files/var` |`_build/release` | Результаты компиляции в режиме выпуска (иерархия аналогична `debug`) |`.git` | Системные файлы репозитория Git |`cmake` | Файлы с дополнительными функциями для CMake |`doc` | Документация для проекта |`files` | Каталог для дополнительных файлов |`files/etc` | Каталог для файлов настроек проекта |`files/log` | Каталог для журналов |`files/share` | Каталог для неизменяемых файлов |`files/var` | Каталог для изменяемых файлов |`l10n` | Файлы переводов |`src` | Исходные тексты |`src/app` | Исходные тексты программы |`src/lib` | Исходные тексты библиотеки |`thirdparty` | Исходные тексты дополнительных и сторонних проектов |`tools` | Дополнительные утилиты |=== Каталог `_build` создаётся, чтобы избежать попадания создаваемых во время сборки файлов в иерархию основного проекта. Запись результатов сборки проекта внутрь иерархии каталогов с исходными текстами приводит к засорению формируемыми на этапе сборки файлами, которые затрудняют разработку, поиск в оригинальных файлах и мешают ориентироваться в проекте. Компиляция проекта в отдельном каталоге обеспечивает возможность одновременной работы с несколькими типами сборки, например, отладка и выпуск. [[qtcreator]] == Qt Creator Настройка программы Qt Creator для работы с описываемыми проектами приведена link:nastroika-qt-creator.html[здесь]. Некоторые описываемые ниже проекты требуют указания ключей для CMake. Это можно сделать в командной строке, добавив к ключу флаг `-D`. Например, чтобы активировать ключ `MYX_CMAKE_CODE_COVERAGE`, нужно к списку параметров командной строки добавить `-DMYX_CMAKE_CODE_COVERAGE=ON`. Также его можно включить в Qt Creator в режиме *Проекты*. [.text-center] .Активация ключа `MYX_CMAKE_CODE_COVERAGE` в Qt Creator image::cmake-project/qtcreator-cmake-option.png[qtcmoption,pdfwidth=90%,scaledwidth=90%,align="center"] {empty} + [[base-project]] == Базовый проект Проект, в котором выполнены приведённые в данном разделе действия, можно посмотреть https://git.246060.ru/f1x1t/myx-cmake-example-base[здесь] или сделать его копию командой: [source,sh] ---- git clone --recursive https://git.246060.ru/f1x1t/myx-cmake-example-base ---- === Инициализация проекта Проект создаётся командой `myx-dev-project`. Обязательно должен быть указан параметр `-i` для инициализации проекта, также можно указать git-сервер, с которого будут загружены типовые файлы, и имя каталога для проекта. Например: [source,sh] ---- myx-dev-project -i -s git.246060.ru myx-cmake-example-base ---- Во время инициализации проекта создаются некоторые типовые каталоги: IMPORTANT: Файлы `.gitkeep` позволяют защитить каталоги от удаления (будет выводиться дополнительное предупреждение, что каталог не пуст) и обеспечивают возможность помещения каталогов с систему контроля версий Git, в которой пустые каталоги недопустимы (это правильно!). WARNING: Эти команды выполнять не нужно. [source,sh] ---- mkdir -p files/{etc,log,share,var} touch files/{etc,log,share,var}/.gitkeep ---- Автоматически создаётся типовой минимальный файл `CMakeLists.txt`, загружаются файл для форматирования исходных текстов автоматической сборки проекта на сервере GitLab, файл `.clang-tidy` с правилами для анализатора исходных текстов `.clang-tidy` и файлы сценариев для выполнения автоматических действий в репозитории, которые устанавливаются в каталог `.git/hooks`. === Базовые инструкции в CMake В корневом каталоге проекта после выполнения команды `myx-dev-project` будет создан файл `CMakeLists.txt`: [source,cmake] ---- # Минимальная версия CMake cmake_minimum_required(VERSION 3.3) # Предпочтительно следовать стандартам принятым в указанном диапазоне версий cmake_policy(VERSION 3.0.2..3.7) # Название и версия проекта и используемые языки программирования project(myx-cmake-example-base VERSION 0.2.0 LANGUAGES C CXX) ---- Значение версии проекта следует формировать согласно правилам https://semver.org/lang/ru/[семантического версионирования]. [[project-required-variables]] Для подключения функций для CMake из библиотеки MyxCMake, нужно отредактировать в файле `CMakeLists.txt` строки, содержащие обязательные переменные: [source,cmake] ---- ### # Обязательные переменные для MyxCMake ### # Название организации set(MYX_CMAKE_ORGANIZATION_NAME "Org." CACHE STRING "") # Имя автора set(MYX_CMAKE_AUTHOR_NAME "John Doe" CACHE STRING "") # Почта автора set(MYX_CMAKE_AUTHOR_EMAIL "mail@johndoe.com" CACHE STRING "") # Краткое описание проекта set(MYX_CMAKE_DESCRIPTION "Пример проекта: начало" CACHE STRING "") find_package(MyxCMake 0.4.1 REQUIRED) ---- Значения обязательных переменных, используемых библиотекой MyxCMake для архивирования исходных текстов, автоматического создания пакетов, генерации документации, следует отредактировать, после чего произведённые изменения можно зафиксировать: [source,sh] ---- git commit -m "Подключение библиотеки MyxCMake" CMakeLists.txt ---- Чтобы проверить корректность подключения MyxCMake, можно выполнить команду (пути обязательно без пробелов!): [source,sh] ---- (cmake -B_build -H. && cmake --build _build && echo OK) ---- Если используется версия CMake новее `3.15`, можно использовать официально задокументированный набор аргументов для каталогов сборки и корня проекта: [source,sh] ---- (cmake -B _build -S . && cmake --build _build && echo OK) ---- Если последней строкой вывода будет `OK`, то CMake успешно проверил окружение для сборки == Проверка программного окружения Поиск программ, библиотек и заголовочных файлов, установленных в системе, можно выполнять с помощью программы https://en.wikipedia.org/wiki/Pkg-config[`pkg-config`] или функции CMake `find_package`. В любом случае для указания того, что наличие искомого объекта обязательно для сборки проекта, используется параметр `REQUIRED`. Если требуемый компонент не будет найден, настройка проекта завершится с ошибкой и для продолжения работы будет необходимо установить недостающие пакеты. Кроме того, можно указывать требования к версии необходимого пакета. === Поиск с помощью программы `pkg-config` Программа `pkg-config` хранит базу данных параметров (обычно в каталогах `/usr/share/pkgconfig`, `/usr/lib/pkgconfig` и `/usr/lib/x86_64-linux-gnu/pkgconfig`), содержащую флаги компиляции для поиска заголовочных файлов и компоновки библиотек, установленных в систему. Для использования в CMake сначала необходимо выполнить проверку наличия программы `pkg-config` в системе и подключить определённую в модуле `PkgConfig` функцию `pkg_check_modules`. Например, для поиска библиотек `gsl`, `fftw3` и `udev` можно написать в файле `CMakeLists.txt`: [source,cmake] ---- # Поиск библиотек с помощью pkgconfig find_package(PkgConfig REQUIRED) pkg_check_modules(GSL gsl REQUIRED) pkg_check_modules(FFTW3 fftw3>=3.3.2 REQUIRED) pkg_check_modules(UDEV udev) ---- Если настройка проекта завершается с ошибкой, то нужно установить пакеты: [source,sh] ---- sudo apt-get install pkg-config libgsl-dev libfftw3-dev ---- === Поиск с помощью функции `find_package` Если системная библиотека поставляется без файла описания для `pkg-config` или необходимо произвести более сложный поиск, например, включающий поиск исполняемого файла, то может быть написан специальный модуль для CMake, который вызывается функцией `find_package`. Примеры вызова функции: [source,cmake] ---- # Поиск с помощью функции find_package find_package(LibXml2) find_package(CURL REQUIRED) find_package(Boost 1.55.0 REQUIRED) ---- Если настройка проекта завершается с ошибкой, то нужно установить пакеты: [source,sh] ---- sudo apt-get install libxml2-dev curl libcurl-dev libboost-all-dev ---- == Автоматически генерируемый заголовочный файл На этапе конфигурирования проекта можно генерировать файлы, в которые будут записаны собранные значения параметров. Функция `myx_cmake_generate_private_config_header()`, из библиотеки MyxCMake создаёт файл `${CMAKE_BINARY_DIR}/include/myx_cmake_private_config_p.hpp`, в который записывается информация о имени и версии проекта, дате и типе сборки. [source,cmake] ---- # Автоматически генерируемый заголовочный файл myx_cmake_generate_private_config_header() ---- == Автоматически генерируемый файл о состоянии проекта Функция `myx_cmake_generate_git_info_header()` библиотеки MyxCMake предоставляет возможность генерировать при каждой сборке проекта файл `${CMAKE_BINARY_DIR}/include/myx_cmake_git_info_p.hpp`, в который записывается информация о теге, текущей ветки и последнем коммите в ней. [source,cmake] ---- # Автоматически генерируемый файл с информацией о репозитории myx_cmake_generate_git_info_header() ---- == Примеры библиотек и приложений [[base-lib-project]] === Базовая библиотека Проект с базовой библиотекой реализован на основе <>. Исходные тексты содержат комментарии, объясняющие назначение используемых функций. Проект можно посмотреть https://git.246060.ru/f1x1t/myx-cmake-example-library[здесь] или сделать его копию командой: [source,sh] ---- git clone --recursive https://git.246060.ru/f1x1t/myx-cmake-example-library ---- В находящийся в корневом каталоге проекта файл `CMakeLists.txt` нужно записать: [source,cmake] ---- # Минимальная версия CMake cmake_minimum_required(VERSION 3.3) # Предпочтительно следовать стандартам принятым в указанном диапазоне версий cmake_policy(VERSION 3.0.2..3.7) # Название и версия проекта и используемые языки программирования project(myx-cmake-example-library VERSION 0.2.0 LANGUAGES C CXX) ### # Обязательные переменные для MyxCMake ### # Название организации set(MYX_CMAKE_ORGANIZATION_NAME "Org." CACHE STRING "") # Имя автора set(MYX_CMAKE_AUTHOR_NAME "John Doe" CACHE STRING "") # Почта автора set(MYX_CMAKE_AUTHOR_EMAIL "mail@johndoe.com" CACHE STRING "") # Краткое описание проекта set(MYX_CMAKE_DESCRIPTION "Пример проекта: библиотека" CACHE STRING "") find_package(MyxCMake 0.4.1 REQUIRED) # Автоматически генерируемый заголовочный файл myx_cmake_generate_private_config_header() # Автоматически генерируемый файл с информацией о репозитории myx_cmake_generate_git_info_header() # Исходные тексты библиотеки add_subdirectory(src/myx-cmake-example-library) ---- <<< В подкаталоге `src/myx-cmake-example-library` нужно создать файл `CMakeLists.txt`: [source,cmake] ---- # Название основной цели и имя библиотеки в текущем каталоге set(TRGT myx-cmake-example-library) # Список файлов исходных текстов set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/init.cpp) # Список заголовочных файлов (используется для установки) set(TRGT_hpp ${CMAKE_CURRENT_SOURCE_DIR}/init.hpp) # Функция для создания цели, результатом которой будет сборка библиотеки # Обязательно использовать тип OBJECT add_library(${TRGT} OBJECT ${TRGT_cpp} ${TRGT_hpp}) # Автоматическая установка значений свойств для цели myx_cmake_common_target_properties(${TRGT}) # Создание разделяемой библиотеки myx_cmake_add_shared_library(${TRGT}) # Создание статической библиотеки myx_cmake_add_static_library(${TRGT}) # Установка заголовочных файлов install(FILES ${TRGT_hpp} COMPONENT dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${TRGT}) # Установка файла для pkg-config myx_cmake_generate_pkgconfig(${TRGT} COMPONENT dev INSTALL_LIBRARY true) ---- <<< файл `init.hpp`: [source,cpp] ---- #ifndef MYX_CMAKE_EXAMPLE_LIBRARY_INIT_HPP_ #define MYX_CMAKE_EXAMPLE_LIBRARY_INIT_HPP_ #pragma once #include int32_t init( int32_t v ); #endif // MYX_CMAKE_EXAMPLE_LIBRARY_INIT_HPP_ ---- и файл `init.cpp`: [source,cpp] ---- #include #include int32_t init( int32_t v = 0 ) { int32_t s = 0; for ( auto i = std::abs( v ); i > 0; i-- ) { s += i; } return( s ); } ---- [[base-app-project]] === Базовое приложение Проект с базовым приложением реализован на основе <>. Исходные тексты содержат комментарии, объясняющие назначение используемых функций. Проект можно посмотреть https://git.246060.ru/f1x1t/myx-cmake-example-app[здесь] или сделать его копию командой: [source,sh] ---- git clone --recursive https://git.246060.ru/f1x1t/myx-cmake-example-app ---- <<< В находящийся в корневом каталоге проекта файл `CMakeLists.txt` нужно записать: [source,cmake] ---- # Минимальная версия CMake cmake_minimum_required(VERSION 3.3) # Предпочтительно следовать стандартам принятым в указанном диапазоне версий cmake_policy(VERSION 3.0.2..3.7) # Название и версия проекта и используемые языки программирования project(myx-cmake-example-app VERSION 0.2.0 LANGUAGES C CXX) ### # Обязательные переменные для MyxCMake ### # Название организации set(MYX_CMAKE_ORGANIZATION_NAME "Org." CACHE STRING "") # Имя автора set(MYX_CMAKE_AUTHOR_NAME "John Doe" CACHE STRING "") # Почта автора set(MYX_CMAKE_AUTHOR_EMAIL "mail@johndoe.com" CACHE STRING "") # Краткое описание проекта set(MYX_CMAKE_DESCRIPTION "Пример проекта: программа" CACHE STRING "") find_package(MyxCMake 0.4.1 REQUIRED) # Boost set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED OFF) set(Boost_USE_STATIC_RUNTIME ON) find_package(Boost 1.55.0 REQUIRED) # Автоматически генерируемый заголовочный файл myx_cmake_generate_private_config_header() # Автоматически генерируемый файл с информацией о репозитории myx_cmake_generate_git_info_header() # Исходные тексты программы add_subdirectory(src/myx-cmake-example-app) ---- В подкаталоге `src/myx-cmake-example-app` нужно создать файл `CMakeLists.txt`: [source,cmake] ---- # Название основной цели и имени программы в текущем каталоге set(TRGT myx-cmake-example-app) # Список файлов исходных текстов set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) # Функция для создания цели, результатом которой будет сборка приложения add_executable(${TRGT} ${TRGT_cpp}) myx_cmake_common_target_properties(${TRGT}) # Добавление к пути поиска заголовочных файлов target_include_directories(${TRGT} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS}) # Правила для установки install(TARGETS ${TRGT} COMPONENT main RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) ---- <<< и файл `main.cpp`: [source,cpp] ---- #include #include #include #include int32_t nsum( int32_t i = 0 ) { int32_t s = 0; for ( auto r: boost::counting_range( 1, i ) ) { s += r; } return( s ); } int main( int argc, char* argv[] ) { // Значение из myx_cmake_private_config.hpp std::cout << "Build type: " << MYX_CMAKE_BUILD_TYPE << std::endl; // Значение из myx_cmake_git_info.hpp std::cout << "Git revision: " << MYX_CMAKE_EXAMPLE_APP_GIT_REV << std::endl; auto s = nsum( argc ); std::cout << s << std::endl; return ( s ); } ---- [[base-app-ext-project]] === Подключение внешнего проекта Проект, использующий для сборки внешний проект, реализован на основе проектов <> и <>. Исходные тексты содержат комментарии, объясняющие назначение используемых функций. Проект можно посмотреть https://git.246060.ru/f1x1t/myx-cmake-example-app-ext[здесь] или сделать его копию командой: [source,sh] ---- git clone --recursive https://git.246060.ru/f1x1t/myx-cmake-example-app-ext ---- Для подключения проекта базовой библиотеки нужно выполнить: [source,sh] ---- git submodule add https://git.246060.ru/f1x1t/myx-cmake-example-library thirdparty/myx-cmake-example-library git submodule update --init --recursive ---- В находящийся в корневом каталоге проекта файл `CMakeLists.txt` нужно записать: [source,cmake] ---- # Минимальная версия CMake cmake_minimum_required(VERSION 3.3) # Предпочтительно следовать стандартам принятым в указанном диапазоне версий cmake_policy(VERSION 3.0.2..3.7) # Название и версия проекта и используемые языки программирования project(myx-cmake-example-app-ext VERSION 0.2.0 LANGUAGES C CXX) ### # Обязательные переменные для MyxCMake ### # Название организации set(MYX_CMAKE_ORGANIZATION_NAME "Org." CACHE STRING "") # Имя автора set(MYX_CMAKE_AUTHOR_NAME "John Doe" CACHE STRING "") # Почта автора set(MYX_CMAKE_AUTHOR_EMAIL "mail@johndoe.com" CACHE STRING "") # Краткое описание проекта set(MYX_CMAKE_DESCRIPTION "Пример проекта: программа с поключенной библиотекой" CACHE STRING "") find_package(MyxCMake 0.4.1 REQUIRED) # Подключение внешних проектов include(ExternalProject) ExternalProject_Add(extlib # <1> EXCLUDE_FROM_ALL TRUE SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/myx-cmake-example-library # <2> INSTALL_DIR ${CMAKE_BINARY_DIR} # <3> DOWNLOAD_COMMAND "" BUILD_BYPRODUCTS /lib/libmyx-cmake-example-library.a CMAKE_ARGS ${MYX_CMAKE_EXTERNAL_PROJECT_ARGS} -DBUILD_MYX_CMAKE_EXAMPLE_LIBRARY_SHARED=OFF # <4> ) # Исходные тексты программы add_subdirectory(src/myx-cmake-example-app-ext) ---- <1> Название цели, от которой будет зависеть основная программа <2> Каталог с внешней библиотекой <3> Каталог, в который устаналиваются результаты сборки внешней библиотеки <4> Аргументы для сборки внешней библиотеки В результате будет создана цель `extlib`, являющаяся результатом сборки подключённой библиотеки. Все функции `ExternalProject_Add` необходимо располагать перед функциям `add_subdirectories`, чтобы в указанных подкаталогах можно было использовать добавленные цели для определения зависимостей. В файле `src/myx-cmake-example-app-ext/CMakeLists.txt` после создания цели `${TRGT}` нужно подключить внешний проект `extlib`: [source,cmake] ---- # Название основной цели и имени программы в текущем каталоге set(TRGT myx-cmake-example-app-ext) # Список файлов исходных текстов set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) # Функция для создания цели, результатом которой будет сборка приложения add_executable(${TRGT} ${TRGT_cpp}) myx_cmake_common_target_properties(${TRGT}) # Зависимость от библиотеки из внешнего проекта add_dependencies(${TRGT} extlib) # Компоновка с библиотекой из внешнего проекта target_link_libraries(${TRGT} myx-cmake-example-library) ---- <<< Для проверки работоспособности в файле `src/myx-cmake-example-app-ext/main.cpp` нужно вызвать функцию `init` из библиотеки, предоставляемой внешним проектом. Например: [source,cpp] ---- #include #include int main( int argc, char* argv[] ) { auto s = init( argc ); std::cout << "Value: " << s << std::endl; return ( 0 ); } ---- === Qt5 В данном разделе будут приведены примеры создания консольного и графического приложений, а также подключения локализации, вызовы препроцессоров `moc`, `uic` и `rcc`. [[qt5-con]] ==== Консольное приложение Пример консольного приложения на Qt5 с поддержкой локализации основан на проекте <>. Исходные тексты содержат комментарии, объясняющие назначение используемых функций. Проект можно посмотреть https://git.246060.ru/f1x1t/myx-cmake-example-qt5-console[здесь] или сделать его копию командой: [source,sh] ---- git clone --recursive https://git.246060.ru/f1x1t/myx-cmake-example-qt5-console ---- <<< В находящийся в корневом каталоге проекта файл `CMakeLists.txt` нужно записать: [source,cmake] ---- # Минимальная версия CMake cmake_minimum_required(VERSION 3.3) # Предпочтительно следовать стандартам принятым в указанном диапазоне версий cmake_policy(VERSION 3.0.2..3.7) # Название и версия проекта и используемые языки программирования project(myx-cmake-example-qt5-console VERSION 0.2.0 LANGUAGES C CXX) ### # Обязательные переменные для MyxCMake ### # Название организации set(MYX_CMAKE_ORGANIZATION_NAME "Org." CACHE STRING "") # Имя автора set(MYX_CMAKE_AUTHOR_NAME "John Doe" CACHE STRING "") # Почта автора set(MYX_CMAKE_AUTHOR_EMAIL "mail@johndoe.com" CACHE STRING "") # Краткое описание проекта set(MYX_CMAKE_DESCRIPTION "Пример проекта: консольная программа Qt5" CACHE STRING "") find_package(MyxCMake 0.4.1 REQUIRED) # Qt5 find_package(Qt5 COMPONENTS Core REQUIRED) # <1> find_package(Qt5Core COMPONENTS Private REQUIRED) # <2> # Исходные тексты программы add_subdirectory(src/myx-cmake-example-qt5-console) ---- <1> Поиск необходимых компонентов Qt5 <2> Поиск приватных заголовочных файлов из пакета `qtbase5-private-dev` <<< В подкаталоге `src/myx-cmake-example-qt5-console` нужно создать файл `CMakeLists.txt`: [source,cmake] ---- # Название основной цели и имени программы в текущем каталоге set(TRGT myx-cmake-example-qt5-console) # Список файлов исходных текстов set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) # Функция для создания цели, результатом которой будет сборка приложения add_executable(${TRGT} ${TRGT_cpp}) myx_cmake_common_target_properties(${TRGT}) # Qt5: подключение заголовочных файлов target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS}) target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_PRIVATE_INCLUDE_DIRS}) # Qt5: подключение библиотек target_link_libraries(${TRGT} Qt5::Core) ---- <<< Фалй `myx-cmake-example-qt5-console/main.cpp`: [source,cpp] ---- #include #include #include int main( int argc, char** argv ) { QCoreApplication app( argc, argv ); qDebug() << "Qt5"; qDebug() << "Min Linux: " << MINLINUX_MAJOR << "." << MINLINUX_MINOR << "." << MINLINUX_PATCH; return( 0 ); } ---- [[qt5-gui]] ==== Графическое приложение, файлы описания ресурсов и интерфейсов Пример приложения на Qt5 с использованием графического интерфейса основан на проекте <>. Исходные тексты содержат комментарии, объясняющие назначение используемых функций. Проект можно посмотреть https://git.246060.ru/f1x1t/myx-cmake-example-qt5-gui[здесь] или сделать его копию командой: [source,sh] ---- git clone --recursive https://git.246060.ru/f1x1t/myx-cmake-example-qt5-gui ---- В находящийся в корневом каталоге проекта файл `CMakeLists.txt` нужно записать: [source,cmake] ---- # Минимальная версия CMake cmake_minimum_required(VERSION 3.3) # Предпочтительно следовать стандартам принятым в указанном диапазоне версий cmake_policy(VERSION 3.0.2..3.7) # Название и версия проекта и используемые языки программирования project(myx-cmake-example-qt5-gui VERSION 0.2.0 LANGUAGES CXX) ### # Обязательные переменные для MyxCMake ### # Название организации set(MYX_CMAKE_ORGANIZATION_NAME "Org." CACHE STRING "") # Имя автора set(MYX_CMAKE_AUTHOR_NAME "John Doe" CACHE STRING "") # Почта автора set(MYX_CMAKE_AUTHOR_EMAIL "mail@johndoe.com" CACHE STRING "") # Краткое описание проекта set(MYX_CMAKE_DESCRIPTION "Пример проекта: графическая программа Qt5" CACHE STRING "") find_package(MyxCMake 0.4.1 REQUIRED) # Qt5 find_package(Qt5Core COMPONENTS Private REQUIRED) find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) # Автоматически генерируемый заголовочный файл myx_cmake_generate_private_config_header() # Исходные тексты программы add_subdirectory(src/myx-cmake-example-qt5-gui) ---- В подкаталоге `src/myx-cmake-example-qt5-gui` нужно создать файл `CMakeLists.txt`: [source,cmake] ---- # Название основной цели и имени программы в текущем каталоге set(TRGT myx-cmake-example-qt5-gui) # cmake-format: off ### # Списки файлов проекта ### # Исходные коды set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_window.cpp) # Заголовочные файлы, для которых необходима обработка препроцессором moc # (содержат класс, унаследованный от QObject, использующий сигналы и/или слоты) set(TRGT_moc_hpp ${CMAKE_CURRENT_SOURCE_DIR}/test_window.hpp) # Другие заголовочные файлы set(TRGT_hpp) # Файлы с описанием графического интерфейса для Qt set(TRGT_ui ${CMAKE_CURRENT_SOURCE_DIR}/test_window.ui) # Файлы описания ресурсов, включаемых в исполняемый файл set(TRGT_qrc ${CMAKE_SOURCE_DIR}/files/share/icon.qrc) ### # Конец списков файлов ### # cmake-format: on set(TRGT_headers ${TRGT_hpp} ${TRGT_moc_hpp}) # Правило для автоматической генерации препроцессором uic qt5_wrap_ui(TRGT_ui_h ${TRGT_ui}) # Правило для автоматической генерации препроцессором moc qt5_wrap_cpp(TRGT_moc_cpp ${TRGT_moc_hpp}) # Поиск строк для локализации в файлах, перечисленных в ${TRGT_cpp} ${TRGT_ui} # Создание и обновление файлов переводов в каталоге ${CMAKE_SOURCE_DIR}/l10n # Интеграция переводов в исполняемый файл для подключения классом QTranslator myx_cmake_qt5_translation(TRGT_qrc_cpp OUTPUT_DIR ${CMAKE_SOURCE_DIR}/l10n BASE_NAME ${TRGT} SOURCES ${TRGT_cpp} ${TRGT_ui} LANGUAGES ru_RU) # Правило для автоматической генерации препроцессором qrc qt5_add_resources(TRTG_qrc_cpp ${TRGT_qrc}) # Функция для создания цели, результатом которой будет сборка приложения add_executable(${TRGT} ${TRGT_headers} ${TRGT_ui_h} ${TRGT_moc_cpp} ${TRGT_qrc_cpp} ${TRGT_cpp}) myx_cmake_common_target_properties(${TRGT}) # Qt5: подключение заголовочных файлов target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS}) target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Gui_INCLUDE_DIRS}) target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Widgets_INCLUDE_DIRS}) # Qt5: подключение библиотек target_link_libraries(${TRGT} Qt5::Core Qt5::Gui Qt5::Widgets) ---- В каталоге `files/share` создать файл описания включаемых ресурсов `icon.qrc`: [source,xml] ---- icon.png ---- и загрузить файл иконки: [source,sh] ---- wget https://git.246060.ru/f1x1t/myx-cmake-example-qt5-gui/raw/branch/master/files/share/icon.png ---- Для графического приложения нужно создать файл описания интерфейса `src/myx-cmake-example-qt5-gui/test_window.ui`: [source,xml] ---- TestWindow 00413253 Test Window 170308026 Press me ---- <<< заголовочный файл `src/myx-cmake-example-qt5-gui/test_window.hpp`: [source,cpp] ---- #ifndef TEST_WINDOW_HPP_ #define TEST_WINDOW_HPP_ #pragma once #include "ui_test_window.h" #include class TestWindow : public QMainWindow, private Ui::TestWindow { Q_OBJECT public: TestWindow( QMainWindow* parent = nullptr ); virtual ~TestWindow(); }; #endif /* TEST_WINDOW_HPP_ */ ---- и файл с реализацией конструктора, в котором проводится инициализация графических элементов, `src/myx-cmake-example-qt5-gui/test_window.cpp`: [source,cpp] ---- #include "test_window.hpp" TestWindow::TestWindow( QMainWindow* parent ) : QMainWindow ( parent ), Ui::TestWindow() { setupUi( this ); } TestWindow::~TestWindow() = default; ---- <<< Для отображения графического окна нужно создать файл `src/myx-cmake-example-qt5-gui/main.cpp`: [source,cpp] ---- #include "myx_cmake_private_config_p.hpp" #include "test_window.hpp" #include #include #include int main( int argc, char** argv ) { QApplication app( argc, argv ); // Подключение переводов в зависимости от текущей локали auto* translator = new QTranslator( QApplication::instance() ); if ( translator->load( QLocale(), MYX_CMAKE_PROJECT_NAME, QStringLiteral( "_" ), QStringLiteral( ":/qm" ) ) ) { QApplication::installTranslator( translator ); } // Установка иконки для программы QApplication::setWindowIcon( QIcon( ":/icon/icon.png" ) ); // Создание и отображение главного окна auto* w = new TestWindow(); w->show(); return( QApplication::exec() ); } ---- Для работы с файлами переводов создаётся цель `l10n`, которую нужно вызывать при появлении новых строк. После первого выполнения команды `make l10n` в корневом каталоге проекта будет создан подкаталог `l10n`, в котором появится файл с расширением `.ts`. Его можно открыть и отредактировать программой `linguist`, входящей в состав пакета `qttools5-dev-tools`. При следующей сборке программы переводы будут интегрированы в исполняемый файл. В примере показано, как экземпляр класса `QTranslator` загружает файл переводов и подключает его для отображения строк в программе. == Дополнительные возможности Библиотека MyxCMake содержит шаблонные функции для использования в программных проектах. Цели для автоматического форматирования и статического анализа исходных текстов создаются автоматически при вызове функции `myx_cmake_common_target_properties()` из библиотеки MyxCMake. Такие функции как анализ покрытия, динамический анализ, сборка из единого компилируемого файла можно подключить только после перечисления подключаемых библиотек. Для решения этой задачи используется функция `myx_cmake_common_target_properties_post_link()`, которую необходимо вызывать после всех вызовов функции `target_link_libraries()`. Пример проекта, демонстрирующего перечисленные ниже возможности можно посмотреть https://git.246060.ru/f1x1t/myx-cmake-example-features[здесь] или сделать его копию командой: [source,sh] ---- git clone --recursive https://git.246060.ru/f1x1t/myx-cmake-example-features ---- === Форматирование исходных текстов Функция `myx_cmake_common_target_properties()` создаёт для файлов, формирующих цель, дополнительные цели `${target}-format-sources-uncrustify` для форматирования исходных текстов на языке C{plus}{plus} в соответствии с правилами, перечисленными в файле `.uncrustify.cfg`, находящимся в корне проекта, а также `${target}-format-sources-dos2unix` для преобразования переводов строк в файлах к стандарту, принятому в Unix. Для проекта создаётся цель `myx-cmake-format-sources`, которая объединяет все цели, выполняющие форматирование исходных текстов. IMPORTANT: Настройка правил форматирования помогает другим разработчикам придерживаться вашего стиля программирования и отправлять изменения в ваш проект в формате, который удобен вам. Проявите заботу о своих коллегах и своём проекте! Чтобы выполнить форматирование, нужно в каталоге `${CMAKE_BINARY_DIR}` выполнить команду: [source,sh] ---- make myx-cmake-format-sources ---- При создании типового проекта командой `myx-dev-git-init` к локальному репозиторию подключается обработчик, который автоматически проверяет исходные тексты на соответствие стандарту форматирования перед выполнением фиксации (`pre-commit`). Таким образом в репозитории будут сохраняться исходные тексты, соответствующие принятым правилам форматирования. === Статический анализ исходных кодов Для работы с программами на языке C{plus}{plus} используются утилиты, выполняющие статический анализ кода и генерирующие отчёты, помогающие программисту находить и устранять ошибки. Эти программы применяют методы, позволяющие в синтаксически корректном коде находить недостатки или ошибки, которые пропускает компилятор, ценой продолжительного анализа исходных текстов. Библиотека MyxCMake поддерживает анализаторы https://github.com/KDE/clazy[clazy], https://clang.llvm.org/extra/clang-tidy[Clang Tidy], https://clang-analyzer.llvm.org[Clang Static Analyzer] и https://www.viva64.com/ru/pvs-studio[PVS-Studio]. [[analyze-clazy]] ==== clazy Функция `myx_cmake_common_target_properties()` создаёт для файлов исходных текстов, формирующих цель, дополнительную цель `${target}-analyze-clazy` для проверки исходных текстов анализатором `clang`. Для всего проекта создаётся цель `myx-cmake-analyze-clazy`, которая выполняет все цели для анализатора. Чтобы выполнить статический анализ, нужно в каталоге `${CMAKE_BINARY_DIR}` выполнить команду: [source,sh] ---- make myx-cmake-analyze-clazy ---- [[analyze-clang-check]] ==== Clang Static Analyzer Функция `myx_cmake_common_target_properties()` создаёт для файлов исходных текстов, формирующих цель, дополнительную цель `${target}-analyze-clang-check` для проверки исходных текстов анализатором `clang-check`. Для всего проекта создаётся цель `myx-cmake-analyze-clang-check`, которая выполняет все цели для анализатора. Чтобы выполнить статический анализ, нужно в каталоге `${CMAKE_BINARY_DIR}` выполнить команду: [source,sh] ---- make myx-cmake-analyze-clang-check ---- [[analyze-clang-tidy]] ==== Clang Tidy Функция `myx_cmake_common_target_properties()` создаёт для файлов исходных текстов, формирующих цель, дополнительную цель `${target}-analyze-clang-tidy` для проверки исходных текстов анализатором `clang-tidy`. Для всего проекта создаётся цель `myx-cmake-analyze-clang-tidy`, которая выполняет все цели для анализатора. Чтобы выполнить статический анализ, нужно в каталоге `${CMAKE_BINARY_DIR}` выполнить команду: [source,sh] ---- make myx-cmake-analyze-clang-tidy ---- [[analyze-pvs-studio]] ==== PVS-Studio Функция `myx_cmake_common_target_properties()` создаёт для всего проекта цель `myx-cmake-analyze-clang-tidy` для проверки исходных текстов анализатором `pvs-studio-analyzer`. Чтобы выполнить статический анализ, нужно в каталоге `${CMAKE_BINARY_DIR}` выполнить команду: [source,sh] ---- make myx-cmake-analyze-pvs-studio ---- === Автоматическое исправление кода IMPORTANT: Редактирование кода в автоматическом режиме может приводить к его неработоспособности, хотя это и маловероятно. Перед выполнением действий, приведённых в данном раздела, желательно фиксировать текущее состояние в репозитории или делать резервную копию. ==== clazy Программа clazy может преобразовывать в программах, использующих Qt, подключения сигналов и слотов старого типа, производить замену старых ключевых слов, подставлять оптимизированные способы для инициализации строк, исправлять циклы и передачу аргументов в функции для избежания лишних копирований. Для включения автоматического исправления нужно в настройках сборки проекта menu:Проекты[Настройки сборки] выбрать цель `myx-cmake-analyze-clazy`: [.text-center] .Выбор цели image::cmake-project/clazy1.png[clazyfix1,pdfwidth=90%,scaledwidth=90%,align="center"] {empty} + Затем в перечне опций включить `MYX_CMAKE_CLAZY_FIX`, нажать кнопку btn:[Применить изменения], а затем скомпилировать проект kbd:[Ctrl+B]: [.text-center] .Разрешение автозамены image::cmake-project/clazy2.png[clazyfix2,pdfwidth=90%,scaledwidth=90%,align="center"] {empty} + Результат автоматической правки исходных текстов можно посмотреть с помощью git (`git diff`). ==== Clang-Tidy Анализатор Clang-Tidy предоставляет более широкие возможности по автоматической правке кода. В проектах, использующих Qt, желательно использовать Clang-Tidy после clazy. Для включения автоматического исправления нужно в настройках сборки проекта menu:Проекты[Настройки сборки] выбрать цель `myx-cmake-analyze-clang-tidy`: [.text-center] .Выбор цели image::cmake-project/clang-tidy1.png[clangtidyfix1,pdfwidth=90%,scaledwidth=90%,align="center"] {empty} + Затем в перечне опций включить `MYX_CMAKE_CLANG_TIDY_FIX`, нажать кнопку btn:[Применить изменения], а затем скомпилировать проект kbd:[Ctrl+B]: [.text-center] .Разрешение автозамены image::cmake-project/clang-tidy2.png[clangtidyfix2,pdfwidth=90%,scaledwidth=90%,align="center"] {empty} + Результат автоматической правки исходных текстов можно посмотреть с помощью git (`git diff`). === Динамический анализ программы Динамический анализ программы позволяет ценой значительного замедления скорости работы получить дополнительную информацию о ходе её выполнения. Современные компиляторы делают вставку инструкций в определённые точки программы, во время работы программы в них собирается необходимая информация, а по её завершению предоставляется отчёт. Основная информация о работе таких анализаторов находится https://github.com/google/sanitizers/wiki[здесь]. Для обеспечения возможности подключения динамического анализа к проекту нужно выполнить функцию `myx_cmake_common_target_properties_post_link()` (обязательно после подключения всех библиотек): [source,cmake] ---- # Дополнительные функции для цели ${TRGT}. # Вызов обязательно после всех функций target_link_libraries myx_cmake_common_target_properties_post_link(${TRGT}) ---- Подключение анализатора осуществляется включением опций при запуске CMake для генерации сборочных файлов. Некоторые из опций между собой несовместимы, в случае попытки совместного использования будет выведено сообщение об ошибке. .Назначение опций для динамического анализа [cols="2m,7",options="header"] |=== | Опция | Назначение | SANITIZE_ADDRESS | Определение ошибок при работе с памятью: использование после освобождения, использование за пределами области видимости, переполнения буферов в стеке, на куче, в общей памяти, утечки памяти, нарушение порядка инициализации | SANITIZE_CFI | Определение нарушений путей исполнения инструкций программы | SANITIZE_LEAK | Определение утечек памяти | SANITIZE_LINK_STATIC | Статическая компоновка анализатора с программой | SANITIZE_MEMORY | Определение попыток доступа к неинициализированным областям памяти | SANITIZE_SS | Определение переполнения буфера стека | SANITIZE_THREAD | Определение состояние гонок | SANITIZE_UNDEFINED | Определение невыровненных и нулевых указателей, переполнения знаковых целых, преобразования типов с плавающей точкой, ведущих к переполнению результирующей переменной |=== Для проверки возможности динамической отладки можно в перечне опций включить `SANITIZE_ADDRESS`, нажать кнопку btn:[Применить изменения], а затем скомпилировать проект kbd:[Ctrl+B]. После запуска программы `myx-cmake-example-features` будет выведено сообщение об утечке памяти, показывающее, что объект типа `QFile` не был удалён. [source,text] ---- ==322360==ERROR: LeakSanitizer: detected memory leaks Indirect leak of 256 byte(s) in 1 object(s) allocated from: #0 0x7fbe8558c947 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10f947) #1 0x7fbe850efeb4 in QFile::QFile() (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x1bbeb4) #2 0x7fbe84a1d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) Indirect leak of 16 byte(s) in 1 object(s) allocated from: #0 0x7fbe8558c947 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10f947) #1 0x56089352a542 in main ../../src/myx-cmake-example-features/main.cpp:41 #2 0x7fbe84a1d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) SUMMARY: AddressSanitizer: 272 byte(s) leaked in 2 allocation(s). ---- === Анализ покрытия кода Для сбора информации о точном количестве исполнений для каждого оператора в программе используется программа https://gcc.gnu.org/onlinedocs/gcc/Gcov.html[Gcov], входящая в состав компилятора https://gcc.gnu.org[GCC]. Для генерирования отчётов в виде HTML-страниц используется программа `lcov`. Для обеспечения возможности подключения анализа покрытия кода к проекту нужно выполнить функцию `myx_cmake_common_target_properties_post_link()` (обязательно после подключения всех библиотек): [source,cmake] ---- # Дополнительные функции для цели ${TRGT}. # Вызов обязательно после всех функций target_link_libraries myx_cmake_common_target_properties_post_link(${TRGT}) ---- Анализ покрытия кода работает только для файлов, скомпилированных GCC. Во избежание ошибок его можно явно включить, используя при вызове CMake флаги `-DCMAKE_C_COMPILER=gcc` и `-DCMAKE_CXX_COMPILER=g++`. Подключение осуществляется включением опции `MYX_CMAKE_CODE_COVERAGE` при запуске CMake для генерации сборочных файлов. В результате будут созданы две дополнительные цели `${TRGT}-coverage` для сбора статистики после работы программы и `${TRGT}-coverage-report` для её вывода в виде HTML-страниц. Пример анализа покрытия кода для проекта `myx-cmake-example-features`: [source,sh] ---- cmake -B_build/cov -H. -DMYX_CMAKE_CODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug cd _build/cov make bin/myx-cmake-example-features make myx-cmake-example-features-coverage make myx-cmake-example-features-coverage-report ---- После выполнения этих команд в каталоге `myx-cmake-example-features-coverage-html` будет сформирован отчёт в виде HTML-страниц, в котором будет показано, что функция `int unused(int)` не вызывалась. === Профилирование кода Библиотека MyxCMake предоставляет вариант сборки для профилирования кода, для которого можно сгенерировать сборочные файлы, присвоив переменной `CMAKE_BUILD_TYPE` значение `Profile`: [source,sh] ---- cmake -B_build/profile -H. -DCMAKE_BUILD_TYPE=Profile cd _build/profile make bin/myx-cmake-example-features ---- По окончании работы исполняемого файла будет сгенерирован файл `gmon.out`, по данным из которого можно строить отчёты утилитой `gprof`. Например: [source,sh] ---- gprof -b bin/myx-cmake-example-features gmon.out > profiling-tree.txt gprof -b -p bin/myx-cmake-example-features gmon.out > profiling-flat.txt ---- Результаты профилирования будут записаны в файлы `profiling-tree.txt` и `profiling-flat.txt`. === Ускорение компиляции Для ускорения компиляции используется сторонний модуль https://github.com/sakra/cotire[cotire], который автоматизирует использование предварительно откомпилированных заголовочных файлов и организует пакетный режим обработки исходных файлов. Аналогичные функции встроены в CMake, начиная с версии 3.16. Для обеспечения возможностей, предоставляемых модулем cotire, нужно выполнить функцию `myx_cmake_common_target_properties_post_link()` (обязательно после подключения всех библиотек): [source,cmake] ---- # Дополнительные функции для цели ${TRGT}. # Вызов обязательно после всех функций target_link_libraries myx_cmake_common_target_properties_post_link(${TRGT}) ---- FIXME === Документирование кода Для документирования кода используются блоки комментариев, оформленные для обработки программой https://www.doxygen.nl[Doxygen]. Установка программы: [source,sh] ---- sudo apt-get install doxygen ---- Пример комментариев для исходных текстов можно посмотреть в проекте `myx-cmake-example-features`. Поддержка автоматической генерации документации реализована в функции библиотеки MyxCMake `myx_cmake_doc_doxygen()`, которую необходимо вызвать в основном файле `CMakeLists.txt` проекта. [source,cmake] ---- # Документация myx_cmake_doc_doxygen(LATEX YES HTML YES) ---- В результате будет добавлена цель `myx-cmake-doc-doxygen`, которую можно использовать после конфигурирования проекта: [source,cmake] ---- make myx-cmake-doc-doxygen ---- Шаблоны для комментирования файлов, классов и функций можно автоматически расставить в файлах исходных кодов с помощью цели `myx-cmake-doc-doxygen-append-comments`, которая доступна при наличии установленной программы `uncrustify`: [source,cmake] ---- make myx-cmake-doc-doxygen-append-comments ---- == Удаление установленных файлов В библиотеку MyxCMake добавлена цель `uninstall`, позволяющая удалить файлы, которые могут быть установлены в результате выполнения цели `install`: [source,sh] ---- cmake -B_build -H. -DCMAKE_INSTALL_PREFIX=_output # <1> cmake --build _build -t install # <2> cmake --build _build -t uninstall # <3> ---- <1> Конфигурирование проекта (каталог сборки `_build`, каталог для установки `_output`) <2> Компиляция проекта и установка в каталог `_output` <3> Удаление файлов, установленных в каталог `_output`, а также пустых каталогов == Архивирование проекта и создание пакетов Стандартный модуль `CPack` предназначен для архивирования исходных текстов проекта и создания пакетов для установки в целевую систему. Переменные, необходимые для создания пакетов и архивов, устанавливаются в начале файла `CMakeLists.txt` <>. Библиотека MyxCMake предоставляет возможность стандартного разбиения на пакеты в соответствии с критериями, приведёнными в таблице. .Критерии разбиения на пакеты [cols="3m,3m,8",options="header"] |=== | Компонент | Имя пакета | Назначение | main | proj | Основные файла проекта (исполняемые файлы, файлы данных, настроек, ресурсов) | dev | libproj-dev | Заголовочные файлы, дополнительные файлы необходимые для разработки | static | libproj-static-dev | Статические библиотеки | doc | proj-doc | Документация |=== Принадлежность устанавливаемого файла к компоненту определяется с помощью параметра `COMPONENT` функции `install()`. В компоненте `main` необходимо перечислить файлы для установки на целевую систему (исполняемые файлы, файлы настроек, файлы данных, разделяемые библиотеки), в компонентах `dev` и `static` --- для установки на систему для разработки (заголовочные файлы, статические библиотеки). Пример включения устанавливаемых файлов в компоненты можно посмотреть https://git.246060.ru/f1x1t/myxlib/src/branch/v2/src/myx/core/CMakeLists.txt#L24-L26[здесь]. Имена компонентов обязательно должны быть в нижнем регистре. По умолчанию цель для упаковки исходных текстов называется `package_source`, цель для создания общего архива скомпилированного проекта --- `package`, цель для создания пакетов в формате Debian --- `deb`. Пример работы с архивированием на основе репозитория библиотеки https://git.246060.ru/f1x1t/myxlib[MyXLib]: [source,sh] ---- git clone --recursive https://git.246060.ru/f1x1t/myxlib -b v2 ---- В корневом каталоге проекта нужно выполнить команды: [source,shell] ---- cmake -В_build/release -H. -DMYXLIB_BUILD_LIBRARIES=ON -DMYXLIB_BUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX=_output # <1> cmake --build _build/release -t install -- -j4 # <2> cmake --build _build/release -t doc-doxygen # <3> cmake --build _build/release -t package # <4> cmake --build _build/release -t package_source # <5> cmake --build _build/release -t deb # <6> ---- <1> Создание конфигурации для сборки проекта <2> Компиляция проекта <3> Генерирование документации <4> Создание архива с результатами компиляции `myx_amd64_0.4.1.tar.xz` <5> Создание архива с исходными текстами `myx-0.4.1.tar.xz` <6> Создание пакетов в формате Debian