diff --git a/.gitignore b/.gitignore index 1e50ba1..538a95c 100644 --- a/.gitignore +++ b/.gitignore @@ -67,7 +67,7 @@ tags ### # -export_autogen.hpp +*_export.hpp # Prerequisites *.d diff --git a/CMakeLists.txt b/CMakeLists.txt index a05b8d2..5237f9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,27 +9,31 @@ project(msg VERSION 1.1.1 LANGUAGES CXX) ### # Подключение дополнительных функций для CMake +# По умолчанию предполагается использование версии MyxCMake, +# файлы которой находятся в каталоге `cmake/myx` текущего проекта. +# Если определена переменная `MYX_CMAKE_USE_SYSTEM`, то выполняется +# поиск версии в каталогах перечисленных в переменной `CMAKE_MODULES_DIR`. ### -find_package(MyxCMake 1.99.9 PATHS ${PROJECT_SOURCE_DIR}/cmake/myx NO_DEFAULT_PATH QUIET REQUIRED) +if(MYX_CMAKE_USE_SYSTEM) + find_package(MyxCMake 1.99.9 PATHS "${PROJECT_SOURCE_DIR}/cmake/myx" NO_DEFAULT_PATH QUIET REQUIRED) +else() + include(${PROJECT_SOURCE_DIR}/cmake/myx/MyxCMakeConfig.cmake) +endif() # Если проект верхнего уровня, подключаем зависимости # с помощью модуля FetchContent if(PROJECT_IS_TOP_LEVEL) - include(FetchContent) - FetchContent_Declare(pow + FetchContent_Add(pow GIT_REPOSITORY https://git.246060.ru/cmake/pow - ) - if(NOT pow_POPULATED) - FetchContent_Populate(pow) - add_subdirectory(${pow_SOURCE_DIR} ${pow_BINARY_DIR}) - endif() + GIT_PATH cmake/pow + GIT_REMOTE origin + ) endif() # Цель для компиляции объектных файлов разделяемой библиотеки -myx_add_library(${PROJECT_NAME} - TYPE OBJECT -) +myx_add_library(${PROJECT_NAME} OBJECT) +# Настройка свойств цели myx_target_setup(${PROJECT_NAME} SOURCES ${PROJECT_SOURCE_DIR}/include/msg/message.hpp @@ -40,6 +44,5 @@ myx_target_setup(${PROJECT_NAME} pow ) -if(PROJECT_IS_TOP_LEVEL) - myx_install_library(${PROJECT_NAME}) -endif() +# Команды для установки библиотеки +myx_install_library(${PROJECT_NAME}) diff --git a/cmake/myx/MyxCMakeConfig.cmake b/cmake/myx/MyxCMakeConfig.cmake index 5bb204f..842c9f7 100644 --- a/cmake/myx/MyxCMakeConfig.cmake +++ b/cmake/myx/MyxCMakeConfig.cmake @@ -3,23 +3,22 @@ cmake_policy(SET CMP0057 NEW) # IN_LIST operator get_filename_component(MYX_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) -set(MYX_CMAKE_CONFIG_DIR "${MYX_CMAKE_SOURCE_DIR}/config") set(MYX_CMAKE_BACKPORTS_DIR "${MYX_CMAKE_SOURCE_DIR}/backports") set(MYX_CMAKE_LIB_DIR "${MYX_CMAKE_SOURCE_DIR}/lib") -include(${MYX_CMAKE_CONFIG_DIR}/Globals.cmake) - include(${MYX_CMAKE_BACKPORTS_DIR}/IncludeGuard.cmake) include(${MYX_CMAKE_BACKPORTS_DIR}/TopLevelProject.cmake) if(${CMAKE_VERSION} VERSION_LESS "3.11.0") include(${MYX_CMAKE_BACKPORTS_DIR}/FetchContent.cmake) endif() +include(${MYX_CMAKE_LIB_DIR}/Includes.cmake) include(${MYX_CMAKE_LIB_DIR}/ColoredMessages.cmake) include(${MYX_CMAKE_LIB_DIR}/NinjaGeneratorWarning.cmake) include(${MYX_CMAKE_LIB_DIR}/DirectoriesGuards.cmake) include(${MYX_CMAKE_LIB_DIR}/SemanticProjectVersion.cmake) include(${MYX_CMAKE_LIB_DIR}/NinjaGeneratorWrapper.cmake) +include(${MYX_CMAKE_LIB_DIR}/FetchContentAdd.cmake) include(${MYX_CMAKE_LIB_DIR}/AddLibrary.cmake) include(${MYX_CMAKE_LIB_DIR}/InstallLibrary.cmake) @@ -28,7 +27,6 @@ include(${MYX_CMAKE_LIB_DIR}/Qt5TargetSetup.cmake) unset(MYX_CMAKE_SOURCE_DIR) unset(MYX_CMAKE_BACKPORTS_DIR) -unset(MYX_CMAKE_CONFIG_DIR) unset(MYX_CMAKE_LIB_DIR) cmake_policy(POP) diff --git a/cmake/myx/config/Globals.cmake b/cmake/myx/config/Globals.cmake deleted file mode 100644 index 239ce77..0000000 --- a/cmake/myx/config/Globals.cmake +++ /dev/null @@ -1,8 +0,0 @@ -include(GNUInstallDirs) - -#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} PARENT_SCOPE) -#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} PARENT_SCOPE) -#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} PARENT_SCOPE) - -#set(MYX_CMAKE_SCRIPTS_PREFIX ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} PARENT_SCOPE) - diff --git a/cmake/myx/lib/AddLibrary.cmake b/cmake/myx/lib/AddLibrary.cmake index 74b1769..75b5ea8 100644 --- a/cmake/myx/lib/AddLibrary.cmake +++ b/cmake/myx/lib/AddLibrary.cmake @@ -1,20 +1,42 @@ +#[=======================================================================[.rst: +myx_add_library +--------------- + +Вспомогательная функция для создания библиотеки:: + + myx_add_library(NAME TYPE) + +Обязательные параметры: `NAME` - имя библиотеки и `TYPE` - тип цели. +Все остальные параметры передаются стандартной функции `add_library()` + +#]=======================================================================] + include_guard(GLOBAL) include(GenerateExportHeader) -function(myx_add_library NAME) +function(myx_add_library NAME TYPE) set(options) - set(oneValueArgs TYPE) - set(multiValueArgs SOURCES) - cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + set(oneValueArgs) + set(multiValueArgs) - if(NOT arg_TYPE) - set(arg_TYPE "OBJECT") + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Вызов стандартной функции `add_library()` + add_library(${NAME} ${TYPE} ${ARG_UNPARSED_ARGUMENTS}) + + # Если вызов был выполнен не из проекта верхнего уровня, + # то созданная цель исключается из цели `all`. + # При этом сама цель `${NAME}` может участвовать в сборке, + # если окажется в перечне зависимостей. + if(NOT PROJECT_IS_TOP_LEVEL) + set_target_properties(${NAME} PROPERTIES + EXCLUDE_FROM_ALL True + ) endif() - add_library(${NAME} ${arg_TYPE}) - - if(arg_TYPE STREQUAL INTERFACE) + if(TYPE STREQUAL INTERFACE) + # Стандартные пути к заголовочным файлам target_include_directories(${NAME} INTERFACE $ @@ -27,10 +49,12 @@ function(myx_add_library NAME) # Опция для разрешения сборки статической библиотеки option(${PROJECT_NAME_UPPER}_BUILD_STATIC "Build static library" ON) + # Стандартные пути к заголовочным файлам target_include_directories(${NAME} PUBLIC $ PRIVATE + $ $ ) @@ -38,14 +62,14 @@ function(myx_add_library NAME) string(TOUPPER ${NAME} suffix) generate_export_header(${NAME} - BASE_NAME "${suffix}" - EXPORT_MACRO_NAME "EXPORT_${suffix}" - DEPRECATED_MACRO_NAME "DEPRECATED_${suffix}" - NO_DEPRECATED_MACRO_NAME "NO_DEPRECATED_${suffix}" - NO_EXPORT_MACRO_NAME "NO_EXPORT_${suffix}" - STATIC_DEFINE "STATIC_DEFINE_${suffix}" - EXPORT_FILE_NAME "${PROJECT_SOURCE_DIR}/include/${NAME}/export_autogen.hpp" - DEFINE_NO_DEPRECATED + BASE_NAME ${suffix} + EXPORT_MACRO_NAME "EXPORT_${suffix}" + DEPRECATED_MACRO_NAME "DEPRECATED_${suffix}" + NO_DEPRECATED_MACRO_NAME "NO_DEPRECATED_${suffix}" + NO_EXPORT_MACRO_NAME "NO_EXPORT_${suffix}" + STATIC_DEFINE "STATIC_DEFINE_${suffix}" + EXPORT_FILE_NAME "${PROJECT_SOURCE_DIR}/include/${NAME}/${NAME}_export.hpp" + DEFINE_NO_DEPRECATED ) # Цель для создания разделяемой библиотеки из объектных файлов diff --git a/cmake/myx/lib/ColoredMessages.cmake b/cmake/myx/lib/ColoredMessages.cmake index 5ae5f3d..8517f6c 100644 --- a/cmake/myx/lib/ColoredMessages.cmake +++ b/cmake/myx/lib/ColoredMessages.cmake @@ -1,4 +1,9 @@ -# Обёртки для функций вывода сообщений +#[=======================================================================[.rst: + +Обёртки для функции `message()`, которые в терминале UNIX +подсвечиают сообщения в зависимости от важности. + +#]=======================================================================] include_guard(GLOBAL) @@ -22,14 +27,22 @@ if(DEFINED ENV{TERM} AND UNIX) set(MyxColorBoldWhite "${Esc}[1;37m") endif() -function(myx_message_error) +function(myx_message_fatal_error) message(FATAL_ERROR ${MyxColorBoldRed}${ARGV}${MyxColorReset}) endfunction() +function(myx_message_send_error) + message(SEND_ERROR ${MyxColorBoldRed}${ARGV}${MyxColorReset}) +endfunction() + function(myx_message_warning) message(WARNING ${MyxColorRed}${ARGV}${MyxColorReset}) endfunction() +function(myx_message_deprecation) + message(DEPRECATION ${MyxColorBoldMagenta}${ARGV}${MyxColorReset}) +endfunction() + function(myx_message_status) message(STATUS ${MyxColorMagenta}${ARGV}${MyxColorReset}) endfunction() diff --git a/cmake/myx/lib/DirectoriesGuards.cmake b/cmake/myx/lib/DirectoriesGuards.cmake index addab82..459cfbe 100644 --- a/cmake/myx/lib/DirectoriesGuards.cmake +++ b/cmake/myx/lib/DirectoriesGuards.cmake @@ -1,8 +1,12 @@ -# Запись результатов сборки проекта внутрь иерархии каталогов с исходными текстами -# приводит к засорению файлами формируемыми на этапе сборки, которые затрудняют -# разработку, поиск в оригинальных файлах и мешают ориентироваться в проекте. -# При работе с несколькими типами сборки, например, отладка и выпуск, появляется -# необходимость корректного полного удаления результатов предыдущего варианта. +#[=======================================================================[.rst: + +Запись результатов сборки проекта внутрь иерархии каталогов с исходными текстами +приводит к засорению файлами формируемыми на этапе сборки, которые затрудняют +разработку, поиск в оригинальных файлах и мешают ориентироваться в проекте. +При работе с несколькими типами сборки, например, отладка и выпуск, появляется +необходимость корректного полного удаления результатов предыдущего варианта. + +#]=======================================================================] include_guard(GLOBAL) @@ -47,4 +51,3 @@ unset(cmake_binary_dir) unset(project_source_dir) unset(project_binary_dir) unset(cmake_install_prefix) - diff --git a/cmake/myx/lib/FetchContentAdd.cmake b/cmake/myx/lib/FetchContentAdd.cmake new file mode 100644 index 0000000..e531de4 --- /dev/null +++ b/cmake/myx/lib/FetchContentAdd.cmake @@ -0,0 +1,35 @@ +include_guard(GLOBAL) + +function(FetchContent_Add NAME) + set(options "") + set(oneValueArgs GIT_REPOSITORY GIT_REMOTE GIT_PATH) + set(multiValueArgs "") + + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + find_package(Git) + if(GIT_FOUND AND arg_GIT_REMOTE AND arg_GIT_PATH) + execute_process(COMMAND ${GIT_EXECUTABLE} config --get remote.${arg_GIT_REMOTE}.url OUTPUT_VARIABLE REMOTE_URL ERROR_QUIET) + if(REMOTE_URL) + string(REGEX REPLACE ":.*" "" SERVER ${REMOTE_URL}) + string(FIND ${SERVER} "http" POS) + if(NOT POS EQUAL 0) + if(NOT SERVER STREQUAL REMOTE_URL) + set(arg_GIT_REPOSITORY "${SERVER}:${arg_GIT_PATH}") + endif() + endif() + endif() + endif() + + FetchContent_Declare( + ${NAME} + ${arg_UNPARSED_ARGUMENTS} + GIT_REPOSITORY ${arg_GIT_REPOSITORY} + ) + + if(NOT ${NAME}_POPULATED) + FetchContent_Populate(${NAME}) + add_subdirectory(${${NAME}_SOURCE_DIR} ${${NAME}_BINARY_DIR}) + endif() + +endfunction() diff --git a/cmake/myx/lib/Includes.cmake b/cmake/myx/lib/Includes.cmake new file mode 100644 index 0000000..8b54c46 --- /dev/null +++ b/cmake/myx/lib/Includes.cmake @@ -0,0 +1,4 @@ +include_guard(GLOBAL) + +include(FetchContent) +include(GNUInstallDirs) diff --git a/cmake/myx/lib/InstallLibrary.cmake b/cmake/myx/lib/InstallLibrary.cmake index f2a18d4..21296ed 100644 --- a/cmake/myx/lib/InstallLibrary.cmake +++ b/cmake/myx/lib/InstallLibrary.cmake @@ -11,6 +11,8 @@ function(myx_install_library NAME) return() endif() + get_target_property(type ${NAME} TYPE) + write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${NAME}ConfigVersion.cmake VERSION ${PROJECT_VERSION} @@ -43,22 +45,30 @@ function(myx_install_library NAME) COMPONENT dev ) - if(TARGET ${NAME}_shared) - install( - TARGETS ${NAME}_shared - EXPORT ${NAME}Targets - LIBRARY - DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT lib - ) + if(${type} STREQUAL "OBJECT_LIBRARY") + if(TARGET ${NAME}_shared) + install( + TARGETS ${NAME}_shared + EXPORT ${NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT lib + ) + endif() + + if(TARGET ${NAME}_static) + install( + TARGETS ${NAME}_static + EXPORT ${NAME}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT lib + ) + endif() endif() - if(TARGET ${NAME}_static) + if(${type} STREQUAL "INTERFACE_LIBRARY") install( - TARGETS ${NAME}_static + TARGETS ${NAME} EXPORT ${NAME}Targets - ARCHIVE - DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib ) endif()