2019-06-01 21:08:41 +00:00
|
|
|
|
= CMake: управление проектом
|
2019-06-02 16:31:29 +00:00
|
|
|
|
:title-separator: {sp}|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
:category: Программирование
|
|
|
|
|
:tags: программирование, cmake,
|
|
|
|
|
:toc:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Полезные ссылки
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
* https://github.com/onqtam/awesome-cmake[Каталог ссылок]
|
2020-04-09 16:23:16 +00:00
|
|
|
|
* https://cgold.readthedocs.io/en/latest/index.html[CGold: The Hitchhiker’s Guide to the CMake]
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Структура каталогов проекта
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
Файлы проекта и результаты компиляции размещаются в каталогах:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
....
|
2020-04-09 16:23:16 +00:00
|
|
|
|
└── project
|
2019-04-20 08:38:43 +00:00
|
|
|
|
├── _build
|
2020-04-06 05:49:00 +00:00
|
|
|
|
│ ├── debug
|
|
|
|
|
│ │ ├── bin
|
|
|
|
|
│ │ ├── etc
|
|
|
|
|
│ │ ├── files
|
|
|
|
|
│ │ │ ├── data
|
|
|
|
|
│ │ │ ├── lib
|
|
|
|
|
│ │ │ └── log
|
|
|
|
|
│ │ ├── include
|
|
|
|
|
│ │ └── lib
|
|
|
|
|
│ └── release
|
2019-04-20 08:38:43 +00:00
|
|
|
|
├── .git
|
2020-04-06 05:49:00 +00:00
|
|
|
|
├── .gitlab-ci
|
2019-04-20 08:38:43 +00:00
|
|
|
|
├── cmake
|
|
|
|
|
│ ├── cmlib
|
2020-04-06 05:49:00 +00:00
|
|
|
|
│ ├── doc
|
2019-04-20 08:38:43 +00:00
|
|
|
|
│ ├── etc
|
2020-04-06 05:49:00 +00:00
|
|
|
|
│ │ └── uncrustify
|
2019-04-20 08:38:43 +00:00
|
|
|
|
│ ├── find
|
|
|
|
|
│ └── generators
|
|
|
|
|
├── doc
|
|
|
|
|
├── files
|
2020-04-06 05:49:00 +00:00
|
|
|
|
│ ├── data
|
2019-04-20 08:38:43 +00:00
|
|
|
|
│ ├── etc
|
2020-04-06 05:49:00 +00:00
|
|
|
|
│ ├── lib
|
|
|
|
|
│ └── log
|
2019-04-20 08:38:43 +00:00
|
|
|
|
├── l10n
|
|
|
|
|
├── src
|
|
|
|
|
│ ├── app
|
|
|
|
|
│ └── lib
|
|
|
|
|
├── thirdparty
|
|
|
|
|
└── tools
|
2019-06-01 21:08:41 +00:00
|
|
|
|
....
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
Назначение каталогов приведено в таблице.
|
|
|
|
|
|
2020-04-08 17:09:58 +00:00
|
|
|
|
[cols="2,4",options="header",]
|
2019-06-01 21:08:41 +00:00
|
|
|
|
|===
|
2020-04-09 16:23:16 +00:00
|
|
|
|
|Каталог | Назначение
|
|
|
|
|
|`_build` | Результаты компиляции
|
|
|
|
|
|`_build/debug` | Результаты компиляции в режиме отладки
|
|
|
|
|
|`_build/debug/bin` | Исполняемые файлы
|
|
|
|
|
|`_build/debug/etc` | Символическая ссылка на каталог `cmex/files/etc`
|
|
|
|
|
|`_build/debug/files/data` | Символическая ссылка на каталог `cmex/files/data`
|
|
|
|
|
|`_build/debug/files/lib` | Символическая ссылка на каталог `cmex/files/lib`
|
|
|
|
|
|`_build/debug/files/log` | Символическая ссылка на каталог `cmex/files/log`
|
|
|
|
|
|`_build/debug/include` | Заголовочные файлы копируемые и генерируемые во время сборки
|
|
|
|
|
|`_build/debug/lib` | Статические и динамические библиотеки
|
|
|
|
|
|`_build/release` | Результаты компиляции в режиме выпуска (иерархия аналогична `debug`)
|
|
|
|
|
|`.git` | Системные файлы репозитория git
|
|
|
|
|
|`.gitlab.ci` | Шаблон правил для автоматической сборки на сервере Gitlab
|
|
|
|
|
|`cmake` | Файлы с дополнительными функциями для CMake
|
|
|
|
|
|`cmake/cmlib` | Библиотека функций для CMake
|
|
|
|
|
|`cmake/doc` | Правила для автоматической генерации документации
|
|
|
|
|
|`cmake/etc` | Файлы настроек, используемые в CMake
|
|
|
|
|
|`cmake/etc/uncrustify` | Файл настройки для программы автоматического форматирования исходных текстов
|
|
|
|
|
|`cmake/find` | Модули CMake для поиска внешних программ и библиотек
|
|
|
|
|
|`cmake/generators` | Генераторы проектов
|
|
|
|
|
|`doc` | Документация для проекта
|
|
|
|
|
|`files` | Каталог для дополнительных файлов
|
|
|
|
|
|`files/etc` | Каталог для файлов настроек проекта
|
|
|
|
|
|`files/data` | Каталог для неизменяемых файлов
|
|
|
|
|
|`files/lib` | Каталог для изменяемых файлов
|
|
|
|
|
|`files/log` | Каталог для журналов
|
|
|
|
|
|`l10n` | Файлы переводов
|
|
|
|
|
|`src` | Исходные тексты
|
|
|
|
|
|`src/app` | Исходные тексты программы
|
|
|
|
|
|`src/lib` | Исходные тексты библиотеки
|
|
|
|
|
|`thirdparty` | Исходные тексты дополнительных и сторонних проектов
|
|
|
|
|
|`tools` | Дополнительные утилиты
|
2019-06-01 21:08:41 +00:00
|
|
|
|
|===
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
Каталог `_build` создаётся, чтобы избежать попадания создаваемых во время
|
2019-06-01 21:08:41 +00:00
|
|
|
|
сборки файлов в иерархию основного проекта. Запись результатов сборки
|
|
|
|
|
проекта внутрь иерархии каталогов с исходными текстами приводит к
|
|
|
|
|
засорению формируемыми на этапе сборки файлами, которые затрудняют
|
|
|
|
|
разработку, поиск в оригинальных файлах и мешают ориентироваться в
|
|
|
|
|
проекте. При работе с несколькими типами сборки, например, отладка и
|
|
|
|
|
выпуск, появляется необходимость корректного полного удаления
|
|
|
|
|
результатов предыдущего тип сборки.
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Начало проекта
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
Проект, в котором выполнены приведённые в данном разделе действия,
|
|
|
|
|
можно посмотреть https://git.246060.ru/f1x1t/cmlib-example-base[здесь]
|
|
|
|
|
или сделать его копию командой:
|
2019-06-03 07:03:24 +00:00
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
2020-04-09 16:23:16 +00:00
|
|
|
|
git clone --recursive https://git.246060.ru/f1x1t/cmlib-example-base
|
2019-06-03 07:03:24 +00:00
|
|
|
|
----
|
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
=== Инициализация подмодулей
|
|
|
|
|
|
|
|
|
|
Для начала нужно создать каталог для проекта, перейти в него и
|
|
|
|
|
инициализировать репозиторий git:
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
mkdir cmlib-example-base
|
|
|
|
|
cd cmlib-example-base
|
|
|
|
|
git init
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
Для подключения основных подмодулей, содержащих дополнительные функции
|
|
|
|
|
для работы с проектом, и фиксации произведённого изменения нужно выполнить:
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
git submodule add git@git.246060.ru:f1x1t/cmlib.git cmake/cmlib
|
|
|
|
|
git submodule add git@git.246060.ru:f1x1t/cmake-find.git cmake/find
|
|
|
|
|
git submodule add git@git.246060.ru:f1x1t/cmake-generators.git cmake/generators
|
|
|
|
|
git submodule add git@git.246060.ru:f1x1t/cmake-doc.git cmake/doc
|
|
|
|
|
git submodule add git@git.246060.ru:f1x1t/uncrustify-config.git cmake/etc/uncrustify
|
|
|
|
|
git commit -a -m "Начало проекта"
|
|
|
|
|
----
|
|
|
|
|
|
2020-04-09 17:10:52 +00:00
|
|
|
|
Отправить изменения в проекте на сервер и сделать ветку `master` основной
|
|
|
|
|
(можно пропустить):
|
2020-04-09 16:23:16 +00:00
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
git remote add origin АДРЕС_РЕПОЗИТОРИЯ_НА_СЕРВЕРЕ
|
|
|
|
|
git push -u origin master
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
Загрузить шаблоны для автоматической сборки проекта в разных вариантах
|
|
|
|
|
программных окружений и зафиксировать изменения:
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
mkdir .gitlab-ci
|
|
|
|
|
wget -O .gitlab-ci/scheduled.yml https://git.246060.ru/f1x1t/gitlab-ci/raw/branch/master/.gitlab-ci/scheduled.yml
|
|
|
|
|
wget -O .gitlab-ci.yml https://git.246060.ru/f1x1t/gitlab-ci/raw/branch/master/.gitlab-ci.yml
|
|
|
|
|
git add .gitlab-ci.yml .gitlab-ci/scheduled.yml
|
|
|
|
|
git commit -m "Настройка автосборки"
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
Загрузить файл настройки для анализатора Clang-Tidy:
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
wget https://git.246060.ru/f1x1t/clang-tidy-config/raw/branch/master/.clang-tidy
|
|
|
|
|
git add .clang-tidy
|
|
|
|
|
git commit -m "Настройка Clang-Tidy"
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
Создать стандартные файлы и каталоги:
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
mkdir -p doc/breathe
|
|
|
|
|
touch doc/breathe/index.md.in
|
|
|
|
|
mkdir -p files/etc
|
|
|
|
|
touch files/etc/.keep-directory
|
|
|
|
|
mkdir -p files/data
|
|
|
|
|
touch files/data/.keep-directory
|
|
|
|
|
mkdir -p files/lib
|
|
|
|
|
touch files/lib/.keep-directory
|
|
|
|
|
mkdir -p files/log
|
|
|
|
|
touch files/log/.keep-directory
|
|
|
|
|
git add doc files
|
|
|
|
|
git commit -m "Стандартные файлы и каталоги"
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
Создать файл `.gitignore` для исключения каталогов и файлов из-под контроля git:
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
wget https://git.246060.ru/f1x1t/cmlib-gitignore/raw/branch/master/.gitignore
|
|
|
|
|
git add .gitignore
|
|
|
|
|
git commit -m "Шаблон для игнорирования каталогов и файлов"
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=== Базовые инструкции в CMake
|
|
|
|
|
|
|
|
|
|
В корневом каталоге проекта нужно создать файл `CMakeLists.txt`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2020-04-09 16:23:16 +00:00
|
|
|
|
# Минимальная версия CMake
|
2019-04-20 08:38:43 +00:00
|
|
|
|
cmake_minimum_required(VERSION 3.3)
|
2020-04-09 16:23:16 +00:00
|
|
|
|
|
|
|
|
|
# Предпочтительно следовать стандартам принятым в указанном диапазоне версий
|
2019-04-20 08:38:43 +00:00
|
|
|
|
cmake_policy(VERSION 3.0.2..3.7)
|
|
|
|
|
|
|
|
|
|
# Название и версия проекта и используемые языки программирования
|
2020-04-09 16:23:16 +00:00
|
|
|
|
project(cmlib-example-base VERSION 0.2.0 LANGUAGES C CXX)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
Значение версии следует формировать согласно правилам
|
2019-06-01 21:08:41 +00:00
|
|
|
|
https://semver.org/lang/ru/[семантического версионирования].
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
Для подключения функций для CMake из библиотеки CMLib, нужно добавить
|
|
|
|
|
в файл `CMakeLists.txt` строки:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# В каталоге cmake/cmlib находятся файлы с библиотечными функциями
|
|
|
|
|
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/cmlib)
|
|
|
|
|
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/cmlib)
|
|
|
|
|
else()
|
|
|
|
|
message(FATAL_ERROR "CMake library directory does not exist")
|
|
|
|
|
endif()
|
|
|
|
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/find)
|
|
|
|
|
|
|
|
|
|
include(CMLibCommon)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
В каталоге `cmake/etc` требуется создать файл `Variables.cmake`,
|
|
|
|
|
в котором требуется определить значения переменных, используемых
|
|
|
|
|
библиотекой CMLib для автоматического создания пакетов, генерации
|
|
|
|
|
документации:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 17:35:09 +00:00
|
|
|
|
[#variables.cmake]
|
2020-04-09 16:23:16 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
|
|
|
|
set(ORGANIZATION_NAME "org")
|
|
|
|
|
set(AUTHOR_NAME "John Doe")
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
set(DOXYGEN_PROJECT_TITLE "Пример проекта (начало)")
|
|
|
|
|
set(DOXYGEN_GENERATE_LATEX YES)
|
|
|
|
|
set(DOXYGEN_GENERATE_HTML YES)
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
set(CPACK_GENERATOR "TXZ;DEB")
|
|
|
|
|
set(CPACK_PACKAGE_CONTACT "John Doe <box@mail.domain>")
|
|
|
|
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CMake project example")
|
|
|
|
|
set(CPACK_DEBIAN_PACKAGE_SECTION "misc")
|
|
|
|
|
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
|
|
|
|
set(CPACK_SOURCE_IGNORE_FILES
|
|
|
|
|
.git/
|
|
|
|
|
obj.*/
|
|
|
|
|
_build
|
|
|
|
|
_output
|
|
|
|
|
files/lib
|
|
|
|
|
files/log
|
|
|
|
|
debian/tmp/
|
|
|
|
|
debian/files
|
|
|
|
|
debian/.*\\\\.log$
|
|
|
|
|
debian/.*.substvars
|
|
|
|
|
debian/stamp.*
|
|
|
|
|
CMakeLists.txt.user.*
|
|
|
|
|
cmake/lib/.git$
|
|
|
|
|
~$
|
|
|
|
|
\\\\..*\\\\.swp$)
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
Произведённые изменения можно зафиксировать:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
2020-04-09 16:23:16 +00:00
|
|
|
|
git add cmake/etc/Variables.cmake CMakeLists.txt
|
|
|
|
|
git commit -m "Подключение библиотеки CMLib"
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 16:23:16 +00:00
|
|
|
|
Чтобы проверить корректность подключения CMLib, можно выполнить команду:
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
(mkdir -p _build && cd _build && cmake .. && make && echo OK)
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
Если последней строкой вывода будет `OK`, то настройка завершена верно.
|
|
|
|
|
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Поиск системных библиотек
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 17:10:52 +00:00
|
|
|
|
Поиск программ, библиотек и заголовочных файлов, установленных в системе, можно
|
|
|
|
|
выполнять с помощью программы 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`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Поиск библиотек с помощью pkgconfig
|
2020-04-09 17:10:52 +00:00
|
|
|
|
find_package(PkgConfig REQUIRED)
|
2019-04-20 08:38:43 +00:00
|
|
|
|
pkg_check_modules(GSL REQUIRED gsl)
|
|
|
|
|
pkg_check_modules(FFTW3 REQUIRED fftw3)
|
|
|
|
|
pkg_check_modules(UDEV udev)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 17:10:52 +00:00
|
|
|
|
=== Поиск с помощью функции `find_package`
|
|
|
|
|
|
|
|
|
|
Если системная библиотека поставляется без файла описания для `pkg-config`
|
|
|
|
|
или необходимо произвести более сложный поиск, например, включающий поиск
|
|
|
|
|
исполняемого файла, то может быть написан специальный модуль для `CMake`,
|
|
|
|
|
который вызывается функцией `find_package`. Примеры вызова функции:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Поиск с помощью функции find_package
|
|
|
|
|
find_package(LibXml2)
|
2020-04-09 17:10:52 +00:00
|
|
|
|
find_package(CURL REQUIRED)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Автоматически генерируемый заголовочный файл
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 17:10:52 +00:00
|
|
|
|
На этапе конфигурирования проекта можно сгенерировать файл, в который
|
|
|
|
|
будут записаны собранные значения параметров. В библиотеке CMLib
|
2019-04-20 08:38:43 +00:00
|
|
|
|
присутствует функция `cmlib_config_hpp_generate()`, создающая файл
|
2020-04-09 17:10:52 +00:00
|
|
|
|
`${CMAKE_BINARY_DIR}/include/cmlib_private_config.hpp`, в который
|
|
|
|
|
записывается информация о имени и версии проекта, дате и типе сборки.
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Автоматически генерируемый заголовочный файл
|
|
|
|
|
cmlib_config_hpp_generate()
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2020-04-09 17:10:52 +00:00
|
|
|
|
|
2020-04-09 17:35:09 +00:00
|
|
|
|
== Удаление установленных файлов
|
|
|
|
|
|
|
|
|
|
В библиотеку CMLib добавлена цель `uninstall`, позволяющая удалить файлы,
|
|
|
|
|
которые могут быть установлены в результате выполнения цели `install`:
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
cd _build/debug
|
|
|
|
|
make install
|
|
|
|
|
make uninstall
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
== Архивирование проекта
|
|
|
|
|
|
|
|
|
|
Стандартный модуль `CPack` предназначен для архивирования исходных
|
|
|
|
|
текстов проекта и создания пакетов для установки в целевую систему.
|
|
|
|
|
Необходимые переменные устанавливаются в файле `cmake/etc/Variables.cmake`
|
2020-04-09 17:39:10 +00:00
|
|
|
|
<<variables.cmake,см. выше>>.
|
2020-04-09 17:35:09 +00:00
|
|
|
|
|
|
|
|
|
По умолчанию цель для упаковки исходных текстов называется `package_source`.
|
|
|
|
|
В библиотеке CMLib определены значения основных параметров,
|
|
|
|
|
а также дополнительная цель `dist`.
|
|
|
|
|
|
|
|
|
|
Для создания бинарных пакетов нужно выполнить в каталоге сборки команду `cpack`.
|
|
|
|
|
|
|
|
|
|
[source,sh]
|
|
|
|
|
----
|
|
|
|
|
cd _build/debug
|
|
|
|
|
make dist
|
|
|
|
|
cpack
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
== Примеры библиотек и приложений
|
|
|
|
|
|
|
|
|
|
Напишу позже.
|
|
|
|
|
|
2020-04-09 17:10:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-09 17:39:10 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Базовая библиотека
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла
|
|
|
|
|
`CMakeLists.txt` в подкаталоге `src/lib`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
add_subdirectory(src/libcmex)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
В каталоге `cmex/src/libcmex` нужно создать файл `cmex.hpp`:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#ifndef LIBCMEX_CMEX_HPP_
|
|
|
|
|
#define LIBCMEX_CMEX_HPP_
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
|
|
int32_t cmex_init(int32_t i);
|
|
|
|
|
|
|
|
|
|
#endif // LIBCMEX_CMEX_HPP_
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
файл `cmex.cpp`:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#include "cmex.hpp"
|
|
|
|
|
|
|
|
|
|
int32_t cmex_init(int32_t i = 0) {
|
2019-06-01 21:08:41 +00:00
|
|
|
|
return i;
|
2019-04-20 08:38:43 +00:00
|
|
|
|
}
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
и файл `CMakeLists.txt`:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Название основной цели и имя библиотеки в текущем каталоге
|
|
|
|
|
set(current_target cmex)
|
|
|
|
|
|
|
|
|
|
# Список файлов исходных текстов
|
|
|
|
|
set(current_target_sources
|
2020-04-04 08:51:36 +00:00
|
|
|
|
${CMAKE_CURRENT_SOURCE_DIR}/cmex.cpp
|
2019-04-20 08:38:43 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Список заголовочных файлов (используется для установки)
|
|
|
|
|
set(current_target_headers
|
2020-04-04 08:51:36 +00:00
|
|
|
|
${CMAKE_CURRENT_SOURCE_DIR}/cmex.hpp
|
2019-04-20 08:38:43 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
add_common_library(TARGET ${current_target} SOURCES ${current_target_sources})
|
|
|
|
|
common_target_properties(${current_target})
|
|
|
|
|
|
|
|
|
|
# Цель, используемая только для установки заголовочных файлов, без компиляции проекта
|
|
|
|
|
add_custom_target(${current_target}-install-headers
|
|
|
|
|
COMMAND "${CMAKE_COMMAND}"
|
|
|
|
|
-DCMAKE_INSTALL_COMPONENT=headers -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Правила для установки
|
|
|
|
|
install(TARGETS ${current_target}_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
|
|
|
if(BUILD_SHARED_LIBS)
|
|
|
|
|
install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
|
|
|
endif()
|
2019-08-29 14:34:57 +00:00
|
|
|
|
install(FILES ${CMAKE_BINARY_DIR}/include/cmlib_config.hpp ${current_target_headers}
|
2019-04-20 08:38:43 +00:00
|
|
|
|
COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${current_target})
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Базовое приложение
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла
|
|
|
|
|
`CMakeLists.txt` в подкаталоге `src/cmex`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
add_subdirectory(src/cmex)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
В каталоге `cmex/src/cmex` нужно создать файл `main.cpp`:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#include "compiler_features.hpp"
|
2019-08-29 14:34:57 +00:00
|
|
|
|
#include "cmlib_config.hpp"
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
#include "cmex.hpp"
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
2019-06-01 21:08:41 +00:00
|
|
|
|
std::cout << CMEX_COMPILER_VERSION_MAJOR << std::endl; // Значение из compiler_features.hpp
|
2019-08-29 14:34:57 +00:00
|
|
|
|
std::cout << BUILD_TYPE << std::endl; // Значение из cmlib_config.hpp
|
|
|
|
|
std::cout << CMEX_VERSION_STR << std::endl; // Значение из cmlib_config.hpp
|
2019-06-01 21:08:41 +00:00
|
|
|
|
std::cout << cmex_init(4) << std::endl; // Функция из внутренней библиотеки
|
|
|
|
|
return 0;
|
2019-04-20 08:38:43 +00:00
|
|
|
|
}
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
и файл `CMakeLists.txt`:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Название основной цели в текущем каталоге
|
|
|
|
|
set(current_target cmex_app)
|
|
|
|
|
|
|
|
|
|
# Список файлов исходных текстов
|
|
|
|
|
set(current_target_sources
|
2020-04-04 08:51:36 +00:00
|
|
|
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
2019-04-20 08:38:43 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Цель для создания исполняемого файла
|
|
|
|
|
add_executable(${current_target} ${current_target_sources})
|
|
|
|
|
common_target_properties(${current_target})
|
|
|
|
|
|
|
|
|
|
# Зависимость от библиотеки из текущего проекта
|
|
|
|
|
add_dependencies(${current_target} cmex)
|
|
|
|
|
|
|
|
|
|
# Добавление внутреннего каталога src/libcmex к списку путей для поиска заголовочных файлов
|
|
|
|
|
target_include_directories(${current_target} PUBLIC
|
|
|
|
|
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src/libcmex>)
|
|
|
|
|
|
|
|
|
|
# Имя выходного файла для цели (параметр OUTPUT_NAME)
|
|
|
|
|
set_target_properties(${current_target}
|
|
|
|
|
PROPERTIES
|
|
|
|
|
OUTPUT_NAME cmex
|
|
|
|
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Путь поиска библиотек внутри проекта
|
|
|
|
|
link_directories(${CMAKE_INSTALL_LIBDIR})
|
|
|
|
|
|
|
|
|
|
# Сначала внутренние статические библиотеки
|
|
|
|
|
target_link_libraries(${current_target} cmex_static)
|
|
|
|
|
|
|
|
|
|
# Правила для установки
|
|
|
|
|
install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Подключение внешнего проекта
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
В каталоге `cmex/thirdparty` нужно создать каталог `cmext` с проектом,
|
2019-08-29 14:34:57 +00:00
|
|
|
|
состоящим из файла `cmext.hpp`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,c]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#ifndef CMEXT_CMEXT_HPP_
|
|
|
|
|
#define CMEXT_CMEXT_HPP_
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
|
|
int32_t cmext_init(int32_t i);
|
|
|
|
|
|
|
|
|
|
#endif
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-08-29 14:34:57 +00:00
|
|
|
|
файла `cmext.cpp`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,c]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#include "cmext.hpp"
|
|
|
|
|
|
|
|
|
|
int32_t cmext_init(int32_t i = 0) {
|
2019-06-01 21:08:41 +00:00
|
|
|
|
return i;
|
2019-04-20 08:38:43 +00:00
|
|
|
|
}
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-08-29 14:34:57 +00:00
|
|
|
|
и файла `CMakeLists.txt`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
cmake_minimum_required(VERSION 3.3)
|
|
|
|
|
project(cmext)
|
|
|
|
|
|
|
|
|
|
include(GNUInstallDirs)
|
|
|
|
|
add_library(cmext cmext.cpp)
|
|
|
|
|
install(TARGETS cmext ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
|
|
|
install(FILES cmext.hpp COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME})
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
В файле `cmex/CMakeLists.txt` нужно подключить стандартный модуль
|
|
|
|
|
`ExternalProject` и описать правила для его загрузки, настройки,
|
|
|
|
|
компиляции и установки для сопряжения с текущим проектом:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Подключение внешних проектов
|
|
|
|
|
include(ExternalProject)
|
|
|
|
|
|
|
|
|
|
ExternalProject_Add(cmext
|
|
|
|
|
EXCLUDE_FROM_ALL TRUE
|
2019-06-02 16:31:29 +00:00
|
|
|
|
SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/cmext
|
2019-04-20 08:38:43 +00:00
|
|
|
|
INSTALL_DIR ${CMAKE_BINARY_DIR}
|
|
|
|
|
DOWNLOAD_COMMAND ""
|
|
|
|
|
BUILD_BYPRODUCTS <INSTALL_DIR>/lib/libcmext.a
|
|
|
|
|
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_BUILD_TYPE=Release
|
|
|
|
|
)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-03 07:03:24 +00:00
|
|
|
|
Вызовы этих функций нужно сделать до функций `add_subdirectories`, чтобы
|
|
|
|
|
в подключенных подкаталогах можно было использовать цель `cmext` для
|
|
|
|
|
определения зависимостей.
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
В файле `cmex/src/cmex/CMakeLists.txt` нужно подключить внешний проект
|
|
|
|
|
`cmext`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Зависимость от библиотеки из внешнего проекта проекта
|
|
|
|
|
add_dependencies(${current_target} cmext)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Добавление каталога, в который устанавливаются заголовочные файлы от внешнего
|
|
|
|
|
# проекта cmext, к списку путей для поиска заголовочных файлов
|
|
|
|
|
target_include_directories(${current_target} PUBLIC
|
|
|
|
|
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include/cmext>)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Библиотека из внешнего проекта cmext
|
|
|
|
|
target_link_libraries(${current_target} ${CMAKE_BINARY_DIR}/lib/libcmext.a)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно
|
|
|
|
|
вызвать функцию `cmext_init` из библиотеки, предоставляемой внешним
|
2020-04-04 08:51:36 +00:00
|
|
|
|
проектом. Например, можно заменить его содержимое на:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#include "compiler_features.hpp"
|
2019-08-29 14:34:57 +00:00
|
|
|
|
#include "cmlib_config.hpp"
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <cmext/cmext.hpp>
|
|
|
|
|
|
|
|
|
|
#include "cmex.hpp"
|
|
|
|
|
|
2019-04-20 12:01:11 +00:00
|
|
|
|
QTextStream& qStdOut()
|
|
|
|
|
{
|
|
|
|
|
static QTextStream ts(stdout);
|
|
|
|
|
return ts;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-20 08:38:43 +00:00
|
|
|
|
int main(int argc, char **argv) {
|
2019-04-20 12:01:11 +00:00
|
|
|
|
// Значение из compiler_features.hpp
|
|
|
|
|
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
|
2019-08-29 14:34:57 +00:00
|
|
|
|
// Значение из cmlib_config.hpp
|
2019-04-20 12:01:11 +00:00
|
|
|
|
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
|
2019-08-29 14:34:57 +00:00
|
|
|
|
// Значение из cmlib_config.hpp
|
2019-04-20 12:01:11 +00:00
|
|
|
|
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
|
|
|
|
|
// Функция из внутренней библиотеки
|
|
|
|
|
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
|
|
|
|
|
// Функция из внешней библиотеки
|
|
|
|
|
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
return 0;
|
2019-04-20 08:38:43 +00:00
|
|
|
|
}
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Qt5
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-08-29 14:34:57 +00:00
|
|
|
|
Для поиска необходимых компонентов Qt5 нужно в файл `cmex/CMakeLists.txt`
|
|
|
|
|
перед вызовом функции `cmlib_config_hpp_generate()` нужно добавить строку:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
find_package(Qt5 COMPONENTS Core Network Gui Widgets DBus Concurrent Sql REQUIRED)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
Библиотека CMLib автоматически подключает вызов препроцессора `moc` и
|
|
|
|
|
компилятора ресурсов `rcc`, если цель использует модуль `Core`, и
|
2019-04-20 08:38:43 +00:00
|
|
|
|
вызывает компилятор файлов описания интерфейса, если цель использует
|
|
|
|
|
модуль `Widgets`.
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
== Консольное приложение
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
В файл `cmex/src/cmex/CMakeLists.txt` добавить строки:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Qt5
|
|
|
|
|
qt_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU)
|
|
|
|
|
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
|
|
|
|
|
target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
|
|
|
|
|
|
|
|
|
|
target_link_libraries(${current_target} Qt5::Core)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
Для проверки работоспособности подключения Qt5 файл
|
|
|
|
|
`cmex/src/cmex/main.cpp` нужно заменить на:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#include "compiler_features.hpp"
|
2019-08-29 14:34:57 +00:00
|
|
|
|
#include "cmlib_config.hpp"
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
#include <QtCore>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <cmext/cmext.hpp>
|
|
|
|
|
|
|
|
|
|
#include "cmex.hpp"
|
|
|
|
|
|
2019-04-20 12:01:11 +00:00
|
|
|
|
QTextStream& qStdOut()
|
|
|
|
|
{
|
|
|
|
|
static QTextStream ts(stdout);
|
|
|
|
|
return ts;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-20 08:38:43 +00:00
|
|
|
|
int main(int argc, char **argv) {
|
2019-06-01 21:08:41 +00:00
|
|
|
|
QCoreApplication app(argc, argv);
|
|
|
|
|
QTranslator translator;
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
|
|
|
|
|
{
|
|
|
|
|
app.installTranslator(&translator);
|
|
|
|
|
}
|
2019-04-20 12:01:11 +00:00
|
|
|
|
// Значение из compiler_features.hpp
|
|
|
|
|
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
|
2019-08-29 14:34:57 +00:00
|
|
|
|
// Значение из cmlib_config.hpp
|
2019-04-20 12:01:11 +00:00
|
|
|
|
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
|
2019-08-29 14:34:57 +00:00
|
|
|
|
// Значение из cmlib_config.hpp
|
2019-04-20 12:01:11 +00:00
|
|
|
|
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
|
|
|
|
|
// Функция из внутренней библиотеки
|
|
|
|
|
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
|
|
|
|
|
// Функция из внешней библиотеки
|
|
|
|
|
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
return 0;
|
2019-04-20 08:38:43 +00:00
|
|
|
|
}
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
После сборки проекта в каталоге `cmex/l10n` появится файл
|
|
|
|
|
`cmex_app_ru_RU.ts`, в котором нужно отредактировать переводы с помощью
|
|
|
|
|
программы `linguist`. После сохранения переводов проект нужно
|
2019-06-02 16:31:29 +00:00
|
|
|
|
пересобрать, файл переводов в скомпилированном виде будет встроен в
|
2019-06-01 21:08:41 +00:00
|
|
|
|
исполняемый файл `cmex`, а доступ к нему будет осуществляться с помощью
|
|
|
|
|
кода:
|
|
|
|
|
|
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
|
|
|
|
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
|
|
|
|
|
{
|
|
|
|
|
app.installTranslator(&translator);
|
|
|
|
|
}
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
== Графическое приложение
|
|
|
|
|
|
|
|
|
|
Для создания минимального графического приложения нужно создать файл
|
|
|
|
|
описания интерфейса `cmex/src/cmex/my_main_window.ui`:
|
|
|
|
|
|
|
|
|
|
[source,xml]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
|
<ui version="4.0">
|
|
|
|
|
<class>MyMainWindow</class>
|
|
|
|
|
<widget class="QMainWindow" name="MyMainWindow">
|
|
|
|
|
<property name="geometry">
|
|
|
|
|
<rect>
|
|
|
|
|
<x>0</x>
|
|
|
|
|
<y>0</y>
|
|
|
|
|
<width>678</width>
|
|
|
|
|
<height>415</height>
|
|
|
|
|
</rect>
|
|
|
|
|
</property>
|
|
|
|
|
<property name="windowTitle">
|
|
|
|
|
<string>Main Window</string>
|
|
|
|
|
</property>
|
|
|
|
|
<widget class="QWidget" name="centralwidget"/>
|
|
|
|
|
</widget>
|
|
|
|
|
<resources/>
|
|
|
|
|
<connections/>
|
|
|
|
|
</ui>
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
заголовочный файл `cmex/src/cmex/my_main_window.hpp`:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#ifndef CMEX_MY_MAIN_WINDOW_HPP_
|
|
|
|
|
#define CMEX_MY_MAIN_WINDOW_HPP_
|
|
|
|
|
|
|
|
|
|
#include <QWidget>
|
|
|
|
|
#include "ui_my_main_window.h"
|
|
|
|
|
|
|
|
|
|
class MyMainWindow : public QWidget, private Ui::MyMainWindow {
|
2019-06-01 21:08:41 +00:00
|
|
|
|
Q_OBJECT
|
|
|
|
|
public:
|
|
|
|
|
MyMainWindow(QWidget* parent = 0);
|
|
|
|
|
virtual ~MyMainWindow();
|
2019-04-20 08:38:43 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif /* CMEX_MY_MAIN_WINDOW_HPP_ */
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
и файл с реализацией конструктора и деструктора
|
|
|
|
|
`cmex/src/cmex/my_main_window.cpp`:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#include "my_main_window.hpp"
|
|
|
|
|
|
|
|
|
|
MyMainWindow::MyMainWindow(QWidget* parent) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MyMainWindow::~MyMainWindow() {
|
|
|
|
|
|
|
|
|
|
}
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
Для отображения графического окна нужно заменить файл
|
|
|
|
|
`cmex/src/cmex/main.cpp` на:
|
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cpp]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
#include "compiler_features.hpp"
|
2019-08-29 14:34:57 +00:00
|
|
|
|
#include "cmlib_config.hpp"
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
#include <QtCore>
|
|
|
|
|
#include <QtWidgets>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <cmext/cmext.hpp>
|
|
|
|
|
|
|
|
|
|
#include "cmex.hpp"
|
|
|
|
|
#include "my_main_window.hpp"
|
|
|
|
|
|
2019-04-20 12:01:11 +00:00
|
|
|
|
QTextStream& qStdOut()
|
|
|
|
|
{
|
|
|
|
|
static QTextStream ts(stdout);
|
|
|
|
|
return ts;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-20 08:38:43 +00:00
|
|
|
|
int main(int argc, char **argv) {
|
2019-06-01 21:08:41 +00:00
|
|
|
|
QApplication app(argc, argv);
|
|
|
|
|
QTranslator translator;
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
|
|
|
|
|
{
|
|
|
|
|
app.installTranslator(&translator);
|
|
|
|
|
}
|
2019-04-20 12:01:11 +00:00
|
|
|
|
|
|
|
|
|
// Значение из compiler_features.hpp
|
|
|
|
|
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
|
2019-08-29 14:34:57 +00:00
|
|
|
|
// Значение из cmlib_config.hpp
|
2019-04-20 12:01:11 +00:00
|
|
|
|
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
|
2019-08-29 14:34:57 +00:00
|
|
|
|
// Значение из cmlib_config.hpp
|
2019-04-20 12:01:11 +00:00
|
|
|
|
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
|
|
|
|
|
// Функция из внутренней библиотеки
|
|
|
|
|
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
|
|
|
|
|
// Функция из внешней библиотеки
|
|
|
|
|
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
MyMainWindow* mmw = new MyMainWindow();
|
|
|
|
|
mmw->show();
|
|
|
|
|
return app.exec();
|
2019-04-20 08:38:43 +00:00
|
|
|
|
}
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
В файле `cmex/src/cmex/CMakeLists.txt` добавить новые файлы к списку
|
|
|
|
|
файлов, используемых для компиляции:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
set(current_target_sources
|
2020-04-04 08:51:36 +00:00
|
|
|
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
|
|
|
|
${CMAKE_CURRENT_SOURCE_DIR}/my_main_window.cpp
|
2019-04-20 08:38:43 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
set(current_target_uis
|
2020-04-04 08:51:36 +00:00
|
|
|
|
${CMAKE_CURRENT_SOURCE_DIR}/my_main_window.ui
|
2019-04-20 08:38:43 +00:00
|
|
|
|
)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
# Цель для создания исполняемого файла
|
|
|
|
|
add_executable(${current_target} ${current_target_sources} ${current_target_uis})
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
и добавить строки для подключения графических библиотек Qt5 и
|
|
|
|
|
соответствующих им заголовочных файлов:
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
2019-06-01 21:08:41 +00:00
|
|
|
|
[source,cmake]
|
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Gui_INCLUDE_DIRS})
|
|
|
|
|
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Widgets_INCLUDE_DIRS})
|
|
|
|
|
target_link_libraries(${current_target} Qt5::Gui)
|
|
|
|
|
target_link_libraries(${current_target} Qt5::Widgets)
|
2019-06-01 21:08:41 +00:00
|
|
|
|
----
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|
|
|
|
|
Во время сборки проекта в файл переводов `cmex/l10n/cmex_app_ru_RU.ts`
|
2019-06-02 23:26:28 +00:00
|
|
|
|
будут добавлены новые строки, их нужно перевести с помощью `linguist` и
|
2019-06-01 21:08:41 +00:00
|
|
|
|
снова скомпилировать проект.
|
2019-04-20 08:38:43 +00:00
|
|
|
|
|