diff --git a/cmake/myx/MyxCMakeConfig.cmake b/cmake/myx/MyxCMakeConfig.cmake index 4970a97..b3378fe 100644 --- a/cmake/myx/MyxCMakeConfig.cmake +++ b/cmake/myx/MyxCMakeConfig.cmake @@ -9,6 +9,7 @@ get_filename_component(MYX_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTO set(MYX_CMAKE_BACKPORTS_DIR "${MYX_CMAKE_SOURCE_DIR}/backports") set(MYX_CMAKE_LIB_DIR "${MYX_CMAKE_SOURCE_DIR}/lib") +include(${MYX_CMAKE_LIB_DIR}/macro/FindPackages.cmake) include(${MYX_CMAKE_LIB_DIR}/macro/InstallRelative.cmake) include(${MYX_CMAKE_BACKPORTS_DIR}/IncludeGuard.cmake) @@ -18,6 +19,7 @@ if(${CMAKE_VERSION} VERSION_LESS "3.11.0") endif() include(${MYX_CMAKE_LIB_DIR}/Includes.cmake) +include(${MYX_CMAKE_LIB_DIR}/CurrentDate.cmake) include(${MYX_CMAKE_LIB_DIR}/ColoredMessages.cmake) include(${MYX_CMAKE_LIB_DIR}/NinjaGeneratorWarning.cmake) include(${MYX_CMAKE_LIB_DIR}/DirectoriesGuards.cmake) @@ -31,6 +33,9 @@ include(${MYX_CMAKE_LIB_DIR}/Qt5TargetSetup.cmake) include(${MYX_CMAKE_LIB_DIR}/Uncrustify.cmake) +include(${MYX_CMAKE_LIB_DIR}/generators/GitInfoHeader.cmake) +include(${MYX_CMAKE_LIB_DIR}/generators/PrivateConfigHeader.cmake) + unset(MYX_CMAKE_SOURCE_DIR) unset(MYX_CMAKE_BACKPORTS_DIR) unset(MYX_CMAKE_LIB_DIR) diff --git a/cmake/myx/MyxCMakeConfigVersion.cmake b/cmake/myx/MyxCMakeConfigVersion.cmake index 49f1e67..5ae5153 100644 --- a/cmake/myx/MyxCMakeConfigVersion.cmake +++ b/cmake/myx/MyxCMakeConfigVersion.cmake @@ -1,4 +1,4 @@ -set(MYX_CMAKE_PACKAGE_VERSION "1.99.64") +set(MYX_CMAKE_PACKAGE_VERSION "1.99.75") if(MYX_CMAKE_PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() diff --git a/cmake/myx/lib/AddLibrary.cmake b/cmake/myx/lib/AddLibrary.cmake index 1596676..df0c197 100644 --- a/cmake/myx/lib/AddLibrary.cmake +++ b/cmake/myx/lib/AddLibrary.cmake @@ -19,6 +19,8 @@ myx_add_library include_guard(GLOBAL) +# Переменная `CMAKE_CURRENT_FUNCTION_LIST_DIR` позволяет определить +# каталог файла. if(${CMAKE_VERSION} VERSION_LESS "3.17.0") set(CMAKE_CURRENT_FUNCTION_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}) endif() @@ -161,17 +163,17 @@ function(myx_add_library NAME TYPE) ) # Формирование файла для pkg-config - file(WRITE "${CMAKE_BINARY_DIR}/${NAME}.pc" + file(WRITE "${PROJECT_BINARY_DIR}/${NAME}.pc" "prefix=${CMAKE_INSTALL_PREFIX}\n" "exec_prefix=${CMAKE_INSTALL_PREFIX}\n" "includedir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n") if(NOT TYPE STREQUAL "INTERFACE") - file(APPEND "${CMAKE_BINARY_DIR}/${NAME}.pc" + file(APPEND "${PROJECT_BINARY_DIR}/${NAME}.pc" "libdir=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\n") endif() - file(APPEND "${CMAKE_BINARY_DIR}/${NAME}.pc" + file(APPEND "${PROJECT_BINARY_DIR}/${NAME}.pc" "\n" "Name: ${NAME}\n" "Description: ${NAME} library\n" @@ -181,13 +183,13 @@ function(myx_add_library NAME TYPE) "Cflags: -I${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\n") if(NOT TYPE STREQUAL "INTERFACE") - file(APPEND "${CMAKE_BINARY_DIR}/${NAME}.pc" + file(APPEND "${PROJECT_BINARY_DIR}/${NAME}.pc" "Libs: -L${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} -l${NAME}\n") endif() # Установка файла для pkg-config install( - FILES "${CMAKE_BINARY_DIR}/${NAME}.pc" + FILES "${PROJECT_BINARY_DIR}/${NAME}.pc" COMPONENT dev DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") diff --git a/cmake/myx/lib/CurrentDate.cmake b/cmake/myx/lib/CurrentDate.cmake new file mode 100644 index 0000000..b48038a --- /dev/null +++ b/cmake/myx/lib/CurrentDate.cmake @@ -0,0 +1,19 @@ +include_guard(GLOBAL) + +if(NOT MYX_TODAY) + if(WIN32) + execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE MYX_TODAY) + else() + execute_process(COMMAND "date" "+%d/%m/%Y" OUTPUT_VARIABLE MYX_TODAY) + endif() + string(REGEX REPLACE "(..)/(..)/(....).*" "\\3-\\2-\\1" MYX_TODAY ${MYX_TODAY}) +endif() + +if(NOT MYX_YEAR) + if(WIN32) + execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE MYX_YEAR) + else() + execute_process(COMMAND "date" "+%d/%m/%Y" OUTPUT_VARIABLE MYX_YEAR) + endif() + string(REGEX REPLACE "(..)/(..)/(....).*" "\\3" MYX_YEAR ${MYX_YEAR}) +endif() diff --git a/cmake/myx/lib/DirectoriesGuards.cmake b/cmake/myx/lib/DirectoriesGuards.cmake index 459cfbe..ce679be 100644 --- a/cmake/myx/lib/DirectoriesGuards.cmake +++ b/cmake/myx/lib/DirectoriesGuards.cmake @@ -17,32 +17,32 @@ get_filename_component(project_binary_dir "${PROJECT_BINARY_DIR}" REALPATH) get_filename_component(cmake_install_prefix "${CMAKE_INSTALL_PREFIX}" REALPATH) if(cmake_install_prefix STREQUAL cmake_binary_dir) - myx_message_error( + myx_message_fatal_error( "Myx: Cannot install into build directory ${CMAKE_INSTALL_PREFIX}.") endif() if(cmake_install_prefix STREQUAL cmake_source_dir) - myx_message_error( + myx_message_fatal_error( "Myx: Cannot install into source directory ${CMAKE_INSTALL_PREFIX}.") endif() if(cmake_install_prefix STREQUAL project_binary_dir) - myx_message_error( + myx_message_fatal_error( "Myx: Cannot install into build directory ${CMAKE_INSTALL_PREFIX}.") endif() if(cmake_install_prefix STREQUAL project_source_dir) - myx_message_error( + myx_message_fatal_error( "Myx: Cannot install into source directory ${CMAKE_INSTALL_PREFIX}.") endif() if(cmake_binary_dir STREQUAL cmake_source_dir) - myx_message_error( + myx_message_fatal_error( "Myx: Cannot build in source directory ${CMAKE_SOURCE_DIR}") endif() if(project_binary_dir STREQUAL project_source_dir) - myx_message_error( + myx_message_fatal_error( "Myx: Cannot build in source directory ${CMAKE_SOURCE_DIR}") endif() diff --git a/cmake/myx/lib/FetchContentAdd.cmake b/cmake/myx/lib/FetchContentAdd.cmake index 6da7051..1b40ac2 100644 --- a/cmake/myx/lib/FetchContentAdd.cmake +++ b/cmake/myx/lib/FetchContentAdd.cmake @@ -1,5 +1,29 @@ +#[=======================================================================[.rst: +FetchContent_Add +---------------- + +Вспомогательная функция для `FetchContent_Declare()`:: + + FetchContent_Add(NAME + [ GIT_REPOSITORY repo ] | + [ GIT_REMOTE remote ] | + [ GIT_PATH path ]) + +Обязательные параметры: `NAME` - идентификатор загружаемого ресурса. +Параметр `GIT_REPOSITORY` определяет имя репозитория по умолчанию. +Если указана пара параметров `GIT_REMOTE` и `GIT_PATH` и у git-репозитория +основного проекта указан удалённый репозиторий с именем, определяемым +переменной `GIT_REMOTE`, то адрес репозитория для получения проекта +изменяется. В этом случае загрузка будет производиться с сервера, +определяемого из адреса с меткой `GIT_REMOTE`, и по пути `GIT_PATH`. + +#]=======================================================================] + include_guard(GLOBAL) +# Обязательно в глобальной области +find_package(Git) + function(FetchContent_Add NAME) set(options "") set(oneValueArgs GIT_REPOSITORY GIT_REMOTE GIT_PATH) @@ -7,7 +31,6 @@ function(FetchContent_Add NAME) 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) diff --git a/cmake/myx/lib/Qt5TargetSetup.cmake b/cmake/myx/lib/Qt5TargetSetup.cmake index 60358fa..a0923b4 100644 --- a/cmake/myx/lib/Qt5TargetSetup.cmake +++ b/cmake/myx/lib/Qt5TargetSetup.cmake @@ -9,25 +9,24 @@ function(myx_qt5_target_setup NAME) get_target_property(type ${NAME} TYPE) - if(ARG_SOURCES OR ARG_CPP OR ARG_HPP OR ARG_MOD) - myx_message_fatal_error("MyxCMake: prohibited use") - endif() - - if(ARG_COMPONENTS) - find_package(Qt5 COMPONENTS ${ARG_COMPONENTS} REQUIRED) - foreach(iter ${ARG_COMPONENTS}) + foreach(iter ${ARG_COMPONENTS}) + if(type STREQUAL "INTERFACE_LIBRARY") + target_include_directories(${NAME} INTERFACE ${Qt5${iter}_INCLUDE_DIRS}) + else() target_include_directories(${NAME} PRIVATE ${Qt5${iter}_INCLUDE_DIRS}) - if(type STREQUAL "EXECUTABLE" AND NOT iter STREQUAL "LinguistTools") - target_link_libraries(${NAME} PRIVATE "Qt5::${iter}") - endif() - endforeach() - endif() + endif() + if(type STREQUAL "EXECUTABLE" AND NOT iter STREQUAL "LinguistTools") + target_link_libraries(${NAME} PRIVATE "Qt5::${iter}") + endif() + endforeach() - if(ARG_PRIVATE) - foreach(iter ${ARG_PRIVATE}) - find_package("Qt5${iter}" COMPONENTS Private REQUIRED) - endforeach() - endif() + foreach(iter ${ARG_PRIVATE}) + if(type STREQUAL "INTERFACE_LIBRARY") + target_include_directories(${NAME} INTERFACE ${Qt5${iter}_PRIVATE_INCLUDE_DIRS}) + else() + target_include_directories(${NAME} PRIVATE ${Qt5${iter}_PRIVATE_INCLUDE_DIRS}) + endif() + endforeach() if(type STREQUAL "EXECUTABLE") target_compile_options(${NAME} PRIVATE ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}) @@ -35,10 +34,12 @@ function(myx_qt5_target_setup NAME) if(ARG_PUBLIC_MOC) set_property(TARGET ${NAME} APPEND PROPERTY PUBLIC_HEADER_FILES "${ARG_PUBLIC_MOC}") + set_property(TARGET ${NAME} APPEND PROPERTY TR_FILES ${ARG_PUBLIC_MOC}) endif() if(ARG_PRIVATE_MOC) - set_property(TARGET ${NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PRIVATE_MOC}") + set_property(TARGET ${NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PRIVATE_MOC}") + set_property(TARGET ${NAME} APPEND PROPERTY TR_FILES ${ARG_PRIVATE_MOC}) endif() if(ARG_PUBLIC_MOC OR ARG_PRIVATE_MOC) @@ -51,19 +52,35 @@ function(myx_qt5_target_setup NAME) if(ARG_UI AND "Widgets" IN_LIST ARG_COMPONENTS) qt5_wrap_ui(ui_h ${ARG_UI}) + set_property(TARGET ${NAME} APPEND PROPERTY TR_FILES ${ARG_UI}) + # TODO + target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_BINARY_DIR}) endif() - if("LinguistTools" IN_LIST ARG_COMPONENTS) + # Перечень файлов, подлежащих переводу + get_target_property(tr ${NAME} TR_FILES) + # Формирование файла ресурсов с переводами + if("LinguistTools" IN_LIST ARG_COMPONENTS AND tr) + # Заглавие файла ресурсов + file(WRITE ${PROJECT_BINARY_DIR}/${NAME}_l10n.qrc "\n") + # Для каждого языка, указанное в параметре LANGS foreach(iter ${ARG_LANGS}) - qt5_create_translation(qm - "${PROJECT_SOURCE_DIR}/include" - "${PROJECT_SOURCE_DIR}/src" - "${PROJECT_SOURCE_DIR}/l10n/${NAME}_${iter}.ts") + # Создание или обновление файла переводов в каталоге ${PROJECT_SOURCE_DIR}/l10n + # и его компиляция в каталог ${PROJECT_BINARY_DIR} + qt5_create_translation(qm ${tr} "${PROJECT_SOURCE_DIR}/l10n/${NAME}_${iter}.ts") + # Добавление записи для скомпилированного файла переводов в ресурсный файл + file(APPEND ${PROJECT_BINARY_DIR}/${NAME}_l10n.qrc + "${NAME}_${iter}.qm\n") + # Добавление скомпилированного файла переводов к списку зависимостей для цели target_sources(${NAME} PRIVATE ${qm}) endforeach() - unset(qm) + # Окончение файла ресурсов + file(APPEND ${PROJECT_BINARY_DIR}/${NAME}_l10n.qrc "\n") + # Комплияция файла ресурсов с переводами + qt5_add_resources(qrc_l10n ${PROJECT_BINARY_DIR}/${NAME}_l10n.qrc) + target_sources(${NAME} PRIVATE ${qrc_l10n}) endif() - + unset(tr) target_sources(${NAME} PRIVATE ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC} ${moc_cpp} ${ui_h} ${qrc_cpp}) # Установка публичных заголовочных файлов diff --git a/cmake/myx/lib/TargetSetup.cmake b/cmake/myx/lib/TargetSetup.cmake index 8320209..fbc9a90 100644 --- a/cmake/myx/lib/TargetSetup.cmake +++ b/cmake/myx/lib/TargetSetup.cmake @@ -3,8 +3,8 @@ include_guard(GLOBAL) function(myx_target_setup NAME) set(options) set(oneValueArgs PCH) - set(multiValueArgs COMPILE_DEFINITIONS FIND_PACKAGES LINK_LIBRARIES - CPP PUBLIC_HEADERS PRIVATE_HEADERS SOURCES) + set(multiValueArgs COMPILE_DEFINITIONS PACKAGES LINK_LIBRARIES + CPP INTERFACE_HEADERS PUBLIC_HEADERS PRIVATE_HEADERS) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -14,31 +14,29 @@ function(myx_target_setup NAME) get_target_property(type ${NAME} TYPE) - foreach(iter ${ARG_FIND_PACKAGES}) - find_package(${iter} REQUIRED) + foreach(iter ${ARG_PACKAGES}) target_include_directories(${NAME} PRIVATE ${${iter}_INCLUDE_DIRS}) target_compile_definitions(${NAME} PRIVATE ${${iter}_COMPILE_DEFINITIONS}) endforeach() target_compile_definitions(${NAME} PRIVATE ${ARG_COMPILE_DEFINITIONS}) - if(ARG_SOURCES) - myx_message_fatal_error("MyxCMake: Use of SOURCES argument") - endif() - if(ARG_CPP) set_property(TARGET ${NAME} APPEND PROPERTY CPP_FILES ${ARG_CPP}) + set_property(TARGET ${NAME} APPEND PROPERTY TR_FILES ${ARG_CPP}) endif() if(ARG_PUBLIC_HEADERS) set_property(TARGET ${NAME} APPEND PROPERTY PUBLIC_HEADER_FILES "${ARG_PUBLIC_HEADERS}") + set_property(TARGET ${NAME} APPEND PROPERTY TR_FILES ${ARG_PUBLIC_HEADERS}) endif() - if(ARG_PUBLIC_HEADERS) + if(ARG_PRIVATE_HEADERS) set_property(TARGET ${NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PRIVATE_HEADERS}") + set_property(TARGET ${NAME} APPEND PROPERTY TR_FILES ${ARG_PRIVATE_HEADERS}) endif() if(ARG_PCH) - if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.16) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.16 AND PROJECT_IS_TOP_LEVEL OR MYX_USE_LOCAL_DIRECTORIES) target_precompile_headers(${NAME} PRIVATE ${ARG_PCH}) else() target_compile_options(${NAME} PRIVATE -include ${ARG_PCH}) @@ -46,15 +44,21 @@ function(myx_target_setup NAME) set_property(TARGET ${NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PCH}") endif() - target_include_directories(${PROJECT_NAME} PRIVATE - $) - - if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/src") - target_include_directories(${PROJECT_NAME} PRIVATE - $) + if(NOT IS_DIRECTORY "${PROJECT_BINARY_DIR}/include") + file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/include") endif() - if(type STREQUAL EXECUTABLE) + if(NOT type STREQUAL "INTERFACE_LIBRARY") + target_include_directories(${PROJECT_NAME} PRIVATE + $) + + if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/src") + target_include_directories(${PROJECT_NAME} PRIVATE + $) + endif() + endif() + + if(type STREQUAL "EXECUTABLE") if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/include") target_include_directories(${PROJECT_NAME} PRIVATE $) @@ -70,6 +74,7 @@ function(myx_target_setup NAME) install(TARGETS ${NAME} COMPONENT main RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() + target_sources(${NAME} PUBLIC $) target_sources(${NAME} PUBLIC ${ARG_PUBLIC_HEADERS}) target_sources(${NAME} PRIVATE ${ARG_CPP} ${ARG_PCH} ${ARG_PRIVATE_HEADERS}) target_link_libraries(${NAME} PRIVATE ${ARG_LINK_LIBRARIES}) @@ -78,7 +83,7 @@ function(myx_target_setup NAME) # Установка публичных заголовочных файлов if(PROJECT_IS_TOP_LEVEL) install_relative(${PROJECT_SOURCE_DIR} - FILES ${ARG_PUBLIC_HEADERS} + FILES ${ARG_PUBLIC_HEADERS} ${ARG_INTERFACE_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT dev ) diff --git a/cmake/myx/lib/Uncrustify.cmake b/cmake/myx/lib/Uncrustify.cmake index d64ca55..620e38f 100644 --- a/cmake/myx/lib/Uncrustify.cmake +++ b/cmake/myx/lib/Uncrustify.cmake @@ -46,11 +46,9 @@ function(myx_uncrustify target) if(NOT ARG_CONFIG) set(ARG_CONFIG "${PROJECT_SOURCE_DIR}/.uncrustify.cfg") - endif() - - if(NOT UNCRUSTIFY_EXE) - myx_message_notify("MyxCMake: uncrustify executable is not found") - return() + if(NOT EXISTS ${ARG_CONFIG}) + set(ARG_CONFIG "${CMAKE_SOURCE_DIR}/.uncrustify.cfg") + endif() endif() if(NOT EXISTS ${ARG_CONFIG}) @@ -58,6 +56,11 @@ function(myx_uncrustify target) return() endif() + if(NOT UNCRUSTIFY_EXE) + myx_message_notify("MyxCMake: uncrustify executable is not found") + return() + endif() + if(NOT TARGET myx-uncrustify) add_custom_target(myx-uncrustify) endif() @@ -72,6 +75,7 @@ function(myx_uncrustify target) list(FILTER __sources EXCLUDE REGEX "qrc_.*\\.cpp$") list(FILTER __sources EXCLUDE REGEX "moc_.*\\.cpp$") list(FILTER __sources EXCLUDE REGEX "ui_.*\\.h$") + list(FILTER __sources EXCLUDE REGEX ".*\\.qm$") add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/uncrustify-${target}.cfg COMMAND ${UNCRUSTIFY_EXE} --update-config-with-doc diff --git a/cmake/myx/lib/generators/GitInfoHeader.cmake b/cmake/myx/lib/generators/GitInfoHeader.cmake new file mode 100644 index 0000000..52263c4 --- /dev/null +++ b/cmake/myx/lib/generators/GitInfoHeader.cmake @@ -0,0 +1,107 @@ +#[=======================================================================[.rst: +myx_generate_git_info_header +---------------------------------- + +Вспомогательная функция для автоматической генерации заголовочного +файла, содержащего информацию о текущем состоянии репозитория git:: + + myx_generate_git_info_header(TARGET BASE_FILENAME + [ PREFIX prefix ] ) + +Обязательные параметры: `TARGET` - имя цели, с которой связан заголовочный файл, +и `BASE_FILENAME` - имя генерируемого заголовочного файла. Дополнительный аргумент +`PREFIX` добавляет префикс к генерируемым именам переменных. + +#]=======================================================================] + +include_guard(GLOBAL) + +function(myx_generate_git_info_header target base_filename) + set(options) + set(oneValueArgs PREFIX) + set(multiValueArgs) + + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(ARG_PREFIX) + string(APPEND ARG_PREFIX "_") + endif() + + set(filename "${PROJECT_BINARY_DIR}/include/${base_filename}") + + set(git_info_hpp_in +"#pragma once + +#if defined (@ARG_PREFIX@GIT_REV) +#error \"Duplicate definition of macros @ARG_PREFIX@GIT_REV\" +#else +#define @ARG_PREFIX@GIT_REV \"@GIT_REV@\" +#endif + +#if defined (@ARG_PREFIX@GIT_DIFF) +#error \"Duplicate definition of macros @ARG_PREFIX@GIT_DIFF\" +#else +#define @ARG_PREFIX@GIT_DIFF \"@GIT_DIFF@\" +#endif + +#if defined (@ARG_PREFIX@GIT_BRANCH) +#error \"Duplicate definition of macros @ARG_PREFIX@GIT_BRANCH\" +#else +#define @ARG_PREFIX@GIT_BRANCH \"@GIT_BRANCH@\" +#endif + +#if defined (@ARG_PREFIX@GIT_TAG) +#error \"Duplicate definition of macros @ARG_PREFIX@GIT_TAG\" +#else +#define @ARG_PREFIX@GIT_TAG \"@GIT_TAG@\" +#endif +") + + set(git_info_hpp_in_path ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/myx_git_info_p.hpp.in) + file(WRITE ${git_info_hpp_in_path} ${git_info_hpp_in}) + + set(git_info_cmake_in +"set(ARG_PREFIX ${ARG_PREFIX}) +set(GIT_REV \"N/A\") +set(GIT_DIFF \"\") +set(GIT_TAG \"N/A\") +set(GIT_BRANCH \"N/A\") + +find_package(Git) + +if(GIT_EXECUTABLE) + execute_process(COMMAND ${GIT_EXECUTABLE} log --pretty=format:'%h' -n 1 OUTPUT_VARIABLE GIT_REV ERROR_QUIET) + + # Check whether we got any revision (which isn't always the case, + # e.g. when someone downloaded a zip file from Github instead of a checkout) + if(NOT \"\${GIT_REV}\" STREQUAL \"\") + execute_process(COMMAND bash -c \"${GIT_EXECUTABLE} diff --quiet --exit-code || echo +\" OUTPUT_VARIABLE GIT_DIFF) + execute_process(COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags OUTPUT_VARIABLE GIT_TAG ERROR_QUIET) + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD OUTPUT_VARIABLE GIT_BRANCH) + + string(STRIP \"\${GIT_REV}\" GIT_REV) + string(SUBSTRING \"\${GIT_REV}\" 1 7 GIT_REV) + string(STRIP \"\${GIT_DIFF}\" GIT_DIFF) + string(STRIP \"\${GIT_TAG}\" GIT_TAG) + string(STRIP \"\${GIT_BRANCH}\" GIT_BRANCH) + endif() +endif() + +configure_file(${git_info_hpp_in_path} \"\${GIT_INFO_FILE}\") +") + set(git_info_cmake_in_path "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${target}-git-info.cmake.in") + file(WRITE ${git_info_cmake_in_path} ${git_info_cmake_in}) + +# cmake-format: off + if(NOT TARGET ${target}-git-info-header) + add_custom_target(${target}-git-info-header ALL + ${CMAKE_COMMAND} -DGIT_INFO_FILE=${filename} -P ${git_info_cmake_in_path} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() +# cmake-format: on + + file(WRITE ${filename} "") + + set_property(TARGET ${target} APPEND PROPERTY PRIVATE_HEADER_FILES ${filename}) + target_sources(${target} PRIVATE ${filename}) +endfunction() diff --git a/cmake/myx/lib/generators/PrivateConfigHeader.cmake b/cmake/myx/lib/generators/PrivateConfigHeader.cmake new file mode 100644 index 0000000..2d1331b --- /dev/null +++ b/cmake/myx/lib/generators/PrivateConfigHeader.cmake @@ -0,0 +1,45 @@ +#[=======================================================================[.rst: +myx_generate_private_config_header +---------------------------------- + +Вспомогательная функция для автоматической генерации заголовочного +файла, содержащего информацию о проекте:: + + myx_generate_private_config_header(TARGET BASE_FILENAME) + +Обязательные параметры: `TARGET` - имя цели, с которой связан заголовочный файл, +и `BASE_FILENAME` - имя генерируемого заголовочного файла. + +#]=======================================================================] + +include_guard(GLOBAL) + +function(myx_generate_private_config_header target base_filename) + set(BUILD_DATE ${MYX_TODAY}) + myx_project_version_int() + get_property(PROJECT_VERSION_INT GLOBAL PROPERTY PROJECT_VERSION_INT) + + set(filename "${PROJECT_BINARY_DIR}/include/${base_filename}") + + set(private_config_hpp_in +"#pragma once + +#define PROJECT_VERSION_STR \"@PROJECT_VERSION@\" +#define PROJECT_VERSION_INT @PROJECT_VERSION_INT@ + +#cmakedefine PROJECT_NAME \"@PROJECT_NAME@\" +#cmakedefine AUTHOR_NAME \"@AUTHOR_NAME@\" +#cmakedefine AUTHOR_EMAIL \"@AUTHOR_EMAIL@\" +#cmakedefine DESCRIPTION \"@PROJECT_DESCRIPTION@\" +#cmakedefine BUILD_TYPE \"@CMAKE_BUILD_TYPE@\" +#cmakedefine BUILD_DATE \"@MYX_TODAY@\" +") + + set(private_config_hpp_in_path "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${target}_config_p.hpp.in") + file(WRITE ${private_config_hpp_in_path} ${private_config_hpp_in}) + + configure_file(${private_config_hpp_in_path} ${filename}) + + set_property(TARGET ${target} APPEND PROPERTY PRIVATE_HEADER_FILES ${filename}) + target_sources(${target} PRIVATE ${filename}) +endfunction() diff --git a/cmake/myx/lib/macro/FindPackages.cmake b/cmake/myx/lib/macro/FindPackages.cmake new file mode 100644 index 0000000..9727195 --- /dev/null +++ b/cmake/myx/lib/macro/FindPackages.cmake @@ -0,0 +1,35 @@ +include_guard(GLOBAL) + +macro(myx_find_packages) + set(options) + set(oneValueArgs) + set(multiValueArgs PACKAGES Boost Qt5 Qt5Private) + + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + foreach(iter ${ARG_PACKAGES}) + find_package(${iter} REQUIRED) + endforeach() + + if(ARG_Boost) + find_package(Boost COMPONENTS ${ARG_Boost} REQUIRED) + endif() + + if(ARG_Qt5) + find_package(Qt5 COMPONENTS ${ARG_Qt5} REQUIRED) + endif() + + if(ARG_Qt5Private) + foreach(iter ${ARG_Qt5Private}) + find_package("Qt5${iter}" COMPONENTS Private REQUIRED) + endforeach() + endif() + + foreach(iter IN LISTS oneValueArgs multiValueArgs) + unset(ARG_${iter}) + endforeach() + unset(ARG_UNPARSED_ARGUMENTS) + unset(multiValueArgs) + unset(oneValueArgs) + unset(options) +endmacro(myx_find_packages) diff --git a/cmake/myx_setup.cmake b/cmake/myx_setup.cmake index 27c5292..984fff9 100644 --- a/cmake/myx_setup.cmake +++ b/cmake/myx_setup.cmake @@ -16,11 +16,11 @@ if(MYX_CMAKE_DIR) set(ENV{MYX_CMAKE_DIR} ${MYX_CMAKE_DIR}) endif() if(DEFINED ENV{MYX_CMAKE_DIR}) - find_package(MyxCMake 1.99.50 CONFIG PATHS $ENV{MYX_CMAKE_DIR} NO_DEFAULT_PATH REQUIRED) + find_package(MyxCMake 1.99.75 CONFIG PATHS $ENV{MYX_CMAKE_DIR} NO_DEFAULT_PATH REQUIRED) myx_message_notice("=== MyxCMake directory: ${MyxCMake_CONFIG} ===") else() if(MYX_CMAKE_USE_SYSTEM) - find_package(MyxCMake 1.99.50 REQUIRED) + find_package(MyxCMake 1.99.75 REQUIRED) myx_message_notice("=== MyxCMake directory: ${MyxCMake_CONFIG} ===") else() include(${PROJECT_SOURCE_DIR}/cmake/myx/MyxCMakeConfig.cmake)