Compare commits

..

16 Commits

Author SHA1 Message Date
d931b5aaea update 2020-04-11 14:57:13 +03:00
c41683d9e2 update 2020-04-10 18:10:40 +03:00
2abd41f429 update 2020-04-10 10:59:43 +03:00
f0cba8e7f6 update 2020-04-09 20:59:56 +03:00
8e1b48e868 update 2020-04-09 20:43:02 +03:00
d3fe32a96b update 2020-04-09 20:41:13 +03:00
62ab8db450 update 2020-04-09 20:39:10 +03:00
2af67616c8 update 2020-04-09 20:35:09 +03:00
d07e6a66f8 update 2020-04-09 20:10:52 +03:00
51adf6eb5a update 2020-04-09 19:23:16 +03:00
007afda3d1 update 2020-04-08 20:09:58 +03:00
3355f9185e update 2020-04-06 08:49:00 +03:00
1e5b6aa485 update 2020-04-04 11:51:36 +03:00
679bf869e8 Merge branch 'adoc' 2019-08-30 09:31:00 +03:00
1aaacb1df7 cmake 2019-08-29 17:34:57 +03:00
1068f502bb update 2019-07-15 21:47:09 +03:00
5 changed files with 485 additions and 254 deletions

View File

@@ -1,8 +1,8 @@
build: build:
pelican -s pelicanconf.py pelican --ignore-cache -s pelicanconf.py
web: web:
pelican -s pelicanconf-web.py pelican --ignore-cache -s pelicanconf-web.py
clean: clean:
rm -rf cache __pycache__ rm -rf cache __pycache__

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # # -*- coding: utf-8 -*- #
from __future__ import unicode_literals
import os import os
class i18n(object): class i18n(object):

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # # -*- coding: utf-8 -*- #
from __future__ import unicode_literals
import os import os
class i18n(object): class i18n(object):
@@ -13,7 +12,7 @@ class i18n(object):
LANGUAGES = ['ru'] LANGUAGES = ['ru']
NEWSTYLE = True NEWSTYLE = True
__name__ = 'i18n' __name__ = 'pelicanconf.i18n'
def register(self): def register(self):
from pelican.signals import generator_init from pelican.signals import generator_init

View File

@@ -7,29 +7,40 @@
== Полезные ссылки == Полезные ссылки
* https://github.com/onqtam/awesome-cmake[Каталог ссылок] * https://github.com/onqtam/awesome-cmake[Каталог ссылок]
* https://cgold.readthedocs.io/en/latest/index.html[CGold: The * https://cgold.readthedocs.io/en/latest/index.html[CGold: The Hitchhikers Guide to the CMake]
Hitchhikers Guide to the CMake]
== Структура каталогов проекта == Структура каталогов проекта
Файлы проекта и результаты компиляции размещаются в каталогах: Файлы проекта и результаты компиляции размещаются в каталогах:
.... ....
└── cmex └── project
├── _build ├── _build
│ ├── Debug │ ├── debug
└── Release │ ├── bin
│ │ ├── etc
│ │ ├── files
│ │ │ ├── data
│ │ │ ├── lib
│ │ │ └── log
│ │ ├── include
│ │ └── lib
│ └── release
├── .git ├── .git
├── .gitlab-ci
├── cmake ├── cmake
│ ├── cmlib │ ├── cmlib
│ ├── doc
│ ├── etc │ ├── etc
│ │ └── uncrustify
│ ├── find │ ├── find
│ └── generators │ └── generators
├── doc ├── doc
├── files ├── files
│ ├── data
│ ├── etc │ ├── etc
│ ├── share │ ├── lib
│ └── var │ └── log
├── l10n ├── l10n
├── src ├── src
│ ├── app │ ├── app
@@ -40,32 +51,43 @@ Hitchhikers Guide to the CMake]
Назначение каталогов приведено в таблице. Назначение каталогов приведено в таблице.
[cols="1,3",options="header",] [cols="2,4",options="header",]
|=== |===
|Каталог |Назначение |Каталог | Назначение
|`cmex/_build` |Результаты компиляции |`_build` | Результаты компиляции
|`cmex/_build/Debug` |Результаты компиляции в режиме отладки |`_build/debug` | Результаты компиляции в режиме отладки
|`cmex/_build/Release` |Результаты компиляции в режиме выпуска |`_build/debug/bin` | Исполняемые файлы
|`cmex/.git` |Репозиторий git |`_build/debug/etc` | Символическая ссылка на каталог `cmex/files/etc`
|`cmex/cmake` |Файлы с дополнительными функциями для CMake |`_build/debug/files/data` | Символическая ссылка на каталог `cmex/files/data`
|`cmex/cmake/cmlib` |Библиотека функций для CMake |`_build/debug/files/lib` | Символическая ссылка на каталог `cmex/files/lib`
|`cmex/cmake/find` |Модули CMake для поиска внешних программ и библиотек |`_build/debug/files/log` | Символическая ссылка на каталог `cmex/files/log`
|`cmex/cmake/etc` |Файлы настроек, используемые в CMake |`_build/debug/include` | Заголовочные файлы копируемые и генерируемые во время сборки
|`cmex/cmake/generators` |Генераторы проектов |`_build/debug/lib` | Статические и динамические библиотеки
|`cmex/doc` |Документация для проекта |`_build/release` | Результаты компиляции в режиме выпуска (иерархия аналогична `debug`)
|`cmake/files` |Каталог для дополнительных файлов |`.git` | Системные файлы репозитория git
|`cmake/files/etc` |Каталог для файлов настроек проекта |`.gitlab.ci` | Шаблон правил для автоматической сборки на сервере Gitlab
|`cmake/files/share` |Каталог для неизменяемых файлов |`cmake` | Файлы с дополнительными функциями для CMake
|`cmake/files/var` |Каталог для изменяемых файлов |`cmake/cmlib` | Библиотека функций для CMake
|`cmex/l10n` |Файлы переводов |`cmake/doc` | Правила для автоматической генерации документации
|`cmex/src` |Исходные тексты |`cmake/etc` | Файлы настроек, используемые в CMake
|`cmex/src/app` |Исходные тексты программ |`cmake/etc/uncrustify` | Файл настройки для программы автоматического форматирования исходных текстов
|`cmex/src/lib` |Исходные тексты библиотек |`cmake/find` | Модули CMake для поиска внешних программ и библиотек
|`cmex/thirdparty` |Исходные тексты сторонних проектов |`cmake/generators` | Генераторы проектов
|`cmex/tools` |Дополнительные утилиты |`doc` | Документация для проекта
|`files` | Каталог для дополнительных файлов
|`files/etc` | Каталог для файлов настроек проекта
|`files/data` | Каталог для неизменяемых файлов
|`files/lib` | Каталог для изменяемых файлов
|`files/log` | Каталог для журналов
|`l10n` | Файлы переводов
|`src` | Исходные тексты
|`src/app` | Исходные тексты программы
|`src/lib` | Исходные тексты библиотеки
|`thirdparty` | Исходные тексты дополнительных и сторонних проектов
|`tools` | Дополнительные утилиты
|=== |===
Каталог `_build` создаётся, чтобы избежать попадания получаемых во время Каталог `_build` создаётся, чтобы избежать попадания создаваемых во время
сборки файлов в иерархию основного проекта. Запись результатов сборки сборки файлов в иерархию основного проекта. Запись результатов сборки
проекта внутрь иерархии каталогов с исходными текстами приводит к проекта внутрь иерархии каталогов с исходными текстами приводит к
засорению формируемыми на этапе сборки файлами, которые затрудняют засорению формируемыми на этапе сборки файлами, которые затрудняют
@@ -74,44 +96,123 @@ Hitchhikers Guide to the CMake]
выпуск, появляется необходимость корректного полного удаления выпуск, появляется необходимость корректного полного удаления
результатов предыдущего тип сборки. результатов предыдущего тип сборки.
== Начало проекта
Проект, в котором выполнены приведённые ниже действия, можно посмотреть [[base-project]]
https://git.246060.ru/f1x1t/cmex[здесь] или сделать его копию командой: == Базовый проект
Проект, в котором выполнены приведённые в данном разделе действия,
можно посмотреть https://git.246060.ru/f1x1t/cmlib-example-base[здесь]
или сделать его копию командой:
[source,sh] [source,sh]
---- ----
git clone --recursive https://git.246060.ru/f1x1t/cmex git clone --recursive https://git.246060.ru/f1x1t/cmlib-example-base
---- ----
В каталоге `cmex` нужно создать файл `CMakeLists.txt`: === Инициализация подмодулей
Для начала нужно создать каталог для проекта, перейти в него и
инициализировать репозиторий git:
[source,sh]
----
mkdir cmlib-example-base
cd cmlib-example-base
git init
----
Для подключения основных подмодулей, содержащих дополнительные функции
для работы с проектом, и фиксации произведённого изменения нужно выполнить:
[source,sh]
----
git submodule add https://git.246060.ru/f1x1t/cmlib.git cmake/cmlib
git submodule add https://git.246060.ru/f1x1t/cmake-find.git cmake/find
git submodule add https://git.246060.ru/f1x1t/cmake-generators.git cmake/generators
git submodule add https://git.246060.ru/f1x1t/cmake-doc.git cmake/doc
git submodule add https://git.246060.ru/f1x1t/uncrustify-config.git cmake/etc/uncrustify
git commit -a -m "Начало проекта"
----
Отправить изменения в проекте на сервер и сделать ветку `master` основной
(можно пропустить):
[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`:
[source,cmake] [source,cmake]
---- ----
# Минимальная версия Cmake # Минимальная версия CMake
cmake_minimum_required(VERSION 3.3) cmake_minimum_required(VERSION 3.3)
# Предпочтительно следовать стандартам принятым в указанном диапазоне версий
cmake_policy(VERSION 3.0.2..3.7) cmake_policy(VERSION 3.0.2..3.7)
# Название и версия проекта и используемые языки программирования # Название и версия проекта и используемые языки программирования
project(cmex VERSION 0.2.0 LANGUAGES C CXX) project(cmlib-example-base VERSION 0.2.0 LANGUAGES C CXX)
---- ----
Значение версии следует формировать согласно правилам Значение версии следует формировать согласно правилам
https://semver.org/lang/ru/[семантического версионирования]. https://semver.org/lang/ru/[семантического версионирования].
В каталоге `cmex` нужно инициализировать репозиторий и установить Для подключения функций для CMake из библиотеки CMLib, нужно добавить
подмодули, содержащие функции для CMake: в файл `CMakeLists.txt` строки:
[source,sh]
----
git init .
git submodule add https://git.246060.ru/f1x1t/cmlib cmake/cmlib
git submodule add https://git.246060.ru/f1x1t/cmake-find cmake/find
git submodule add https://git.246060.ru/f1x1t/cmake-generators cmake/generators
git submodule update --remote --init
----
и подключить в файле `CMakeLists.txt`:
[source,cmake] [source,cmake]
---- ----
@@ -126,84 +227,113 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/find)
include(CMLibCommon) include(CMLibCommon)
---- ----
В файле `cmake/etc/organization.txt` записать название организации, [[variables-cmake]]
которой принадлежит проект: В каталоге `cmake/etc` требуется создать файл `Variables.cmake`,
в котором должны быть определены переменные, используемые
библиотекой CMLib для архивирования исходных текстов, автоматического
создания пакетов, генерации документации:
.... [source,cmake]
ORG, Inc. ----
.... set(ORGANIZATION_NAME "org")
set(AUTHOR_NAME "John Doe")
В файле `cmake/etc/cpack_ignore.txt` перечислить шаблоны для исключения set(DOXYGEN_PROJECT_TITLE "Пример проекта (начало)")
из архива, создаваемого целью `dist`. Например: set(DOXYGEN_GENERATE_LATEX YES)
set(DOXYGEN_GENERATE_HTML YES)
.... set(CPACK_GENERATOR "TXZ;DEB")
cmake/lib/.git$ set(CPACK_PACKAGE_CONTACT "John Doe <box@mail.domain>")
.git$ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CMake project example")
files/var set(CPACK_DEBIAN_PACKAGE_SECTION "misc")
CMakeLists.txt.user set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
~$ set(CPACK_SOURCE_IGNORE_FILES
\\\\..*\\\\.bak$ "${CMAKE_BINARY_DIR}"
\\\\..*\\\\.tmp$ "/\\\\.git/"
\\\\..*\\\\.swp$ "/\\\\.gitlab-ci/"
.... "^${CMAKE_SOURCE_DIR}/.?build.?/"
"^${CMAKE_SOURCE_DIR}/.?output.?/"
"^${CMAKE_SOURCE_DIR}/files/lib"
"^${CMAKE_SOURCE_DIR}/files/log"
"\\\\.clang-tidy$"
"\\\\.cmake-format$"
"\\\\.gitignore$"
"\\\\.gitattributes$"
"\\\\.gitmodules$"
"\\\\.gitlab-ci.yml"
"CMakeLists.txt.user.*"
"~$"
"\\\\.swp$")
----
Чтобы проверить корректность файла `CMakeLists.txt`, нужно создать Произведённые изменения можно зафиксировать:
каталог `_build` в каталоге `cmex`, перейти в него и выполнить команды:
[source,sh] [source,sh]
---- ----
cmake .. git add cmake/etc/Variables.cmake CMakeLists.txt
make git commit -m "Подключение библиотеки CMLib"
---- ----
Чтобы проверить корректность подключения CMLib, можно выполнить команду:
[source,sh]
----
(mkdir -p _build && cd _build && cmake .. && make && echo OK)
----
Если последней строкой вывода будет `OK`, то настройка завершена верно.
== Поиск системных библиотек == Поиск системных библиотек
Системные библиотеки можно искать с помощью программы `pkgconfig`, Поиск программ, библиотек и заголовочных файлов, установленных в системе, можно
которая хранит базу данных параметров, включающую пути к заголовочным выполнять с помощью программы https://en.wikipedia.org/wiki/Pkg-config[`pkg-config`]
файлами и перечни библиотек, необходимых для компоновки. Сначала или функции CMake `find_package`. В любом случае для указания того,
производится наличие модуля `PkgConfig`, в котором определена функция что наличие искомого объекта обязательно для сборки, используется
`pkg_check_modules`, которая и осуществляет поиск. Например, для поиска параметр `REQUIRED`.
библиотек `gsl`, `fftw3` и `udev` можно написать:
=== Поиск с помощью программы `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] [source,cmake]
---- ----
# Поиск библиотек с помощью pkgconfig # Поиск библиотек с помощью pkgconfig
find_package(PkgConfig) find_package(PkgConfig REQUIRED)
pkg_check_modules(GSL REQUIRED gsl) pkg_check_modules(GSL REQUIRED gsl)
pkg_check_modules(FFTW3 REQUIRED fftw3) pkg_check_modules(FFTW3 REQUIRED fftw3)
pkg_check_modules(UDEV udev) pkg_check_modules(UDEV udev)
---- ----
Если системная библиотека поставляется без файла описания для === Поиск с помощью функции `find_package`
`pkgconfig`, то для её поиска может быть написан специальный модуль для
`CMake`, который вызывается функцией `find_package`. Кроме того функция Если системная библиотека поставляется без файла описания для `pkg-config`
`find_package` может возвращать дополнительные значения, например, пути или необходимо произвести более сложный поиск, например, включающий поиск
к исполняемым файлам. исполняемого файла, то может быть написан специальный модуль для `CMake`,
который вызывается функцией `find_package`. Примеры вызова функции:
[source,cmake] [source,cmake]
---- ----
# Поиск с помощью функции find_package # Поиск с помощью функции find_package
find_package(LibXml2) find_package(LibXml2)
find_package(CURL) find_package(CURL REQUIRED)
---- ----
Если для библиотеки нет модуля, выполняющего её поиск, то можно
произвести поиск с помощью функции `find_library`. Например,
[source,cmake]
----
# Поиск библиотеки с помощью функции find_library
find_library(MATHGL mgl PATHS /usr/lib /usr/lib/x86_64-linux-gnu)
find_library(MATHGLQT5 mgl-qt5 PATHS /usr/lib /usr/lib/x86_64-linux-gnu)
----
== Автоматически генерируемый заголовочный файл == Автоматически генерируемый заголовочный файл
На этапе конфигурирования проекта можно создать файл, в который будут На этапе конфигурирования проекта можно сгенерировать файл, в который
записаны параметры, полученные на данной стадии. В библиотеке CMLib будут записаны собранные значения параметров. В библиотеке CMLib
присутствует функция `cmlib_config_hpp_generate()`, создающая файл присутствует функция `cmlib_config_hpp_generate()`, создающая файл
`${CMAKE_BUILD_DIR}/include/config.hpp`, в который записывается `${CMAKE_BINARY_DIR}/include/cmlib_private_config.hpp`, в который
информация о имени и версии проекта, дате и типе сборки. записывается информация о имени и версии проекта, дате и типе сборки.
[source,cmake] [source,cmake]
---- ----
@@ -211,150 +341,266 @@ find_library(MATHGLQT5 mgl-qt5 PATHS /usr/lib /usr/lib/x86_64-linux-gnu)
cmlib_config_hpp_generate() cmlib_config_hpp_generate()
---- ----
== Базовая библиотека
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла == Удаление установленных файлов
`CMakeLists.txt` в подкаталоге `src/lib`:
В библиотеку CMLib добавлена цель `uninstall`, позволяющая удалить файлы,
которые могут быть установлены в результате выполнения цели `install`:
[source,sh]
----
cd _build/debug
make install
make uninstall
----
== Архивирование проекта и создание пакетов
Стандартный модуль `CPack` предназначен для архивирования исходных
текстов проекта и создания пакетов для установки в целевую систему.
Необходимые переменные устанавливаются в файле `cmake/etc/Variables.cmake`
<<variables-cmake,см. выше>>.
Устанавливаемые файлы делятся на две группы `MAIN` и `DEV` с помощью
параметра `COMPONENT` функции `install`. В группу `MAIN` необходимо
помещать файлы для установки на целевую систему (исполняемые файлы,
файлы настроек, файлы данных, разделяемые библиотеки), а в группу `DEV` ---
для установки на систему для разработки (заголовочные файлы, статические
библиотеки).
По умолчанию цель для упаковки исходных текстов называется `package_source`.
Бинарные пакеты создаются программой `cpack`. Пример:
[source,sh]
----
cd _build/debug
make
make package_source
cpack
----
== Примеры библиотек и приложений
=== Базовая библиотека
Проект с базовой библиотекой реализован на основе <<base-project,базового проекта>>.
Исходные тексты содержат комментарии, объясняющие назначение используемых функций.
Проект можно посмотреть https://git.246060.ru/f1x1t/cmlib-example-library[здесь]
или сделать его копию командой:
[source,sh]
----
git clone --recursive https://git.246060.ru/f1x1t/cmlib-example-library
----
В файл `CMakeLists.txt`, находящийся в корневом каталоге проекта, нужно добавить:
[source,cmake] [source,cmake]
---- ----
add_subdirectory(src/libcmex) # Поиск библиотеки 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 COMPONENTS headers)
# Автоматически генерируемый заголовочный файл
cmlib_config_hpp_generate()
# Каталог с исходными текстами библиотеки
add_subdirectory(src/cmlib-example)
# Документация
add_subdirectory(cmake/doc)
# Создание вспомогательных символических ссылок
add_dependencies(cmlib-example create_auxilary_symlinks)
---- ----
В каталоге `cmex/src/libcmex` нужно создать файл `cmex.hpp`:
[source,cpp] В подкаталоге `src/cmlib-example` нужно создать файл `CMakeLists.txt`:
----
#ifndef LIBCMEX_CMEX_HPP_
#define LIBCMEX_CMEX_HPP_
#include <stdint.h>
int32_t cmex_init(int32_t i);
#endif // LIBCMEX_CMEX_HPP_
----
файл `cmex.cpp`:
[source,cpp]
----
#include "cmex.hpp"
int32_t cmex_init(int32_t i = 0) {
return i;
}
----
и файл `CMakeLists.txt`:
[source,cmake] [source,cmake]
---- ----
# Название основной цели и имя библиотеки в текущем каталоге # Название основной цели и имя библиотеки в текущем каталоге
set(current_target cmex) set(TRGT cmlib-example)
# Список файлов исходных текстов # Список файлов исходных текстов
set(current_target_sources set(TRGT_sources ${CMAKE_CURRENT_SOURCE_DIR}/init.cpp)
cmex.cpp
)
# Список заголовочных файлов (используется для установки) # Список заголовочных файлов (используется для установки)
set(current_target_headers set(TRGT_headers ${CMAKE_CURRENT_SOURCE_DIR}/init.hpp)
cmex.hpp
)
add_common_library(TARGET ${current_target} SOURCES ${current_target_sources}) # Функция для создания цели, результатом которой будет сборка библиотеки
common_target_properties(${current_target}) add_common_library(TARGET ${TRGT} SOURCES ${TRGT_sources})
common_target_properties(${TRGT})
# Цель, используемая только для установки заголовочных файлов, без компиляции проекта # Добавление к пути поиска заголовочных файлов
add_custom_target(${current_target}-install-headers target_include_directories(${TRGT} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=headers -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
# Правила для установки # Цель, используемая только для установки
install(TARGETS ${current_target}_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) # заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=DEV -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
# Установка статической библиотеки
install(TARGETS ${TRGT}_static COMPONENT DEV ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
# Установка динамической библиотеки
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)
install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS ${TRGT}_shared COMPONENT DEV LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif() endif()
install(FILES ${CMAKE_BINARY_DIR}/include/config.hpp ${current_target_headers}
COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${current_target}) # Установка заголовочных файлов
install(FILES ${TRGT_headers} COMPONENT DEV DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${TRGT})
# Установка файла для pkg-config
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT DEV DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
---- ----
== Базовое приложение
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла файл `init.hpp`:
`CMakeLists.txt` в подкаталоге `src/cmex`:
[source,cpp]
----
#ifndef CMLIB_EXAMPLE_HPP_
#define CMLIB_EXAMPLE_HPP_
#include <stdint.h>
int32_t cmlib_example_init(int32_t i);
#endif // CMLIB_EXAMPLE_HPP_
----
и файл `init.cpp`:
[source,cpp]
----
#include "init.hpp"
#include <boost/range/counting_range.hpp>
int32_t cmlib_example_init(int32_t i = 0)
{
int32_t s = 0;
for ( auto r : boost::counting_range( 1, i ) )
{
s += r;
}
return s;
}
----
=== Базовое приложение
Проект с базовым приложением реализован на основе <<base-project,базового проекта>>.
Исходные тексты содержат комментарии, объясняющие назначение используемых функций.
Проект можно посмотреть https://git.246060.ru/f1x1t/cmlib-example-app[здесь]
или сделать его копию командой:
[source,sh]
----
git clone --recursive https://git.246060.ru/f1x1t/cmlib-example-app
----
В файл `CMakeLists.txt`, находящийся в корневом каталоге проекта, нужно добавить:
[source,cmake] [source,cmake]
---- ----
add_subdirectory(src/cmex) # 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 COMPONENTS headers)
# Автоматически генерируемый заголовочный файл
cmlib_config_hpp_generate()
# Приложение
add_subdirectory(src/cmlib-example)
# Документация
add_subdirectory(cmake/doc)
# Создание вспомогательных символических ссылок
add_dependencies(cmlib-example create_auxilary_symlinks)
---- ----
В каталоге `cmex/src/cmex` нужно создать файл `main.cpp`: В подкаталоге `src/cmlib-example` нужно создать файл `CMakeLists.txt`:
[source,cmake]
----
# Название основной цели и имя библиотеки в текущем каталоге
set(TRGT cmlib-example)
# Список файлов исходных текстов
set(TRGT_sources ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
# Функция для создания цели, результатом которой будет сборка приложения
add_executable(${TRGT} ${TRGT_sources})
common_target_properties(${TRGT})
# Добавление к пути поиска заголовочных файлов
target_include_directories(${TRGT} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
# Имя целевого каталога и выходного файла для цели
set_target_properties(${TRGT}
PROPERTIES
OUTPUT_NAME ${TRGT}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
)
# Правила для установки
install(TARGETS ${TRGT} COMPONENT MAIN RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
----
и файл `main.cpp`:
[source,cpp] [source,cpp]
---- ----
#include "compiler_features.hpp" #include "compiler_features.hpp"
#include "config.hpp" #include "cmlib_private_config.hpp"
#include <iostream> #include <iostream>
#include <boost/range/counting_range.hpp>
#include "cmex.hpp" 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) { int main(int argc, char* argv[])
std::cout << CMEX_COMPILER_VERSION_MAJOR << std::endl; // Значение из compiler_features.hpp {
std::cout << BUILD_TYPE << std::endl; // Значение из config.hpp // Значение из compiler_features.hpp
std::cout << CMEX_VERSION_STR << std::endl; // Значение из config.hpp std::cout << CMLIB_EXAMPLE_APP_COMPILER_VERSION_MAJOR << std::endl;
std::cout << cmex_init(4) << std::endl; // Функция из внутренней библиотеки // Значение из cmlib_private_config.hpp
return 0; std::cout << CMLIB_BUILD_TYPE << std::endl;
// Значение из cmlib_private_config.hpp
std::cout << CMLIB_BUILD_DATE << std::endl;
auto s = nsum( argc );
std::cout << s << std::endl;
return ( s );
} }
---- ----
и файл `CMakeLists.txt`:
[source,cmake] ПИШУ ЗДЕСЬ!!!
----
# Название основной цели в текущем каталоге
set(current_target cmex_app)
# Список файлов исходных текстов
set(current_target_sources
main.cpp
)
# Цель для создания исполняемого файла
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})
----
== Подключение внешнего проекта == Подключение внешнего проекта
В каталоге `cmex/thirdparty` нужно создать каталог `cmext` с проектом, В каталоге `cmex/thirdparty` нужно создать каталог `cmext` с проектом,
состоящим из файлов `cmext.hpp`: состоящим из файла `cmext.hpp`:
[source,c] [source,c]
---- ----
@@ -368,7 +614,7 @@ int32_t cmext_init(int32_t i);
#endif #endif
---- ----
`cmext.cpp`: файла `cmext.cpp`:
[source,c] [source,c]
---- ----
@@ -379,7 +625,7 @@ int32_t cmext_init(int32_t i = 0) {
} }
---- ----
и `CMakeLists.txt`: и файла `CMakeLists.txt`:
[source,cmake] [source,cmake]
---- ----
@@ -440,12 +686,12 @@ target_link_libraries(${current_target} ${CMAKE_BINARY_DIR}/lib/libcmext.a)
Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно
вызвать функцию `cmext_init` из библиотеки, предоставляемой внешним вызвать функцию `cmext_init` из библиотеки, предоставляемой внешним
проектом. Например: проектом. Например, можно заменить его содержимое на:
[source,cpp] [source,cpp]
---- ----
#include "compiler_features.hpp" #include "compiler_features.hpp"
#include "config.hpp" #include "cmlib_config.hpp"
#include <iostream> #include <iostream>
#include <cmext/cmext.hpp> #include <cmext/cmext.hpp>
@@ -461,9 +707,9 @@ QTextStream& qStdOut()
int main(int argc, char **argv) { int main(int argc, char **argv) {
// Значение из compiler_features.hpp // Значение из compiler_features.hpp
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl; qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
// Значение из config.hpp // Значение из cmlib_config.hpp
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl; qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
// Значение из config.hpp // Значение из cmlib_config.hpp
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl; qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
// Функция из внутренней библиотеки // Функция из внутренней библиотеки
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl; qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
@@ -476,8 +722,8 @@ int main(int argc, char **argv) {
== Qt5 == Qt5
Для поиска необходимых компонентов Qt5 нужно в файл Для поиска необходимых компонентов Qt5 нужно в файл `cmex/CMakeLists.txt`
`cmex/CMakeLists.txt` добавить строки: перед вызовом функции `cmlib_config_hpp_generate()` нужно добавить строку:
[source,cmake] [source,cmake]
---- ----
@@ -509,7 +755,7 @@ target_link_libraries(${current_target} Qt5::Core)
[source,cpp] [source,cpp]
---- ----
#include "compiler_features.hpp" #include "compiler_features.hpp"
#include "config.hpp" #include "cmlib_config.hpp"
#include <QtCore> #include <QtCore>
#include <iostream> #include <iostream>
@@ -533,9 +779,9 @@ int main(int argc, char **argv) {
} }
// Значение из compiler_features.hpp // Значение из compiler_features.hpp
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl; qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
// Значение из config.hpp // Значение из cmlib_config.hpp
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl; qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
// Значение из config.hpp // Значение из cmlib_config.hpp
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl; qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
// Функция из внутренней библиотеки // Функция из внутренней библиотеки
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl; qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
@@ -632,7 +878,7 @@ MyMainWindow::~MyMainWindow() {
[source,cpp] [source,cpp]
---- ----
#include "compiler_features.hpp" #include "compiler_features.hpp"
#include "config.hpp" #include "cmlib_config.hpp"
#include <QtCore> #include <QtCore>
#include <QtWidgets> #include <QtWidgets>
@@ -659,9 +905,9 @@ int main(int argc, char **argv) {
// Значение из compiler_features.hpp // Значение из compiler_features.hpp
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl; qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
// Значение из config.hpp // Значение из cmlib_config.hpp
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl; qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
// Значение из config.hpp // Значение из cmlib_config.hpp
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl; qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
// Функция из внутренней библиотеки // Функция из внутренней библиотеки
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl; qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
@@ -680,12 +926,12 @@ int main(int argc, char **argv) {
[source,cmake] [source,cmake]
---- ----
set(current_target_sources set(current_target_sources
main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
my_main_window.cpp ${CMAKE_CURRENT_SOURCE_DIR}/my_main_window.cpp
) )
set(current_target_uis set(current_target_uis
my_main_window.ui ${CMAKE_CURRENT_SOURCE_DIR}/my_main_window.ui
) )
---- ----
@@ -710,28 +956,3 @@ target_link_libraries(${current_target} Qt5::Widgets)
будут добавлены новые строки, их нужно перевести с помощью `linguist` и будут добавлены новые строки, их нужно перевести с помощью `linguist` и
снова скомпилировать проект. снова скомпилировать проект.
== Удаление установленных файлов
В библиотеку CMLib добавлена цель `uninstall`, позволяющая удалить
файлы, перечисленные в файле `${CMAKE_BUILD_DIR}/install_manifest.txt`.
== Архивирование проекта
Стандартный модуль `CPack` осуществляет архивирование проекта. В файле
`cproj/cmake/etc/cpack_ignore.txt` определён список типовых масок файлов
для исключения из архива:
....
.git$
files/var
CMakeLists.txt.user
~$
\\\\..*\\\\.tmp$
\\\\..*\\\\.bak$
\\\\..*\\\\.swp$
\\\\..*\\\\.o$
....
По умолчанию цель для упаковки проекта называется `package_source`. В
библиотеке CMLib определены значения основных параметров, а также
дополнительная цель `dist`.

View File

@@ -13,14 +13,14 @@
[source,sh] [source,sh]
---- ----
sudo apt-get install clang-tidy-6.0 sudo apt-get install clang-tidy-10
---- ----
Использование: Использование:
[source,sh] [source,sh]
---- ----
cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-6.0" path/to/source cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-10" path/to/source
---- ----
В каталоге проекта нужно создать файл `.clang-tidy` в формате YAML со В каталоге проекта нужно создать файл `.clang-tidy` в формате YAML со
@@ -30,12 +30,25 @@ cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-6.0" path/to/source
---- ----
--- ---
Checks: '-*, Checks: '-*,
clang-diagnostic-*, bugprone-*,
readability-*, clang-analyzer-*,
modernize-*, cppcoreguidelines-*,
cppcoreguidelines-*, google-*,
google-*, llvm-*,
bugprone-*' misc-*,
modernize-*,
readability-*,
performance-*,
portability-*,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-readability-magic-numbers,
-readability-else-after-return,
-modernize-use-trailing-return-type,
-modernize-avoid-c-arrays,
-performance-no-automatic-move,
'
CheckOptions: CheckOptions:
- key: readability-identifier-naming.ClassCase - key: readability-identifier-naming.ClassCase
value: CamelCase value: CamelCase
@@ -124,7 +137,7 @@ cmake -DCMAKE_LINK_WHAT_YOU_USE=TRUE ..
[source,sh] [source,sh]
---- ----
sudo apt-get install clazy clang-6.0 sudo apt-get install clazy clang-9
---- ----
Использование: Использование:
@@ -132,7 +145,6 @@ sudo apt-get install clazy clang-6.0
[source,sh] [source,sh]
---- ----
CLAZY_CHECKS=level2 cmake -DCMAKE_CXX_COMPILER=clazy .. CLAZY_CHECKS=level2 cmake -DCMAKE_CXX_COMPILER=clazy ..
CLANGXX=clang++-6.0 make CLANGXX=clang++-9 make
---- ----
=== PVS-Studio