Начало проекта

This commit is contained in:
2021-12-08 14:32:04 +03:00
commit 17daab8623
105 changed files with 9814 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
# Создание динамической библиотеки из объектной библиотеки
function(myx_cmake_add_shared_library target)
get_target_property(_target_type ${target} TYPE)
if(NOT _target_type STREQUAL OBJECT_LIBRARY)
message(
FATAL_ERROR
"MyxCMake: add_shared_library needs target of type OBJECT_LIBRARY")
return()
endif()
add_library(${target}-shared SHARED $<TARGET_OBJECTS:${target}>)
set_target_properties(
${target}-shared
PROPERTIES OUTPUT_NAME ${target}
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
LIBRARY_OUTPUT_DIRECTORY
${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
install(TARGETS ${target}-static LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endfunction()

View File

@@ -0,0 +1,19 @@
# Создание статической библиотеки из объектной библиотеки
function(myx_cmake_add_static_library target)
get_target_property(_target_type ${target} TYPE)
if(NOT _target_type STREQUAL OBJECT_LIBRARY)
message(
FATAL_ERROR
"MyxCMake: add_static_library needs target of type OBJECT_LIBRARY")
return()
endif()
add_library(${target}-static STATIC $<TARGET_OBJECTS:${target}>)
set_target_properties(
${target}-static
PROPERTIES OUTPUT_NAME ${target}
ARCHIVE_OUTPUT_DIRECTORY
${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
install(TARGETS ${target}-static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endfunction()

View File

@@ -0,0 +1,96 @@
cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW) # IN_LIST operator
option(MYX_CMAKE_ENABLE_WARNING_FLAGS "Enable autodetected warning flags" ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS
ON
CACHE BOOL "Enable generation of compile_commands.json." FORCE)
# Добавление конфигурации для профилирования
if(CMAKE_CONFIGURATION_TYPES)
if(NOT "Profile" IN_LIST CMAKE_CONFIGURATION_TYPES)
list(APPEND CMAKE_CONFIGURATION_TYPES Profile)
endif()
else()
set(_allowed_build_types None Debug Release Profile RelWithDebInfo MinSizeRel)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${_allowed_build_types})
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE
Debug
CACHE STRING "" FORCE)
elseif(NOT "${CMAKE_BUILD_TYPE}" IN_LIST _allowed_build_types)
message(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}")
endif()
endif()
set(_gcc_debug_flags "-ggdb -fno-omit-frame-pointer")
set(_gcc_profile_flags "-pg")
if(CMAKE_BUILD_TYPE STREQUAL Profile)
# Ключи компиляции для режима профилирования в зависимости от типа компилятора
if(CMAKE_CXX_COMPILER_IS_CLANG OR CMAKE_CXX_COMPILER_IS_GCC)
set(CMAKE_C_FLAGS_PROFILE
"${CMAKE_C_FLAGS_RELEASE} ${_gcc_debug_flags} ${_gcc_profile_flags}"
CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_PROFILE
"${CMAKE_CXX_FLAGS_RELEASE} ${MYX_CMAKE_DETECTED_CXX_FLAGS} ${_gcc_debug_flags} ${_gcc_profile_flags}"
CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_PROFILE
"${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${_gcc_profile_flags}"
CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE
"${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${_gcc_profile_flags}"
CACHE STRING "" FORCE)
set(CMAKE_STATIC_LINKER_FLAGS_PROFILE
"${CMAKE_STATIC_LINKER_FLAGS_RELEASE} ${_gcc_profile_flags}"
CACHE STRING "" FORCE)
set(CMAKE_MODULE_LINKER_FLAGS_PROFILE
"${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${_gcc_profile_flags}"
CACHE STRING "" FORCE)
elseif(CMAKE_CXX_COMPILER_IS_Intel)
message("Set options for profiling with Intel C++")
elseif(CMAKE_CXX_COMPILER_IS_MSVC)
message("Set options for profiling with Visual Studio C++")
endif()
set(CMAKE_VERBOSE_MAKEFILE
ON
CACHE BOOL "Enable generation of verbose build scripts." FORCE)
elseif(CMAKE_BUILD_TYPE STREQUAL Debug)
# В режиме отладки подробный вывод сообщений компилятора
if(CMAKE_CXX_COMPILER_IS_CLANG OR CMAKE_CXX_COMPILER_IS_GCC)
string(REPLACE " ${_gcc_debug_flags}" "" CMAKE_C_FLAGS_DEBUG
"${CMAKE_C_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_DEBUG
"${CMAKE_C_FLAGS_DEBUG} ${_gcc_debug_flags}"
CACHE STRING "" FORCE)
string(REPLACE " ${_gcc_debug_flags}" "" CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG}")
if(MYX_CMAKE_ENABLE_WARNING_FLAGS)
set(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} ${MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG} ${_gcc_debug_flags}"
CACHE STRING "" FORCE)
else()
set(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} ${_gcc_debug_flags}"
CACHE STRING "" FORCE)
endif()
endif()
set(CMAKE_VERBOSE_MAKEFILE
ON
CACHE BOOL "Enable generation of verbose build scripts." FORCE)
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} ${MYX_CMAKE_DETECTED_CXX_FLAGS}"
CACHE STRING "" FORCE)
elseif(CMAKE_BUILD_TYPE STREQUAL None)
# Режим None используется для статического анализа кода
set(CMAKE_VERBOSE_MAKEFILE
ON
CACHE BOOL "Enable generation of verbose build scripts." FORCE)
endif()
unset(_gcc_debug_flags)
unset(_gcc_profile_flags)
cmake_policy(POP)

View File

@@ -0,0 +1,69 @@
# Общие настройки для пакета: организация, автор, версия
set(CPACK_PACKAGE_VENDOR ${MYX_CMAKE_ORGANIZATION_NAME_LOWER} CACHE STRING "")
set(CPACK_PACKAGE_NAME ${MYX_CMAKE_PROJECT_NAME_LOWER} CACHE STRING "")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION} CACHE STRING "")
# Параметры для архива исходных текстов
if(NOT CPACK_SOURCE_GENERATOR)
set(CPACK_SOURCE_GENERATOR "TGZ")
endif()
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${MYX_CMAKE_PROJECT_NAME_LOWER}-${CPACK_PACKAGE_VERSION}")
# Типы генераторов для бинарных архивов
if(NOT CPACK_GENERATOR)
set(CPACK_GENERATOR "TGZ" "DEB")
endif()
# Параметры для архива собранного проекта
set(CPACK_TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(CPACK_TARGET_ARCH "amd64")
endif()
set(CPACK_PACKAGE_FILE_NAME "${MYX_CMAKE_PROJECT_NAME_LOWER}_${CPACK_TARGET_ARCH}_${CPACK_PACKAGE_VERSION}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${MYX_CMAKE_PROJECT_NAME_LOWER}-${CPACK_PACKAGE_VERSION}")
# Список масок для исключения из архива исходных текстов
set(CPACK_SOURCE_IGNORE_FILES
"${CPACK_SOURCE_IGNORE_FILES}"
"${CMAKE_BINARY_DIR}"
"^${CMAKE_SOURCE_DIR}/.?build.?/"
"^${CMAKE_SOURCE_DIR}/.?output.?/"
"^${CMAKE_SOURCE_DIR}/files/var"
"^${CMAKE_SOURCE_DIR}/files/log"
"CMakeLists.txt.user.*"
".*.autosave"
".*.status"
"~$"
"\\\\.swp$")
option(MYX_CMAKE_COMPACT_SOURCE_PACKAGE "Make compact source package" ON)
if(MYX_CMAKE_COMPACT_SOURCE_PACKAGE)
# Список масок для исключения из архива исходных текстов для более компактного архива
set(CPACK_SOURCE_IGNORE_FILES
"${CPACK_SOURCE_IGNORE_FILES}"
"\\\\.git"
"/\\\\.git/"
"/\\\\.gitlab-ci/"
"\\\\.clang-tidy$"
"\\\\.cmake-format$"
"\\\\.gitignore$"
"\\\\.gitattributes$"
"\\\\.gitmodules$"
"\\\\.gitlab-ci.yml$")
endif()
set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_CURRENT_LIST_DIR}/MyxCMakeCPackProject.cmake)
option(MYX_CMAKE_CPACK_DEFAULT_SCHEME "Use packaging default scheme" ON)
# Правила для сборки обычных архивов
if(MYX_CMAKE_CPACK_DEFAULT_SCHEME)
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_COMPONENTS_GROUPING IGNORE)
endif()
# Правила для сборки пакетов для Debian
include(CMLibCPackDeb)
# Подключение модуля, выполняющего сборку архивов и пакетов
include(CPack)

View File

@@ -0,0 +1,81 @@
# По умолчанию пакет собирается для дистрибутива unstable
if(NOT DEBIAN_PACKAGE_TYPE)
set(DEBIAN_PACKAGE_TYPE "unstable")
endif()
if(NOT CPACK_DEBIAN_PACKAGE_SECTION)
set(CPACK_DEBIAN_PACKAGE_SECTION "misc")
endif()
if(NOT CPACK_DEBIAN_PACKAGE_PRIORITY)
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
endif()
# По умолчанию пакет для Debian делится на компоненты
if(NOT CPACK_DEB_COMPONENT_INSTALL)
set(CPACK_DEB_COMPONENT_INSTALL ON)
endif()
if(MYX_CMAKE_CPACK_DEFAULT_SCHEME)
# Если имя компонента по умолчанию не определено, то устанавливается MAIN
if(NOT CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME main)
endif()
# В списке компонентов обязательно должны быть main, base-dev, libs-dev и doc
list(
APPEND
CPACK_COMPONENTS_ALL
main
base-dev
libs-dev
doc)
list(REMOVE_DUPLICATES CPACK_COMPONENTS_ALL)
# Правило формирования имени пакета и файла для компонента main
set(CPACK_DEBIAN_MAIN_PACKAGE_NAME "${MYX_CMAKE_PROJECT_NAME_LOWER}")
set(CPACK_DEBIAN_MAIN_FILE_NAME
${MYX_CMAKE_PROJECT_NAME_LOWER}_${CPACK_PACKAGE_VERSION}_${CPACK_TARGET_ARCH}.deb)
# Правило формирования имени пакета и файла для компонента base-dev
set(CPACK_DEBIAN_BASE-DEV_PACKAGE_NAME "lib${MYX_CMAKE_PROJECT_NAME_LOWER}-base-dev")
set(CPACK_DEBIAN_BASE-DEV_FILE_NAME
lib${MYX_CMAKE_PROJECT_NAME_LOWER}-base-dev_${CPACK_PACKAGE_VERSION}_${CPACK_TARGET_ARCH}.deb)
# Правило формирования имени пакета и файла для компонента libs-dev
set(CPACK_DEBIAN_LIBS-DEV_PACKAGE_NAME lib${MYX_CMAKE_PROJECT_NAME_LOWER}-dev)
set(CPACK_DEBIAN_LIBS-DEV_FILE_NAME
lib${MYX_CMAKE_PROJECT_NAME_LOWER}-dev_${CPACK_PACKAGE_VERSION}_${CPACK_TARGET_ARCH}.deb)
set(CPACK_DEBIAN_LIBS-DEV_PACKAGE_DEPENDS "lib${MYX_CMAKE_PROJECT_NAME_LOWER}-base-dev")
foreach(component ${CPACK_COMPONENTS_ALL})
string(TOLOWER ${component} _cl)
string(TOUPPER ${component} _cu)
# Правила формирования имени пакета и файла для остальных компонентов
if(NOT ${_cl} STREQUAL main AND NOT ${_cl} STREQUAL base-dev AND NOT ${_cl} STREQUAL libs-dev)
set(CPACK_DEBIAN_${_cu}_PACKAGE_NAME "${MYX_CMAKE_PROJECT_NAME_LOWER}-${_cl}")
set(CPACK_DEBIAN_${_cu}_FILE_NAME
"${MYX_CMAKE_PROJECT_NAME_LOWER}-${_cl}_${CPACK_PACKAGE_VERSION}_${CPACK_TARGET_ARCH}.deb")
endif()
# Если в каталоге ${CMAKE_SOURCE_DIR}/cmake/deb/${_cl} находятся сценарии сопровождающего
# postinst, preinst, postrm и prerm, то они будут добавлены к пакету.
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/preinst")
list(APPEND CPACK_DEBIAN_${_cu}_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/preinst")
endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/postinst")
list(APPEND CPACK_DEBIAN_${_cu}_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/postinst")
endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/prerm")
list(APPEND CPACK_DEBIAN_${_cu}_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/prerm")
endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/postrm")
list(APPEND CPACK_DEBIAN_${_cu}_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/deb/${_cl}/postrm")
endif()
endforeach()
endif()
if(UNIX AND NOT TARGET deb)
add_custom_target(deb WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND cpack -G DEB)
endif()

View File

@@ -0,0 +1,5 @@
if(CPACK_GENERATOR MATCHES "DEB")
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/${CPACK_PACKAGE_VENDOR}/${CPACK_PACKAGE_NAME}")
else()
set(CPACK_PACKAGING_INSTALL_PREFIX "${PROJECT_NAME}")
endif()

View File

@@ -0,0 +1,22 @@
# Запись результатов сборки проекта внутрь иерархии каталогов с исходными
# текстами приводит к засорению файлами формируемыми на этапе сборки, которые
# затрудняют разработку, поиск в оригинальных файлах и мешают ориентироваться в
# проекте. При работе с несколькими типами сборки, например, отладка и выпуск,
# появляется необходимость корректного полного удаления результатов предыдущего
# варианта.
get_filename_component(_source_realpath "${CMAKE_SOURCE_DIR}" REALPATH)
get_filename_component(_binary_realpath "${CMAKE_BINARY_DIR}" REALPATH)
get_filename_component(_install_realpath "${CMAKE_INSTALL_PREFIX}" REALPATH)
if(_install_realpath STREQUAL _binary_realpath)
message(FATAL_ERROR "MyxCMake: Cannot install into build directory.")
endif()
if(_install_realpath STREQUAL _source_realpath)
message(FATAL_ERROR "MyxCMake: Cannot install into source directory.")
endif()
if(_source_realpath STREQUAL _binary_realpath)
message(FATAL_ERROR "MyxCMake: In-source builds are not allowed.")
endif()

View File

@@ -0,0 +1,34 @@
set(CLANG_CHECK_NAMES clang-check)
foreach(V RANGE 9 15)
list(INSERT CLANG_CHECK_NAMES 0 "clang-check-${V}")
endforeach()
find_program(CLANG_CHECK_EXE NAMES ${CLANG_CHECK_NAMES})
if(CLANG_CHECK_EXE)
option(MYX_CMAKE_CLANG_CHECK_FIX "MyxCMake: perform fixes for Clang Check" OFF)
endif()
unset(V)
unset(CLANG_CHECK_NAMES)
function(myx_cmake_clang_check_analyze target)
set(_args --analyze --extra-arg="-Wno-unknown-warning-option")
get_target_property(__sources ${target} SOURCES)
list(FILTER __sources EXCLUDE REGEX "qrc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "moc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "ui_.*\\.h$")
if(CLANG_CHECK_EXE)
if(MYX_CMAKE_CLANG_ANALYZE_FIX)
list(APPEND _args "--fixit")
endif()
if(NOT TARGET myx-cmake-clang-check-analyze)
add_custom_target(myx-cmake-clang-check-analyze)
endif()
add_custom_target(${target}-clang-check-analyze WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CLANG_CHECK_EXE} ${_args} -p ${CMAKE_BINARY_DIR} ${__sources})
add_dependencies(${target}-clang-check-analyze ${target})
add_dependencies(myx-cmake-clang-check-analyze ${target}-clang-check-analyze)
else()
message(STATUS "MyxCMake: Clang Check analyzer is not found")
endif()
endfunction()

View File

@@ -0,0 +1,34 @@
set(CLANG_TIDY_NAMES clang-tidy)
foreach(V RANGE 9 15)
list(INSERT CLANG_TIDY_NAMES 0 "clang-tidy-${V}")
endforeach()
find_program(CLANG_TIDY_EXE NAMES ${CLANG_TIDY_NAMES})
if(CLANG_TIDY_EXE)
option(MYX_CMAKE_CLANG_TIDY_FIX "MyxCMake: perform fixes for Clang Tidy" OFF)
endif()
unset(V)
unset(CLANG_TIDY_NAMES)
function(myx_cmake_clang_tidy_analyze target)
set(_args -extra-arg="-Wno-unknown-warning-option")
get_target_property(__sources ${target} SOURCES)
list(FILTER __sources EXCLUDE REGEX "qrc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "moc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "ui_.*\\.h$")
if(CLANG_TIDY_EXE)
if(MYX_CMAKE_CLANG_TIDY_FIX)
list(APPEND _args "--fix")
endif()
if(NOT TARGET myx-cmake-clang-tidy-analyze)
add_custom_target(myx-cmake-clang-tidy-analyze)
endif()
add_custom_target(${target}-clang-tidy-analyze WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CLANG_TIDY_EXE} ${_args} -p ${CMAKE_BINARY_DIR} ${__sources})
add_dependencies(${target}-clang-tidy-analyze ${target})
add_dependencies(myx-cmake-clang-tidy-analyze ${target}-clang-tidy-analyze)
else()
message(STATUS "MyxCMake: Clang Tidy analyzer is not found")
endif()
endfunction()

View File

@@ -0,0 +1,57 @@
find_program(CLAZY_EXE NAMES clazy-standalone)
set(CLANG_APPLY_REPLACEMENTS_NAMES clang-apply-replacements)
foreach(V RANGE 9 15)
list(INSERT CLANG_APPLY_REPLACEMENTS 0 "clang-apply-replacements-${V}")
endforeach()
find_program(CLANG_APPLY_REPLACEMENTS_EXE NAMES ${CLANG_APPLY_REPLACEMENTS_NAMES})
if(CLANG_TIDY_EXE)
option(MYX_CMAKE_CLANG_TIDY_FIX "MyxCMake: perform fixes for Clang Tidy" OFF)
endif()
unset(V)
unset(CLANG_TIDY_NAMES)
if(CLAZY_EXE AND CLANG_APPLY_REPLACEMENTS_EXE)
option(MYX_CMAKE_CLAZY_FIX "MyxCMake: perform fixes for Clazy" OFF)
endif()
function(myx_cmake_clazy_analyze target)
set(options)
set(oneValueArgs CHECKS)
set(multiValueArgs)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT ARG_CHECKS)
set(ARG_CHECKS "level2,container-inside-loop,heap-allocated-small-trivial-type,inefficient-qlist,isempty-vs-count,qt-keywords,unneeded-cast"
)
endif()
get_target_property(__sources ${target} SOURCES)
list(FILTER __sources EXCLUDE REGEX "qrc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "moc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "ui_.*\\.h$")
set(_args -checks=${ARG_CHECKS} -extra-arg="-Wno-unknown-warning-option"
-export-fixes=clazy-fixes-file.yaml)
if(CLAZY_EXE)
if(NOT TARGET myx-cmake-clazy-analyze)
add_custom_target(myx-cmake-clazy-analyze)
endif()
if(MYX_CMAKE_CLAZY_FIX)
add_custom_target(
${target}-clazy-analyze
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CLAZY_EXE} ${_args} -p ${CMAKE_BINARY_DIR} ${__sources}
COMMAND ${CLANG_APPLY_REPLACEMENTS_EXE} ${CMAKE_BINARY_DIR})
else()
add_custom_target(${target}-clazy-analyze WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CLAZY_EXE} ${_args} -p ${CMAKE_BINARY_DIR} ${__sources})
endif()
add_dependencies(${target}-clazy-analyze ${target})
add_dependencies(myx-cmake-clazy-analyze ${target}-clazy-analyze)
else()
message(STATUS "MyxCMake: Clazy standalone analyzer is not found")
endif()
endfunction()

View File

@@ -0,0 +1,63 @@
if(CMAKE_EXPORT_COMPILE_COMMANDS)
find_program(PVS_STUDIO_ANALYZER_EXE NAMES pvs-studio-analyzer)
include(PVS-Studio)
else()
message(STATUS "MyxCMake: CMAKE_EXPORT_COMPILE_COMMANDS is not set. PVS checks will be disabled.")
endif()
function(myx_cmake_pvs_studio_analyze target)
if(PVS_STUDIO_ANALYZER_EXE)
if(NOT TARGET myx-cmake-pvs-studio-analyze)
add_custom_target(myx-cmake-pvs-studio-analyze)
endif()
set(PVS_STUDIO_CONFIG "${CMAKE_BINARY_DIR}/PVS-Studio-${target}.cfg")
set(PVS_STUDIO_CONFIG_COMMAND "${CMAKE_COMMAND}" -E echo "sourcetree-root=${CMAKE_SOURCE_DIR}" > "${PVS_STUDIO_CONFIG}")
add_custom_command(OUTPUT "${PVS_STUDIO_CONFIG}"
COMMAND ${PVS_STUDIO_CONFIG_COMMAND}
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Generating PVS-Studio.cfg")
set(PVS_STUDIO_HEADER "${CMAKE_BINARY_DIR}/include/pvs_studio_suppression_${target}.hpp")
file(WRITE ${PVS_STUDIO_HEADER}
"#ifndef PVS_STUDIO_HPP_\n"
"#define PVS_STUDIO_HPP_\n"
"#pragma once\n"
"//-V813_MINSIZE=33\n"
"#endif // PVS_STUDIO_HPP_\n"
)
get_target_property(__sources ${target} SOURCES)
list(FILTER __sources EXCLUDE REGEX "qrc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "moc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "ui_.*\\.h$")
pvs_studio_add_target(
TARGET ${target}-pvs-studio-analyze
CONFIG ${PVS_STUDIO_CONFIG}
DEPENDS ${PVS_STUDIO_CONFIG}
LOG "${CMAKE_BINARY_DIR}/PVS-Studio-${target}.log"
SOURCES ${__sources}
COMPILE_COMMANDS HIDE_HELP
OUTPUT FORMAT errorfile
ARGS --exclude-path ${CMAKE_CURRENT_BINARY_DIR}/${target}_autogen
MODE GA:1,2,3;64:1;OP:1,2;CS:1,2)
add_dependencies(myx-cmake-pvs-studio-analyze ${target}-pvs-studio-analyze)
get_target_property(__target_type ${target} TYPE)
if(${__target_type} STREQUAL INTERFACE_LIBRARY)
set(__target_type INTERFACE)
else()
set(__target_type PRIVATE)
endif()
if(MSVC)
target_compile_options(${target} BEFORE ${__target_type} /FI ${PVS_STUDIO_HEADER})
else() # GCC/Clang
target_compile_options(${target} BEFORE ${__target_type} -include ${PVS_STUDIO_HEADER})
endif()
else()
message(STATUS "MyxCMake: PVS-Studio analyzer is not found")
endif()
endfunction()

View File

@@ -0,0 +1,34 @@
option(MYX_CMAKE_CODE_COVERAGE "MyxCMake: enable code coverage" OFF)
if(MYX_CMAKE_CODE_COVERAGE)
find_program(LCOV_EXE NAMES lcov)
find_program(GENHTML_EXE NAMES genhtml)
endif()
function(myx_cmake_code_coverage target)
if(CMAKE_CXX_COMPILER_IS_GCC AND MYX_CMAKE_CODE_COVERAGE)
target_compile_options(${target} PUBLIC "--coverage")
set_property(
TARGET ${target}
APPEND_STRING
PROPERTY LINK_FLAGS " --coverage")
if(LCOV_EXE)
add_custom_target(
${target}-coverage
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${LCOV_EXE} --test-name ${target} --output "${target}.lcov"
--capture --directory ${CMAKE_BINARY_DIR})
add_dependencies(${target}-coverage ${target})
if(GENHTML_EXE)
add_custom_target(
${target}-coverage-report
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${GENHTML_EXE} --output-directory "${target}-coverage-html"
"${target}.lcov")
add_dependencies(${target}-coverage-report ${target}-coverage)
endif()
endif()
endif()
endfunction()

View File

@@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
include(GNUInstallDirs)
include(MyxCMakeCheckPaths)
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS
${CMAKE_CXX_SOURCE_FILE_EXTENSIONS};tpp;tcc)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
include(MyxCMakeProjectVersion)
include(MyxCMakeRequiredVariables)
include(MyxCMakeGlobalFunctions)
include(MyxCMakeGlobalVariables)
include(MyxCMakeToday)
include(MyxCMakeLSBInfo)
include(MyxCMakeCompiler)
include(MyxCMakeCompilerFlags)
include(MyxCMakeDistCC)
include(MyxCMakeUnityBuild)
include(MyxCMakePrecompiledHeaders)
include(MyxCMakeBuildTypes)
include(MyxCMakeDebugOutputOptions)
include(MyxCMakeCodeAnalyzeClangCheck)
include(MyxCMakeCodeAnalyzeClangTidy)
include(MyxCMakeCodeAnalyzeClazy)
include(MyxCMakeCodeAnalyzePvsStudio)
include(MyxCMakeCodeCoverage)
include(MyxCMakeFormatSources)
include(MyxCMakeCommonTargetProperties)
include(MyxCMakeAddSharedLibrary)
include(MyxCMakeAddStaticLibrary)
include(MyxCMakePkgConfig)
include(MyxCMakeNinjaGeneratorHelper)
include(CMLibGit)
# include(CMLibDocDoxygen) include(CMLibDocBreathe)
# include(CMLibExternalProject)
include(MyxCMakeCPack)
include(MyxCMakeUninstall)

View File

@@ -0,0 +1,157 @@
function(myx_cmake_common_target_properties target)
get_target_property(_target_type ${target} TYPE)
set(__visibility PUBLIC)
if(_target_type STREQUAL INTERFACE_LIBRARY)
set(__visibility INTERFACE)
else()
#
if(TARGET Qt5::Core)
if(_target_type STREQUAL EXECUTABLE)
target_compile_options(${target}
PUBLIC ${Qt5Core_EXECUTABLE_COMPILE_FLAGS})
endif()
if(NOT MYX_CMAKE_DEBUG_OUTPUT)
target_compile_definitions(${target} PUBLIC QT_NO_DEBUG_OUTPUT)
endif()
if(NOT MYX_CMAKE_INFO_OUTPUT)
target_compile_definitions(${target} PUBLIC QT_NO_INFO_OUTPUT)
endif()
if(NOT MYX_CMAKE_WARNING_OUTPUT)
target_compile_definitions(${target} PUBLIC QT_NO_WARNING_OUTPUT)
endif()
endif()
if(CMAKE_CXX_COMPILER_IS_GCC AND NOT APPLE)
set_property(
TARGET ${target}
APPEND_STRING
PROPERTY LINK_FLAGS " -Wl,--no-as-needed")
endif()
# Исключение файлов qrc из списка объединяемых файлов
get_target_property(__sources ${target} SOURCES)
foreach(src IN LISTS __sources)
string(REGEX MATCH ".*/qrc_.*\\.cpp$" __qrc ${src})
if(__qrc)
set_property(SOURCE ${__qrc} PROPERTY COTIRE_EXCLUDED ON)
set_property(SOURCE ${__qrc} PROPERTY SKIP_UNITY_BUILD_INCLUSION ON)
endif()
endforeach()
target_include_directories(
${target}
PUBLIC $<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>)
endif()
target_compile_features(${target} ${__visibility} cxx_alias_templates
cxx_nullptr cxx_override)
if(_target_type STREQUAL EXECUTABLE)
set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(
${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
if(CMAKE_CXX_COMPILE_OPTIONS_PIE)
target_compile_options(${target} PUBLIC ${CMAKE_CXX_COMPILE_OPTIONS_PIE})
endif()
if(CMAKE_CXX_COMPILER_IS_GCC AND MYX_CMAKE_CODE_COVERAGE)
myx_cmake_code_coverage(${target})
endif()
endif()
if(APPLE)
target_compile_definitions(${target} ${__visibility} Darwin)
endif()
if(_target_type STREQUAL OBJECT_LIBRARY)
# target_include_directories(${target} PUBLIC
# $<INSTALL_INTERFACE:include/${target}>)
set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
# LTO only for executables (not libraries) in Release build type
if(_target_type STREQUAL EXECUTABLE AND CMAKE_BUILD_TYPE STREQUAL Release)
check_cxx_compiler_flag(-flto CXX_HAS_LTO_FLAG)
check_cxx_compiler_flag(-fno-fat-lto-objects CXX_HAS_NO_FAT_LTO_FLAG)
if(CXX_HAS_LTO_FLAG)
target_compile_options(${target} PUBLIC "-flto")
set_property(
TARGET ${target}
APPEND_STRING
PROPERTY LINK_FLAGS " -flto")
if(CXX_HAS_NO_FAT_LTO_FLAG)
target_compile_options(${target} PUBLIC "-fno-fat-lto-objects")
set_property(
TARGET ${target}
APPEND_STRING
PROPERTY LINK_FLAGS " -fno-fat-lto-objects")
endif()
endif()
endif()
# cmake-format: off
if(COMMAND cotire)
set_property(TARGET ${target}
PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${MYX_CMAKE_PRECOMPILED_HEADERS})
set_property(TARGET ${target}
PROPERTY COTIRE_ADD_UNITY_BUILD ${MYX_CMAKE_UNITY_BUILD})
endif()
# cmake-format: on
if(CMAKE_BUILD_TYPE STREQUAL Profile)
target_compile_definitions(${target} ${__visibility} PROFILE)
elseif(CMAKE_BUILD_TYPE STREQUAL Debug)
target_compile_definitions(${target} ${__visibility} DEBUG)
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
target_compile_definitions(${target} ${__visibility} RELEASE)
elseif(CMAKE_BUILD_TYPE STREQUAL None)
target_compile_definitions(${target} ${__visibility} ANALYSIS)
endif()
target_compile_definitions(
${target} ${__visibility}
"MYX_CMAKE_LSB_ID_${MYX_CMAKE_LSB_DISTRIBUTOR_ID}")
target_compile_definitions(
${target} ${__visibility}
"MYX_CMAKE_LSB_CODENAME_${MYX_CMAKE_LSB_CODENAME}")
myx_cmake_clang_tidy_analyze(${target})
myx_cmake_clang_check_analyze(${target})
myx_cmake_clazy_analyze(${target})
myx_cmake_pvs_studio_analyze(${target})
myx_cmake_format_sources(${target})
# Создание в каталоге ${CMAKE_BINARY_DIR} стандартных каталогов bin,include,lib
if(NOT TARGET ${target}-default-directories)
add_custom_target(
${target}-default-directories
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/bin
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/lib
)
add_dependencies(${target} ${target}-default-directories)
endif()
# Создание в каталоге ${CMAKE_BINARY_DIR} символических ссылок на каталоги в ${CMAKE_SOURCE_DIR}/files
if(NOT TARGET ${target}-symlinks AND UNIX)
add_custom_target(
${target}-symlinks
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
# Ссылка на каталог с журналами
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/files/log
${CMAKE_BINARY_DIR}/log
# Ссылка на каталог с обрабатываемыми данными
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/files/var
${CMAKE_BINARY_DIR}/var
# Ссылка на каталог с постоянными данными
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/files/share
${CMAKE_BINARY_DIR}/share
# Ссылка на каталог настроек
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/files/etc
${CMAKE_BINARY_DIR}/etc)
add_dependencies(${target} ${target}-symlinks)
endif()
endfunction()

View File

@@ -0,0 +1,64 @@
# C compiler name
if(CMAKE_C_COMPILER_ID STREQUAL "Intel")
set(CMAKE_C_COMPILER_IS_INTEL ON)
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL
"AppleClang")
set(CMAKE_C_COMPILER_IS_CLANG ON)
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(CMAKE_C_COMPILER_IS_GCC ON)
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_C_COMPILER_IS_MSVC ON)
endif()
# C++ compiler name
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(CMAKE_CXX_COMPILER_IS_INTEL ON)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL
"AppleClang")
set(CMAKE_CXX_COMPILER_IS_CLANG ON)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_COMPILER_IS_GCC ON)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_COMPILER_IS_MSVC ON)
endif()
# Предпочтительные пути к утилитам для компоновки
if(CMAKE_CXX_COMPILER_IS_GCC)
# Astra Linux Smolensk 1.5
if(MYX_CMAKE_LSB_DISTRIBUTOR_ID STREQUAL "AstraLinuxSE"
AND MYX_CMAKE_LSB_CODENAME STREQUAL "smolensk"
AND MYX_CMAKE_LSB_RELEASE STREQUAL "1.5")
find_program(CMAKE_GCC_AR NAMES "/usr/bin/x86_64-linux-gnu-gcc-ar-4.7")
find_program(CMAKE_GCC_NM NAMES "/usr/bin/x86_64-linux-gnu-gcc-nm-4.7")
find_program(CMAKE_GCC_RANLIB
NAMES "/usr/bin/x86_64-linux-gnu-gcc-ranlib-4.7")
# Elbrus E2K
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "e2k")
find_program(CMAKE_GCC_AR
NAMES "/usr/${CMAKE_SYSTEM_PROCESSOR}-linux/bin/ar")
find_program(CMAKE_GCC_NM
NAMES "/usr/${CMAKE_SYSTEM_PROCESSOR}-linux/bin/nm")
find_program(CMAKE_GCC_RANLIB
NAMES "/usr/${CMAKE_SYSTEM_PROCESSOR}-linux/bin/ranlib")
else()
find_program(CMAKE_GCC_AR NAMES "gcc-ar" "ar")
find_program(CMAKE_GCC_NM NAMES "gcc-nm" "nm")
find_program(CMAKE_GCC_RANLIB NAMES "gcc-ranlib" "ranlib")
endif()
if(CMAKE_GCC_AR)
set(CMAKE_AR
${CMAKE_GCC_AR}
CACHE STRING "" FORCE)
endif()
if(CMAKE_GCC_NM)
set(CMAKE_NM
${CMAKE_GCC_NM}
CACHE STRING "" FORCE)
endif()
if(CMAKE_GCC_RANLIB)
set(CMAKE_RANLIB
${CMAKE_GCC_RANLIB}
CACHE STRING "" FORCE)
endif()
endif()

View File

@@ -0,0 +1,240 @@
# based on https://github.com/bluescarni/yacma
include(CheckCXXCompilerFlag)
macro(CHECK_ENABLE_CXX_FLAG flag)
set(CMAKE_REQUIRED_QUIET TRUE)
check_cxx_compiler_flag("${flag}" CHECK_CXX_FLAG)
unset(CMAKE_REQUIRED_QUIET)
if(CHECK_CXX_FLAG)
message(STATUS "'${flag}': flag is supported.")
string(CONCAT _MYX_CMAKE_DETECTED_CXX_FLAGS
"${_MYX_CMAKE_DETECTED_CXX_FLAGS} ${flag}")
else()
message(STATUS "'${flag}': flag is NOT supported.")
endif()
# NOTE: check_cxx_compiler stores variables in the cache.
unset(CHECK_CXX_FLAG CACHE)
endmacro()
macro(CHECK_ENABLE_DEBUG_CXX_FLAG flag)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_REQUIRED_QUIET TRUE)
check_cxx_compiler_flag("${flag}" CHECK_CXX_FLAG_DEBUG)
unset(CMAKE_REQUIRED_QUIET)
if(CHECK_CXX_FLAG_DEBUG)
message(STATUS "'${flag}': debug flag is supported.")
string(CONCAT _MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG
"${_MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG} ${flag}")
else()
message(STATUS "'${flag}': debug flag is NOT supported.")
endif()
# NOTE: check_cxx_compiler stores variables in the cache.
unset(CHECK_CXX_FLAG_DEBUG CACHE)
endif()
endmacro()
function(myx_cmake_set_cxx_standard version)
# Выбор стандарта по умолчанию (можно переопределить в проекте)
set(CMAKE_CXX_STANDARD_REQUIRED
YES
PARENT_SCOPE)
if(version EQUAL 11)
set(CMAKE_CXX_STANDARD
11
PARENT_SCOPE)
set(CMAKE_CXX_EXTENSIONS
YES
PARENT_SCOPE)
endif()
if(version EQUAL 14)
set(CMAKE_CXX_STANDARD
14
PARENT_SCOPE)
set(CMAKE_CXX_EXTENSIONS
YES
PARENT_SCOPE)
endif()
if(version EQUAL 17)
if(${CMAKE_VERSION} VERSION_LESS "3.10.0")
check_cxx_compiler_flag(-std=gnu++17 HAVE_FLAG_STD_GNUXX17)
if(HAVE_FLAG_STD_GNUXX17)
add_compile_options("-std=gnu++17")
else()
check_cxx_compiler_flag(-std=gnu++1z HAVE_FLAG_STD_GNUXX1Z)
if(HAVE_FLAG_STD_GNUXX1Z)
add_compile_options("-std=gnu++1z")
else()
check_cxx_compiler_flag(-std=c++17 HAVE_FLAG_STD_CXX17)
if(HAVE_FLAG_STD_CXX17)
add_compile_options("-std=c++17")
else()
check_cxx_compiler_flag(-std=c++1z HAVE_FLAG_STD_CXX1Z)
if(HAVE_FLAG_STD_CXX1Z)
add_compile_options("-std=c++1z")
endif()
endif()
endif()
endif()
else()
set(CMAKE_CXX_STANDARD
17
PARENT_SCOPE)
set(CMAKE_CXX_EXTENSIONS
YES
PARENT_SCOPE)
endif()
endif()
endfunction()
if(NOT MYX_CMAKE_CXX_FLAGS_AUTODETECTION_DONE)
set(_MYX_CMAKE_DETECTED_CXX_FLAGS "")
set(_MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG "")
# Configuration bits specific for clang.
if(CMAKE_CXX_COMPILER_IS_CLANG)
if(CMAKE_COLOR_MAKEFILE)
check_enable_cxx_flag(-fcolor-diagnostics)
endif()
# For now it seems like -Wshadow from clang behaves better than GCC's, just
# enable it here for the time being.
check_enable_debug_cxx_flag(-Wshadow)
# New warnings in clang 8. NOTE: a few issues with macros here, let's
# disable for now. CHECK_ENABLE_DEBUG_CXX_FLAG(-Wextra-semi-stmt) New
# warnings in clang 10.
check_enable_debug_cxx_flag(-Wtautological-overlap-compare)
check_enable_debug_cxx_flag(-Wtautological-compare)
check_enable_debug_cxx_flag(-Wtautological-bitwise-compare)
check_enable_debug_cxx_flag(-Wbitwise-conditional-parentheses)
check_enable_debug_cxx_flag(-Wrange-loop-analysis)
check_enable_debug_cxx_flag(-Wmisleading-indentation)
check_enable_debug_cxx_flag(-Wc99-designator)
check_enable_debug_cxx_flag(-Wreorder-init-list)
check_enable_debug_cxx_flag(-Wsizeof-pointer-div)
check_enable_debug_cxx_flag(-Wsizeof-array-div)
check_enable_debug_cxx_flag(-Wxor-used-as-pow)
check_enable_debug_cxx_flag(-Wfinal-dtor-non-final-class)
# NOTE: this is a new flag in Clang 13 which seems to give
# incorrect warnings for UDLs.
check_enable_debug_cxx_flag(-Wno-reserved-identifier)
endif()
# Common configuration for GCC, clang and Intel.
if(CMAKE_CXX_COMPILER_IS_CLANG
OR CMAKE_CXX_COMPILER_IS_INTEL
OR CMAKE_CXX_COMPILER_IS_GCC)
check_enable_debug_cxx_flag(-Wall)
check_enable_debug_cxx_flag(-Wextra)
check_enable_debug_cxx_flag(-Wnon-virtual-dtor)
check_enable_debug_cxx_flag(-Wnoexcept)
check_enable_debug_cxx_flag(-Wlogical-op)
check_enable_debug_cxx_flag(-Wconversion)
check_enable_debug_cxx_flag(-Wdeprecated)
# This limit is supposed to be at least 1024 in C++11, but for some reason
# clang sets this to 256, and gcc to 900.
check_enable_cxx_flag(-ftemplate-depth=1024)
check_enable_debug_cxx_flag(-Wold-style-cast)
check_enable_debug_cxx_flag(-Wdisabled-optimization)
# This is useful when the compiler decides the template backtrace is too
# verbose.
check_enable_debug_cxx_flag(-ftemplate-backtrace-limit=0)
check_enable_debug_cxx_flag(-fstack-protector-all)
# A few suggestion flags.
check_enable_debug_cxx_flag(-Wsuggest-attribute=pure)
check_enable_debug_cxx_flag(-Wsuggest-attribute=const)
check_enable_debug_cxx_flag(-Wsuggest-attribute=noreturn)
check_enable_debug_cxx_flag(-Wsuggest-attribute=format)
# From GCC 5.
check_enable_debug_cxx_flag(-Wodr)
check_enable_debug_cxx_flag(-Wsuggest-final-types)
check_enable_debug_cxx_flag(-Wsuggest-final-methods)
check_enable_debug_cxx_flag(-Wsuggest-override)
# From GCC 6.
check_enable_debug_cxx_flag(-Wshift-negative-value)
check_enable_debug_cxx_flag(-Wshift-overflow=2)
check_enable_debug_cxx_flag(-Wduplicated-cond)
check_enable_debug_cxx_flag(-Wnull-dereference)
# From GCC 7.
check_enable_debug_cxx_flag(-Wrestrict)
check_enable_debug_cxx_flag(-Waligned-new)
check_enable_debug_cxx_flag(-fdiagnostics-parseable-fixits)
check_enable_debug_cxx_flag(-fdiagnostics-generate-patch)
# From GCC 8.
check_enable_debug_cxx_flag(-Wcast-align=strict)
# This is supposed to produce a nice graphical visualization of mismatching
# template errors.
check_enable_cxx_flag(-fdiagnostics-show-template-tree)
check_enable_debug_cxx_flag(-fdiagnostics-show-option)
check_enable_debug_cxx_flag(-pedantic)
check_enable_debug_cxx_flag(-Wcast-align)
check_enable_debug_cxx_flag(-Wcast-qual)
check_enable_debug_cxx_flag(-Wctor-dtor-privacy)
check_enable_debug_cxx_flag(-Wdisabled-optimization)
check_enable_debug_cxx_flag(-Wformat=2)
check_enable_debug_cxx_flag(-Winit-self)
check_enable_debug_cxx_flag(-Wmissing-include-dirs)
check_enable_debug_cxx_flag(-Woverloaded-virtual)
check_enable_debug_cxx_flag(-Wredundant-decls)
check_enable_debug_cxx_flag(-Wsign-promo)
check_enable_debug_cxx_flag(-Wstrict-overflow=5)
check_enable_debug_cxx_flag(-Wundef)
check_enable_debug_cxx_flag(-Wno-unused)
check_enable_debug_cxx_flag(-Wno-variadic-macros)
check_enable_debug_cxx_flag(-Wno-parentheses)
check_enable_debug_cxx_flag(-Wstrict-null-sentinel)
check_enable_debug_cxx_flag(-Wshadow-all)
endif()
if(CMAKE_CXX_COMPILER_IS_GCC)
if(CMAKE_COLOR_MAKEFILE)
check_enable_cxx_flag(-fdiagnostics-color=auto)
endif()
# The -Wmaybe-uninitialized flag is enabled by -Wall, but it is known to
# emit a lot of possibly spurious warnings. Let's just disable it.
check_enable_debug_cxx_flag(-Wno-maybe-uninitialized)
# New in GCC 9.
check_enable_debug_cxx_flag(-Waddress-of-packed-member)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.999")
# NOTE: GCC >= 6 seems to be wrongly warning about visibility attributes
# in some situations: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80947
# Let's just disable the warning for now.
check_enable_cxx_flag(-Wno-attributes)
endif()
endif()
# cmake-format: off
if(MYX_CMAKE_LSB_DISTRIBUTOR_ID STREQUAL "AstraLinuxSE" AND
MYX_CMAKE_LSB_CODENAME STREQUAL "smolensk" AND
MYX_CMAKE_LSB_RELEASE STREQUAL "1.5")
# cmake-format: on
myx_cmake_set_cxx_standard(11)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "e2k")
myx_cmake_set_cxx_standard(14)
check_enable_debug_cxx_flag(-Wno-invalid-offsetof)
list(APPEND CMAKE_LIBRARY_PATH "/usr/lib/e2k-linux-gnu")
else()
myx_cmake_set_cxx_standard(17)
# -Wshadow gives a lot of false positives with GCC 4.7.2 in Astra Linux 1.5
if(CMAKE_CXX_COMPILER_IS_GCC)
check_enable_debug_cxx_flag(-Wshadow)
endif()
endif()
# Set the cache variables.
set(MYX_CMAKE_DETECTED_CXX_FLAGS
"${_MYX_CMAKE_DETECTED_CXX_FLAGS}"
CACHE INTERNAL "")
set(MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG
"${_MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG}"
CACHE INTERNAL "")
set(MYX_CMAKE_CXX_FLAGS_AUTODETECTION_DONE
YES
CACHE INTERNAL "")
endif()

View File

@@ -0,0 +1,18 @@
# По умолчанию отключена отладочная печать (если не включена явно программистом)
option(MYX_CMAKE_DEBUG_OUTPUT "Enable debug output" OFF)
option(MYX_CMAKE_INFO_OUTPUT "Enable info output" OFF)
option(MYX_CMAKE_WARNING_OUTPUT "Enable warning output" OFF)
# Если сборка производится в режиме для отладки, то включаются флаги для
# разрешения отладочной печати
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(MYX_CMAKE_DEBUG_OUTPUT
ON
CACHE BOOL "" FORCE)
set(MYX_CMAKE_INFO_OUTPUT
ON
CACHE BOOL "" FORCE)
set(MYX_CMAKE_WARNING_OUTPUT
ON
CACHE BOOL "" FORCE)
endif()

View File

@@ -0,0 +1,13 @@
find_program(DISTCC_EXECUTABLE distcc)
mark_as_advanced(DISTCC_EXECUTABLE)
if(DISTCC_EXECUTABLE)
foreach(lang C CXX)
if(NOT DEFINED CMAKE_${lang}_COMPILER_LAUNCHER
AND NOT CMAKE_${lang}_COMPILER MATCHES ".*/distcc$")
message(STATUS "MyxCMake: distcc enabled for ${lang}")
set(CMAKE_${lang}_COMPILER_LAUNCHER
${DISTCC_EXECUTABLE}
CACHE STRING "")
endif()
endforeach()
endif()

View File

@@ -0,0 +1,52 @@
function(myx_cmake_format_sources target)
get_target_property(__sources ${target} SOURCES)
list(FILTER __sources EXCLUDE REGEX "qrc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "moc_.*\\.cpp$")
list(FILTER __sources EXCLUDE REGEX "ui_.*\\.h$")
if(NOT TARGET myx-cmake-format-sources)
add_custom_target(myx-cmake-format-sources)
endif()
if(NOT TARGET myx-cmake-check-format-sources)
add_custom_target(myx-cmake-check-format-sources)
endif()
if(NOT TARGET myx-cmake-add-doxygen-comments)
add_custom_target(myx-cmake-add-doxygen-comments)
endif()
find_program(UNCRUSTIFY_EXE NAMES uncrustify)
if(UNCRUSTIFY_EXE)
if(EXISTS ${CMAKE_SOURCE_DIR}/files/etc/uncrustify.cfg)
list(APPEND UNCRUSTIFY_OPTS -c ${CMAKE_SOURCE_DIR}/files/etc/uncrustify.cfg)
endif()
# cmake-format: off
add_custom_target(${target}-check-format-sources-uncrustify
COMMAND ${UNCRUSTIFY_EXE} ${UNCRUSTIFY_OPTS} --check ${__sources})
list(APPEND UNCRUSTIFY_OPTS --replace --no-backup)
add_custom_target(${target}-format-sources-uncrustify
COMMAND ${UNCRUSTIFY_EXE} ${UNCRUSTIFY_OPTS} --mtime ${__sources})
add_custom_target(${target}-add-doxygen-comments-uncrustify
COMMAND ${UNCRUSTIFY_EXE} ${UNCRUSTIFY_OPTS}
--set cmt_insert_file_header=fileheader.txt
--set cmt_insert_file_footer=filefooter.txt
--set cmt_insert_func_header=funcheader.txt
--set cmt_insert_class_header=classheader.txt
--set cmt_insert_before_ctor_dtor=true ${__sources})
# cmake-format: on
add_dependencies(myx-cmake-check-format-sources ${target}-check-format-sources-uncrustify)
add_dependencies(myx-cmake-format-sources ${target}-format-sources-uncrustify)
add_dependencies(myx-cmake-add-doxygen-comments ${target}-add-doxygen-comments-uncrustify)
else()
message(STATUS "MyxCMake: uncrustify executable is not found")
endif()
find_program(DOS2UNIX_EXE NAMES dos2unix)
if(DOS2UNIX_EXE)
list(APPEND DOS2UNIX_OPTS -k -r)
add_custom_target(${target}-format-sources-dos2unix COMMAND ${DOS2UNIX_EXE} ${DOS2UNIX_OPTS} ${__sources})
add_dependencies(myx-cmake-format-sources ${target}-format-sources-dos2unix)
else()
message(STATUS "MyxCMake: dos2unix executable is not found")
endif()
endfunction()

View File

@@ -0,0 +1,19 @@
# Формирование строки, состоящей из заглавных символов, цифр и подчёркиваний
function(myx_cmake_canonical_string in_string out_string)
string(TOUPPER ${in_string} _arg_uppercase)
string(REGEX REPLACE "[ -]" "_" _arg_fixed ${_arg_uppercase})
set(${out_string}
${_arg_fixed}
PARENT_SCOPE)
endfunction()
# Добавление общего префикса ко всем переменным в списке
function(myx_cmake_list_transform_prepend var prefix)
set(temp "")
foreach(filename ${${var}})
list(APPEND temp "${prefix}${filename}")
endforeach()
set(${var}
"${temp}"
PARENT_SCOPE)
endfunction()

View File

@@ -0,0 +1,29 @@
if(NOT MYX_CMAKE_THEME_NAME)
set(MYX_CMAKE_THEME_NAME "default")
endif()
# cmake-format: off
myx_cmake_canonical_string(${MYX_CMAKE_ORGANIZATION_NAME} MYX_CMAKE_ORGANIZATION_NAME_CANONICAL)
myx_cmake_canonical_string(${PROJECT_NAME} MYX_CMAKE_PROJECT_NAME_CANONICAL)
myx_cmake_canonical_string(${MYX_CMAKE_THEME_NAME} MYX_CMAKE_THEME_NAME_CANONICAL)
string(TOLOWER ${MYX_CMAKE_ORGANIZATION_NAME_CANONICAL} MYX_CMAKE_ORGANIZATION_NAME_LOWER)
string(TOLOWER ${MYX_CMAKE_PROJECT_NAME_CANONICAL} MYX_CMAKE_PROJECT_NAME_LOWER)
string(TOLOWER ${MYX_CMAKE_THEME_NAME_CANONICAL} MYX_CMAKE_THEME_NAME_LOWER)
string(TOUPPER ${MYX_CMAKE_ORGANIZATION_NAME_CANONICAL} MYX_CMAKE_ORGANIZATION_NAME_UPPER)
string(TOUPPER ${MYX_CMAKE_PROJECT_NAME_CANONICAL} MYX_CMAKE_PROJECT_NAME_UPPER)
string(TOUPPER ${MYX_CMAKE_THEME_NAME_CANONICAL} MYX_CMAKE_THEME_NAME_UPPER)
# cmake-format: on
option(MYX_CMAKE_ADD_THEME_PREFIX "Append theme name to install prefix" OFF)
if(MYX_CMAKE_ADD_THEME_PREFIX AND NOT MYX_CMAKE_THEME_PREFIX_APPENDED)
if(NOT MYX_CMAKE_THEME_NAME_LOWER STREQUAL "default")
set(MYX_CMAKE_THEME_PREFIX_APPENDED
ON
CACHE BOOL "" FORCE)
set(CMAKE_INSTALL_PREFIX
"${CMAKE_INSTALL_PREFIX}/${MYX_CMAKE_THEME_NAME}"
CACHE PATH "" FORCE)
endif()
endif()

View File

@@ -0,0 +1,29 @@
if(CMAKE_CROSSCOMPILING)
return()
endif()
if(MYX_CMAKE_LSB_RELEASE)
return()
endif()
set(MYX_CMAKE_LSB_DISTRIBUTOR_ID "unknown")
set(MYX_CMAKE_LSB_CODENAME "unknown")
set(MYX_CMAKE_LSB_RELEASE "unknown")
if(EXISTS /etc/mcst_version)
set(MYX_CMAKE_LSB_DISTRIBUTOR_ID "ElbrusD")
set(MYX_CMAKE_LSB_CODENAME "Jessie")
execute_process(
COMMAND cat /etc/mcst_version
OUTPUT_VARIABLE MYX_CMAKE_LSB_RELEASE
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
find_program(_lsb_release_executable lsb_release)
# cmake-format: off
if(_lsb_release_executable)
execute_process(COMMAND ${_lsb_release_executable} -si OUTPUT_VARIABLE MYX_CMAKE_LSB_DISTRIBUTOR_ID OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${_lsb_release_executable} -sc OUTPUT_VARIABLE MYX_CMAKE_LSB_CODENAME OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${_lsb_release_executable} -sr OUTPUT_VARIABLE MYX_CMAKE_LSB_RELEASE OUTPUT_STRIP_TRAILING_WHITESPACE)
# cmake-format: on
endif()
endif()

View File

@@ -0,0 +1,9 @@
# Если выбран генератор Ninja, то в основном сборочном каталоге создаётся файл
# Makefile, который обрабатывается командой make и передаёт исполнение системе
# сборки ninja. Таким образом можно выполнять команду make, даже если правила
# сборки проекта сгенерированы для ninja.
if(CMAKE_GENERATOR MATCHES Ninja)
file(WRITE ${CMAKE_BINARY_DIR}/Makefile
".PHONY: build\n" "%:\n" "\t@ninja \$@\n" "build:\n" "\t@ninja\n")
endif()

View File

@@ -0,0 +1,47 @@
function(myx_cmake_generate_pkgconfig target)
set(options)
set(oneVA COMPONENT)
set(multiVA)
cmake_parse_arguments(ARG "${options}" "${oneVA}" "${multiVA}" ${ARGN})
if(NOT ARG_COMPONENT)
set(ARG_COMPONENT "base-dev")
endif()
get_target_property(_target_type ${target} TYPE)
if(_target_type STREQUAL INTERFACE_LIBRARY)
file(
WRITE "${CMAKE_BINARY_DIR}/${target}.pc"
"prefix=${CMAKE_INSTALL_PREFIX}\n"
"exec_prefix=${CMAKE_INSTALL_PREFIX}\n"
"includedir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n"
"\n"
"Name: ${target}\n"
"Description: ${target} header-only library\n"
"Version: ${PROJECT_VERSION}\n"
"\n"
"Requires:\n"
"Cflags: -I${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n")
else()
file(
WRITE "${CMAKE_BINARY_DIR}/${target}.pc"
"prefix=${CMAKE_INSTALL_PREFIX}\n"
"exec_prefix=${CMAKE_INSTALL_PREFIX}\n"
"libdir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\n"
"includedir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n"
"\n"
"Name: ${target}\n"
"Description: ${target} library\n"
"Version: ${PROJECT_VERSION}\n"
"\n"
"Requires:\n"
"Libs: -L${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} -l${target}\n"
"Cflags: -I${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n")
endif()
install(
FILES "${CMAKE_BINARY_DIR}/${target}.pc"
COMPONENT ${ARG_COMPONENT}
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endfunction()

View File

@@ -0,0 +1,10 @@
if(${CMAKE_VERSION} VERSION_LESS "3.16.0")
include(cotire OPTIONAL)
if(COMMAND cotire)
option(MYX_CMAKE_PRECOMPILED_HEADERS "MyxCMake: enable precompiled headers"
OFF)
endif()
else()
option(MYX_CMAKE_PRECOMPILED_HEADERS "MyxCMake: enable precompiled headers"
OFF)
endif()

View File

@@ -0,0 +1,17 @@
function(myx_cmake_check_project_version)
if(NOT ${PROJECT_VERSION_PATCH} MATCHES "([0-9]+)")
message(FATAL_ERROR "MyxCMake: Please set project version in X.Y.Z format")
endif()
endfunction()
function(myx_cmake_set_project_version_int)
myx_cmake_check_project_version()
math(
EXPR
_version_int
"(${PROJECT_VERSION_MAJOR} << 16) + (${PROJECT_VERSION_MINOR} << 8) + ${PROJECT_VERSION_PATCH}"
)
set_property(GLOBAL PROPERTY PROJECT_VERSION_INT ${_version_int})
endfunction()
myx_cmake_set_project_version_int()

View File

@@ -0,0 +1,34 @@
#
# Обязательные переменные, значения которым необходимо присвоить в файле
# CMakeLists.txt до подключения MyxCMake, либо передать из командной строки
# через ключ -D
#
if(NOT MYX_CMAKE_ORGANIZATION_NAME)
message(
FATAL_ERROR
"MyxCMake: Required variable MYX_CMAKE_ORGANIZATION_NAME is not defined")
endif()
if(NOT MYX_CMAKE_AUTHOR_NAME)
message(
FATAL_ERROR
"MyxCMake: Required variable MYX_CMAKE_AUTHOR_NAME is not defined")
endif()
if(NOT MYX_CMAKE_AUTHOR_EMAIL)
message(
FATAL_ERROR
"MyxCMake: Required variable MYX_CMAKE_AUTHOR_EMAIL is not defined")
endif()
set(CPACK_PACKAGE_CONTACT
"${MYX_CMAKE_AUTHOR_NAME} <${MYX_CMAKE_AUTHOR_EMAIL}>"
CACHE STRING "")
if(NOT MYX_CMAKE_DESCRIPTION)
message(
FATAL_ERROR
"MyxCMake: Required variable MYX_CMAKE_DESCRIPTION is not defined")
endif()
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
${MYX_CMAKE_DESCRIPTION}
CACHE STRING "")

View File

@@ -0,0 +1,8 @@
if(NOT TODAY)
if(WIN32)
execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE TODAY)
else()
execute_process(COMMAND "date" "+%d/%m/%Y" OUTPUT_VARIABLE TODAY)
endif()
string(REGEX REPLACE "(..)/(..)/(....).*" "\\3-\\2-\\1" TODAY ${TODAY})
endif()

View File

@@ -0,0 +1,6 @@
if(NOT TARGET uninstall)
configure_file("${CMAKE_CURRENT_LIST_DIR}/CMLibUninstall.cmake.in"
"${CMAKE_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake_uninstall.cmake)
endif()

View File

@@ -0,0 +1,31 @@
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)
# Удаление пустых каталогов
foreach(_file ${files})
set(_res 0)
while(_res EQUAL 0)
get_filename_component(_file ${_file} DIRECTORY)
execute_process(COMMAND rmdir ${_file} RESULT_VARIABLE _res OUTPUT_QUIET ERROR_QUIET)
endwhile()
endforeach()

View File

@@ -0,0 +1,8 @@
if(${CMAKE_VERSION} VERSION_LESS "3.16.0")
include(cotire OPTIONAL)
if(COMMAND cotire)
option(MYX_CMAKE_UNITY_BUILD "Enable unity build" OFF)
endif()
else()
option(MYX_CMAKE_UNITY_BUILD "Enable unity build" OFF)
endif()