Compare commits
18 Commits
adoc
...
218f22c8d2
Author | SHA1 | Date | |
---|---|---|---|
218f22c8d2 | |||
d931b5aaea | |||
ec16a3a380 | |||
c41683d9e2 | |||
2abd41f429 | |||
f0cba8e7f6 | |||
8e1b48e868 | |||
d3fe32a96b | |||
62ab8db450 | |||
2af67616c8 | |||
d07e6a66f8 | |||
51adf6eb5a | |||
007afda3d1 | |||
3355f9185e | |||
1e5b6aa485 | |||
679bf869e8 | |||
1aaacb1df7 | |||
1068f502bb |
4
Makefile
4
Makefile
@@ -1,8 +1,8 @@
|
||||
build:
|
||||
pelican -s pelicanconf.py
|
||||
pelican --ignore-cache -s pelicanconf.py
|
||||
|
||||
web:
|
||||
pelican -s pelicanconf-web.py
|
||||
pelican --ignore-cache -s pelicanconf-web.py
|
||||
|
||||
clean:
|
||||
rm -rf cache __pycache__
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*- #
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
|
||||
class i18n(object):
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*- #
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
|
||||
class i18n(object):
|
||||
@@ -13,7 +12,7 @@ class i18n(object):
|
||||
LANGUAGES = ['ru']
|
||||
NEWSTYLE = True
|
||||
|
||||
__name__ = 'i18n'
|
||||
__name__ = 'pelicanconf.i18n'
|
||||
|
||||
def register(self):
|
||||
from pelican.signals import generator_init
|
||||
|
2
plugins/thirdparty/asciidoctor
vendored
2
plugins/thirdparty/asciidoctor
vendored
Submodule plugins/thirdparty/asciidoctor updated: 288c5aeba0...b271b3ed55
Submodule themes/bootstrap4 updated: ce6b18660a...c651ba0ef0
@@ -1,737 +0,0 @@
|
||||
= CMake: управление проектом
|
||||
:title-separator: {sp}|
|
||||
:category: Программирование
|
||||
:tags: программирование, cmake,
|
||||
:toc:
|
||||
|
||||
== Полезные ссылки
|
||||
|
||||
* https://github.com/onqtam/awesome-cmake[Каталог ссылок]
|
||||
* https://cgold.readthedocs.io/en/latest/index.html[CGold: The
|
||||
Hitchhiker’s Guide to the CMake]
|
||||
|
||||
== Структура каталогов проекта
|
||||
|
||||
Файлы проекта и результаты компиляции размещаются в каталогах:
|
||||
|
||||
....
|
||||
└── cmex
|
||||
├── _build
|
||||
│ ├── Debug
|
||||
│ └── Release
|
||||
├── .git
|
||||
├── cmake
|
||||
│ ├── cmlib
|
||||
│ ├── etc
|
||||
│ ├── find
|
||||
│ └── generators
|
||||
├── doc
|
||||
├── files
|
||||
│ ├── etc
|
||||
│ ├── share
|
||||
│ └── var
|
||||
├── l10n
|
||||
├── src
|
||||
│ ├── app
|
||||
│ └── lib
|
||||
├── thirdparty
|
||||
└── tools
|
||||
....
|
||||
|
||||
Назначение каталогов приведено в таблице.
|
||||
|
||||
[cols="1,3",options="header",]
|
||||
|===
|
||||
|Каталог |Назначение
|
||||
|`cmex/_build` |Результаты компиляции
|
||||
|`cmex/_build/Debug` |Результаты компиляции в режиме отладки
|
||||
|`cmex/_build/Release` |Результаты компиляции в режиме выпуска
|
||||
|`cmex/.git` |Репозиторий git
|
||||
|`cmex/cmake` |Файлы с дополнительными функциями для CMake
|
||||
|`cmex/cmake/cmlib` |Библиотека функций для CMake
|
||||
|`cmex/cmake/find` |Модули CMake для поиска внешних программ и библиотек
|
||||
|`cmex/cmake/etc` |Файлы настроек, используемые в CMake
|
||||
|`cmex/cmake/generators` |Генераторы проектов
|
||||
|`cmex/doc` |Документация для проекта
|
||||
|`cmake/files` |Каталог для дополнительных файлов
|
||||
|`cmake/files/etc` |Каталог для файлов настроек проекта
|
||||
|`cmake/files/share` |Каталог для неизменяемых файлов
|
||||
|`cmake/files/var` |Каталог для изменяемых файлов
|
||||
|`cmex/l10n` |Файлы переводов
|
||||
|`cmex/src` |Исходные тексты
|
||||
|`cmex/src/app` |Исходные тексты программ
|
||||
|`cmex/src/lib` |Исходные тексты библиотек
|
||||
|`cmex/thirdparty` |Исходные тексты сторонних проектов
|
||||
|`cmex/tools` |Дополнительные утилиты
|
||||
|===
|
||||
|
||||
Каталог `_build` создаётся, чтобы избежать попадания получаемых во время
|
||||
сборки файлов в иерархию основного проекта. Запись результатов сборки
|
||||
проекта внутрь иерархии каталогов с исходными текстами приводит к
|
||||
засорению формируемыми на этапе сборки файлами, которые затрудняют
|
||||
разработку, поиск в оригинальных файлах и мешают ориентироваться в
|
||||
проекте. При работе с несколькими типами сборки, например, отладка и
|
||||
выпуск, появляется необходимость корректного полного удаления
|
||||
результатов предыдущего тип сборки.
|
||||
|
||||
== Начало проекта
|
||||
|
||||
Проект, в котором выполнены приведённые ниже действия, можно посмотреть
|
||||
https://git.246060.ru/f1x1t/cmex[здесь] или сделать его копию командой:
|
||||
|
||||
[source,sh]
|
||||
----
|
||||
git clone --recursive https://git.246060.ru/f1x1t/cmex
|
||||
----
|
||||
|
||||
В каталоге `cmex` нужно создать файл `CMakeLists.txt`:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Минимальная версия Cmake
|
||||
cmake_minimum_required(VERSION 3.3)
|
||||
cmake_policy(VERSION 3.0.2..3.7)
|
||||
|
||||
# Название и версия проекта и используемые языки программирования
|
||||
project(cmex VERSION 0.2.0 LANGUAGES C CXX)
|
||||
----
|
||||
|
||||
Значение версии следует формировать согласно правилам
|
||||
https://semver.org/lang/ru/[семантического версионирования].
|
||||
|
||||
В каталоге `cmex` нужно инициализировать репозиторий и установить
|
||||
подмодули, содержащие функции для CMake:
|
||||
|
||||
[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]
|
||||
----
|
||||
# В каталоге 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)
|
||||
----
|
||||
|
||||
В файле `cmake/etc/organization.txt` записать название организации,
|
||||
которой принадлежит проект:
|
||||
|
||||
....
|
||||
ORG, Inc.
|
||||
....
|
||||
|
||||
В файле `cmake/etc/cpack_ignore.txt` перечислить шаблоны для исключения
|
||||
из архива, создаваемого целью `dist`. Например:
|
||||
|
||||
....
|
||||
cmake/lib/.git$
|
||||
.git$
|
||||
files/var
|
||||
CMakeLists.txt.user
|
||||
~$
|
||||
\\\\..*\\\\.bak$
|
||||
\\\\..*\\\\.tmp$
|
||||
\\\\..*\\\\.swp$
|
||||
....
|
||||
|
||||
Чтобы проверить корректность файла `CMakeLists.txt`, нужно создать
|
||||
каталог `_build` в каталоге `cmex`, перейти в него и выполнить команды:
|
||||
|
||||
[source,sh]
|
||||
----
|
||||
cmake ..
|
||||
make
|
||||
----
|
||||
|
||||
== Поиск системных библиотек
|
||||
|
||||
Системные библиотеки можно искать с помощью программы `pkgconfig`,
|
||||
которая хранит базу данных параметров, включающую пути к заголовочным
|
||||
файлами и перечни библиотек, необходимых для компоновки. Сначала
|
||||
производится наличие модуля `PkgConfig`, в котором определена функция
|
||||
`pkg_check_modules`, которая и осуществляет поиск. Например, для поиска
|
||||
библиотек `gsl`, `fftw3` и `udev` можно написать:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Поиск библиотек с помощью pkgconfig
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(GSL REQUIRED gsl)
|
||||
pkg_check_modules(FFTW3 REQUIRED fftw3)
|
||||
pkg_check_modules(UDEV udev)
|
||||
----
|
||||
|
||||
Если системная библиотека поставляется без файла описания для
|
||||
`pkgconfig`, то для её поиска может быть написан специальный модуль для
|
||||
`CMake`, который вызывается функцией `find_package`. Кроме того функция
|
||||
`find_package` может возвращать дополнительные значения, например, пути
|
||||
к исполняемым файлам.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Поиск с помощью функции find_package
|
||||
find_package(LibXml2)
|
||||
find_package(CURL)
|
||||
----
|
||||
|
||||
Если для библиотеки нет модуля, выполняющего её поиск, то можно
|
||||
произвести поиск с помощью функции `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_config_hpp_generate()`, создающая файл
|
||||
`${CMAKE_BUILD_DIR}/include/config.hpp`, в который записывается
|
||||
информация о имени и версии проекта, дате и типе сборки.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Автоматически генерируемый заголовочный файл
|
||||
cmlib_config_hpp_generate()
|
||||
----
|
||||
|
||||
== Базовая библиотека
|
||||
|
||||
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла
|
||||
`CMakeLists.txt` в подкаталоге `src/lib`:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
add_subdirectory(src/libcmex)
|
||||
----
|
||||
|
||||
В каталоге `cmex/src/libcmex` нужно создать файл `cmex.hpp`:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
#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]
|
||||
----
|
||||
# Название основной цели и имя библиотеки в текущем каталоге
|
||||
set(current_target cmex)
|
||||
|
||||
# Список файлов исходных текстов
|
||||
set(current_target_sources
|
||||
cmex.cpp
|
||||
)
|
||||
|
||||
# Список заголовочных файлов (используется для установки)
|
||||
set(current_target_headers
|
||||
cmex.hpp
|
||||
)
|
||||
|
||||
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()
|
||||
install(FILES ${CMAKE_BINARY_DIR}/include/config.hpp ${current_target_headers}
|
||||
COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${current_target})
|
||||
----
|
||||
|
||||
== Базовое приложение
|
||||
|
||||
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла
|
||||
`CMakeLists.txt` в подкаталоге `src/cmex`:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
add_subdirectory(src/cmex)
|
||||
----
|
||||
|
||||
В каталоге `cmex/src/cmex` нужно создать файл `main.cpp`:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
#include "compiler_features.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "cmex.hpp"
|
||||
|
||||
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
|
||||
std::cout << CMEX_VERSION_STR << std::endl; // Значение из config.hpp
|
||||
std::cout << cmex_init(4) << std::endl; // Функция из внутренней библиотеки
|
||||
return 0;
|
||||
}
|
||||
----
|
||||
|
||||
и файл `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` с проектом,
|
||||
состоящим из файлов `cmext.hpp`:
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#ifndef CMEXT_CMEXT_HPP_
|
||||
#define CMEXT_CMEXT_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int32_t cmext_init(int32_t i);
|
||||
|
||||
#endif
|
||||
----
|
||||
|
||||
`cmext.cpp`:
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include "cmext.hpp"
|
||||
|
||||
int32_t cmext_init(int32_t i = 0) {
|
||||
return i;
|
||||
}
|
||||
----
|
||||
|
||||
и `CMakeLists.txt`:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
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})
|
||||
----
|
||||
|
||||
В файле `cmex/CMakeLists.txt` нужно подключить стандартный модуль
|
||||
`ExternalProject` и описать правила для его загрузки, настройки,
|
||||
компиляции и установки для сопряжения с текущим проектом:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Подключение внешних проектов
|
||||
include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(cmext
|
||||
EXCLUDE_FROM_ALL TRUE
|
||||
SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/cmext
|
||||
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
|
||||
)
|
||||
----
|
||||
|
||||
Вызовы этих функций нужно сделать до функций `add_subdirectories`, чтобы
|
||||
в подключенных подкаталогах можно было использовать цель `cmext` для
|
||||
определения зависимостей.
|
||||
|
||||
В файле `cmex/src/cmex/CMakeLists.txt` нужно подключить внешний проект
|
||||
`cmext`:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Зависимость от библиотеки из внешнего проекта проекта
|
||||
add_dependencies(${current_target} cmext)
|
||||
----
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Добавление каталога, в который устанавливаются заголовочные файлы от внешнего
|
||||
# проекта cmext, к списку путей для поиска заголовочных файлов
|
||||
target_include_directories(${current_target} PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include/cmext>)
|
||||
----
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Библиотека из внешнего проекта cmext
|
||||
target_link_libraries(${current_target} ${CMAKE_BINARY_DIR}/lib/libcmext.a)
|
||||
----
|
||||
|
||||
Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно
|
||||
вызвать функцию `cmext_init` из библиотеки, предоставляемой внешним
|
||||
проектом. Например:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
#include "compiler_features.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cmext/cmext.hpp>
|
||||
|
||||
#include "cmex.hpp"
|
||||
|
||||
QTextStream& qStdOut()
|
||||
{
|
||||
static QTextStream ts(stdout);
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Значение из compiler_features.hpp
|
||||
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
|
||||
// Значение из config.hpp
|
||||
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
|
||||
// Значение из config.hpp
|
||||
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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
----
|
||||
|
||||
== Qt5
|
||||
|
||||
Для поиска необходимых компонентов Qt5 нужно в файл
|
||||
`cmex/CMakeLists.txt` добавить строки:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
find_package(Qt5 COMPONENTS Core Network Gui Widgets DBus Concurrent Sql REQUIRED)
|
||||
----
|
||||
|
||||
Библиотека CMLib автоматически подключает вызов препроцессора `moc` и
|
||||
компилятора ресурсов `rcc`, если цель использует модуль `Core`, и
|
||||
вызывает компилятор файлов описания интерфейса, если цель использует
|
||||
модуль `Widgets`.
|
||||
|
||||
== Консольное приложение
|
||||
|
||||
В файл `cmex/src/cmex/CMakeLists.txt` добавить строки:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# 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)
|
||||
----
|
||||
|
||||
Для проверки работоспособности подключения Qt5 файл
|
||||
`cmex/src/cmex/main.cpp` нужно заменить на:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
#include "compiler_features.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
#include <QtCore>
|
||||
#include <iostream>
|
||||
#include <cmext/cmext.hpp>
|
||||
|
||||
#include "cmex.hpp"
|
||||
|
||||
QTextStream& qStdOut()
|
||||
{
|
||||
static QTextStream ts(stdout);
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
QCoreApplication app(argc, argv);
|
||||
QTranslator translator;
|
||||
|
||||
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
|
||||
{
|
||||
app.installTranslator(&translator);
|
||||
}
|
||||
// Значение из compiler_features.hpp
|
||||
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
|
||||
// Значение из config.hpp
|
||||
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
|
||||
// Значение из config.hpp
|
||||
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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
----
|
||||
|
||||
После сборки проекта в каталоге `cmex/l10n` появится файл
|
||||
`cmex_app_ru_RU.ts`, в котором нужно отредактировать переводы с помощью
|
||||
программы `linguist`. После сохранения переводов проект нужно
|
||||
пересобрать, файл переводов в скомпилированном виде будет встроен в
|
||||
исполняемый файл `cmex`, а доступ к нему будет осуществляться с помощью
|
||||
кода:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
|
||||
{
|
||||
app.installTranslator(&translator);
|
||||
}
|
||||
----
|
||||
|
||||
== Графическое приложение
|
||||
|
||||
Для создания минимального графического приложения нужно создать файл
|
||||
описания интерфейса `cmex/src/cmex/my_main_window.ui`:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<?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>
|
||||
----
|
||||
|
||||
заголовочный файл `cmex/src/cmex/my_main_window.hpp`:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
#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 {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyMainWindow(QWidget* parent = 0);
|
||||
virtual ~MyMainWindow();
|
||||
};
|
||||
|
||||
#endif /* CMEX_MY_MAIN_WINDOW_HPP_ */
|
||||
----
|
||||
|
||||
и файл с реализацией конструктора и деструктора
|
||||
`cmex/src/cmex/my_main_window.cpp`:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
#include "my_main_window.hpp"
|
||||
|
||||
MyMainWindow::MyMainWindow(QWidget* parent) {
|
||||
|
||||
}
|
||||
|
||||
MyMainWindow::~MyMainWindow() {
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Для отображения графического окна нужно заменить файл
|
||||
`cmex/src/cmex/main.cpp` на:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
#include "compiler_features.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtWidgets>
|
||||
#include <iostream>
|
||||
#include <cmext/cmext.hpp>
|
||||
|
||||
#include "cmex.hpp"
|
||||
#include "my_main_window.hpp"
|
||||
|
||||
QTextStream& qStdOut()
|
||||
{
|
||||
static QTextStream ts(stdout);
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
QApplication app(argc, argv);
|
||||
QTranslator translator;
|
||||
|
||||
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
|
||||
{
|
||||
app.installTranslator(&translator);
|
||||
}
|
||||
|
||||
// Значение из compiler_features.hpp
|
||||
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
|
||||
// Значение из config.hpp
|
||||
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
|
||||
// Значение из config.hpp
|
||||
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;
|
||||
|
||||
MyMainWindow* mmw = new MyMainWindow();
|
||||
mmw->show();
|
||||
return app.exec();
|
||||
}
|
||||
----
|
||||
|
||||
В файле `cmex/src/cmex/CMakeLists.txt` добавить новые файлы к списку
|
||||
файлов, используемых для компиляции:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
set(current_target_sources
|
||||
main.cpp
|
||||
my_main_window.cpp
|
||||
)
|
||||
|
||||
set(current_target_uis
|
||||
my_main_window.ui
|
||||
)
|
||||
----
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
# Цель для создания исполняемого файла
|
||||
add_executable(${current_target} ${current_target_sources} ${current_target_uis})
|
||||
----
|
||||
|
||||
и добавить строки для подключения графических библиотек Qt5 и
|
||||
соответствующих им заголовочных файлов:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
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)
|
||||
----
|
||||
|
||||
Во время сборки проекта в файл переводов `cmex/l10n/cmex_app_ru_RU.ts`
|
||||
будут добавлены новые строки, их нужно перевести с помощью `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`.
|
@@ -13,14 +13,14 @@
|
||||
|
||||
[source,sh]
|
||||
----
|
||||
sudo apt-get install clang-tidy-6.0
|
||||
sudo apt-get install clang-tidy-10
|
||||
----
|
||||
|
||||
Использование:
|
||||
|
||||
[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 со
|
||||
@@ -30,12 +30,25 @@ cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-6.0" path/to/source
|
||||
----
|
||||
---
|
||||
Checks: '-*,
|
||||
clang-diagnostic-*,
|
||||
readability-*,
|
||||
modernize-*,
|
||||
bugprone-*,
|
||||
clang-analyzer-*,
|
||||
cppcoreguidelines-*,
|
||||
google-*,
|
||||
bugprone-*'
|
||||
llvm-*,
|
||||
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:
|
||||
- key: readability-identifier-naming.ClassCase
|
||||
value: CamelCase
|
||||
@@ -124,7 +137,7 @@ cmake -DCMAKE_LINK_WHAT_YOU_USE=TRUE ..
|
||||
|
||||
[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]
|
||||
----
|
||||
CLAZY_CHECKS=level2 cmake -DCMAKE_CXX_COMPILER=clazy ..
|
||||
CLANGXX=clang++-6.0 make
|
||||
CLANGXX=clang++-9 make
|
||||
----
|
||||
|
||||
=== PVS-Studio
|
||||
|
Reference in New Issue
Block a user