From 3de4031f4658008cc1fb3171c28c933b9d7a3fe2 Mon Sep 17 00:00:00 2001 From: Andrei Astafev Date: Wed, 2 Aug 2023 12:07:01 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20MyxCMake?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmake/myx/MyxCMakeConfig.cmake | 6 +- cmake/myx/MyxCMakeConfigVersion.cmake | 2 +- cmake/myx/lib/AddExternalTarget.cmake | 79 ---------- cmake/myx/lib/DownloadContent.cmake | 77 ++++++++++ cmake/myx/lib/FetchContentAdd.cmake | 56 ------- cmake/myx/lib/TargetSetupQt.cmake | 153 +++++++++++++++++++ cmake/myx/lib/doc/Doxygen.cmake | 2 +- cmake/myx/lib/generators/GitInfo.cmake | 2 +- cmake/myx/lib/macro/FindQt.cmake | 40 +++++ cmake/myx/lib/macro/QtTargetSetup.cmake | 176 ---------------------- cmake/myx/lib/uncrustify/Uncrustify.cmake | 10 +- cmake/myx_setup.cmake | 4 +- 12 files changed, 284 insertions(+), 323 deletions(-) delete mode 100644 cmake/myx/lib/AddExternalTarget.cmake create mode 100644 cmake/myx/lib/DownloadContent.cmake delete mode 100644 cmake/myx/lib/FetchContentAdd.cmake create mode 100644 cmake/myx/lib/TargetSetupQt.cmake create mode 100644 cmake/myx/lib/macro/FindQt.cmake delete mode 100644 cmake/myx/lib/macro/QtTargetSetup.cmake diff --git a/cmake/myx/MyxCMakeConfig.cmake b/cmake/myx/MyxCMakeConfig.cmake index e4ada74..6c04f4f 100644 --- a/cmake/myx/MyxCMakeConfig.cmake +++ b/cmake/myx/MyxCMakeConfig.cmake @@ -38,6 +38,7 @@ include(CMakeDependentOption) # Полезные макросы include(${MYX_CMAKE_LIB_DIR}/macro/CreateSymlink.cmake) include(${MYX_CMAKE_LIB_DIR}/macro/FindPackages.cmake) +include(${MYX_CMAKE_LIB_DIR}/macro/FindQt.cmake) include(${MYX_CMAKE_LIB_DIR}/macro/InstallRelative.cmake) include(${MYX_CMAKE_LIB_DIR}/macro/CheckEnableCxxCompilerFlag.cmake) include(${MYX_CMAKE_LIB_DIR}/macro/GTest.cmake) @@ -50,8 +51,7 @@ 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}/AddExternalTarget.cmake) -include(${MYX_CMAKE_LIB_DIR}/FetchContentAdd.cmake) +include(${MYX_CMAKE_LIB_DIR}/DownloadContent.cmake) set(MYX_CMAKE_TOOLCHAINS_DIR "${MYX_CMAKE_LIB_DIR}/toolchains") include(${MYX_CMAKE_LIB_DIR}/Toolchains.cmake) @@ -61,7 +61,7 @@ include(${MYX_CMAKE_LIB_DIR}/AddExecutable.cmake) include(${MYX_CMAKE_LIB_DIR}/AddInterfaceLibrary.cmake) include(${MYX_CMAKE_LIB_DIR}/AddObjectLibrary.cmake) include(${MYX_CMAKE_LIB_DIR}/TargetSetup.cmake) -include(${MYX_CMAKE_LIB_DIR}/macro/QtTargetSetup.cmake) +include(${MYX_CMAKE_LIB_DIR}/TargetSetupQt.cmake) include(${MYX_CMAKE_LIB_DIR}/uncrustify/Uncrustify.cmake) include(${MYX_CMAKE_LIB_DIR}/doc/Doxygen.cmake) diff --git a/cmake/myx/MyxCMakeConfigVersion.cmake b/cmake/myx/MyxCMakeConfigVersion.cmake index 5eee7a2..e2f97a5 100644 --- a/cmake/myx/MyxCMakeConfigVersion.cmake +++ b/cmake/myx/MyxCMakeConfigVersion.cmake @@ -1,4 +1,4 @@ -set(MYX_CMAKE_PACKAGE_VERSION "2.4.2") +set(MYX_CMAKE_PACKAGE_VERSION "2.4.10") if(MYX_CMAKE_PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() diff --git a/cmake/myx/lib/AddExternalTarget.cmake b/cmake/myx/lib/AddExternalTarget.cmake deleted file mode 100644 index b1f562b..0000000 --- a/cmake/myx/lib/AddExternalTarget.cmake +++ /dev/null @@ -1,79 +0,0 @@ -#[=======================================================================[.rst: -myx_add_external_target ------------------------ - -Функция для подключения целей из внешних проектов:: - - myx_add_external_target(TARGET_NAME - [ MODULES_PATH modules_path ] | - [ GIT_REPOSITORY url ] | - [ GIT_TAG tag ] | - [ LOCAL_PATH local_path ] ) - -Обязательный параметр: `TARGET_NAME` - имя цели, содержащейся во внешнем проекте. -Параметр `MODULES_PATH` содержит имя каталога, в который будут загружаться -внешние проекты (по умолчанию `modules`). Параметр `GIT_REPOSITORY` содержит -адрес внешнего проекта, который нужно загрузить с помощью git. Параметр `GIT_TAG` -содержит используемые метку, идентификатор коммита или ветку в репозитории. -Параметр `LOCAL_PATH` используется для указания пути к подкаталогу, находящемуся -вне текущего проекта. Его следует указывать только при вызове функции из -вспомогательного файла `external_targets.cmake`. - -#]=======================================================================] - - -find_package(Git) - -function(myx_add_external_target TARGET_NAME) - set(options) - set(oneValueArgs) - set(multiValueArgs MODULES_PATH GIT_REPOSITORY GIT_TAG LOCAL_PATH) - cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(TARGET ${TARGET_NAME}) - return() - endif() - - if(ARG_LOCAL_PATH) - myx_message_notice("Using directory ${ARG_LOCAL_PATH} to build target ${TARGET_NAME}") - add_subdirectory(${ARG_LOCAL_PATH} ${CMAKE_BINARY_DIR}/${TARGET_NAME} EXCLUDE_FROM_ALL) - return() - endif() - - if(NOT ARG_MODULES_PATH) - set(ARG_MODULES_PATH modules) - endif() - - if(CMAKE_SCRIPT_MODE_FILE) - set(PROJECT_SOURCE_DIR ${CMAKE_SOURCE_DIR}) - endif() - set(ARG_MODULES_PATH ${PROJECT_SOURCE_DIR}/${ARG_MODULES_PATH}) - - if(NOT IS_DIRECTORY ${ARG_MODULES_PATH}) - execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ARG_MODULES_PATH}) - endif() - - if(GIT_EXECUTABLE) - if(NOT IS_DIRECTORY ${ARG_MODULES_PATH}/${TARGET_NAME}) - execute_process(COMMAND ${GIT_EXECUTABLE} clone ${ARG_GIT_REPOSITORY} ${TARGET_NAME} - WORKING_DIRECTORY ${ARG_MODULES_PATH}) - else() - execute_process(COMMAND ${GIT_EXECUTABLE} fetch - WORKING_DIRECTORY ${ARG_MODULES_PATH}/${TARGET_NAME}) - endif() - execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${ARG_GIT_TAG} - WORKING_DIRECTORY ${ARG_MODULES_PATH}/${TARGET_NAME}) - endif() - - if(NOT CMAKE_SCRIPT_MODE_FILE) - add_subdirectory(${ARG_MODULES_PATH}/${TARGET_NAME} EXCLUDE_FROM_ALL) - endif() - - if(NOT TARGET ${TARGET_NAME}) - myx_message_fatal_error("Target ${TARGET_NAME} is not found.") - endif() - -endfunction(myx_add_external_target) - -include("${PROJECT_SOURCE_DIR}/external_targets.cmake" OPTIONAL) - diff --git a/cmake/myx/lib/DownloadContent.cmake b/cmake/myx/lib/DownloadContent.cmake new file mode 100644 index 0000000..aecca67 --- /dev/null +++ b/cmake/myx/lib/DownloadContent.cmake @@ -0,0 +1,77 @@ +#[=======================================================================[.rst: +myx_download_content +----------------------- + +Функция для загрузки дополнительных репозиториев:: + + myx_download_content(NAME + [ DOWNLOAD_DIR dir ] | + [ GIT_REPOSITORY url ] | + [ GIT_TAG tag ] ) + +Обязательный параметр: `NAME` - имя целевого каталога. +Параметр `DOWNLOAD_DIR` содержит имя каталога, в который будет загружаться +содержимое (по умолчанию `downloads`). +Параметр `GIT_REPOSITORY` содержит адрес внешнего проекта, который нужно +загрузить с помощью git. +Параметр `GIT_TAG` содержит используемые метку, идентификатор коммита или +ветку в загружаемом репозитории. + +#]=======================================================================] + +find_package(Git QUIET) + +option(ENABLE_DOWNLOAD_CONTENT "Enable download content" ON) + +function(myx_download_content NAME) + set(options) + set(oneValueArgs) + set(multiValueArgs DOWNLOAD_DIR GIT_REPOSITORY GIT_TAG) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT CMAKE_SCRIPT_MODE_FILE) + if(TARGET myx-download-${NAME}) + return() + else() + add_custom_target(myx-download-${NAME}) + endif() + if(NOT TARGET myx-download-content) + add_custom_target(myx-download-content) + endif() + endif() + + if(NOT ARG_DOWNLOAD_DIR) + set(ARG_DOWNLOAD_DIR "_downloads") + endif() + + if(CMAKE_SCRIPT_MODE_FILE) + set(PROJECT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) + endif() + set(ARG_DOWNLOAD_DIR ${PROJECT_SOURCE_DIR}/${ARG_DOWNLOAD_DIR}) + + if(NOT IS_DIRECTORY ${ARG_DOWNLOAD_DIR}) + execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ARG_DOWNLOAD_DIR}) + endif() + + if(ENABLE_DOWNLOAD_CONTENT AND GIT_EXECUTABLE AND ARG_GIT_REPOSITORY) + if(NOT IS_DIRECTORY ${ARG_DOWNLOAD_DIR}/${NAME}) + execute_process(COMMAND ${GIT_EXECUTABLE} clone ${ARG_GIT_REPOSITORY} ${NAME} + WORKING_DIRECTORY ${ARG_DOWNLOAD_DIR}) + else() + execute_process(COMMAND ${GIT_EXECUTABLE} fetch + WORKING_DIRECTORY ${ARG_DOWNLOAD_DIR}/${NAME}) + endif() + if(ARG_GIT_TAG) + execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${ARG_GIT_TAG} + WORKING_DIRECTORY ${ARG_DOWNLOAD_DIR}/${NAME}) + else() + execute_process(COMMAND ${GIT_EXECUTABLE} pull + WORKING_DIRECTORY ${ARG_DOWNLOAD_DIR}/${NAME}) + endif() + endif() + + if(NOT CMAKE_SCRIPT_MODE_FILE) + add_subdirectory(${ARG_DOWNLOAD_DIR}/${NAME} EXCLUDE_FROM_ALL) + endif() +endfunction() + diff --git a/cmake/myx/lib/FetchContentAdd.cmake b/cmake/myx/lib/FetchContentAdd.cmake deleted file mode 100644 index 4202c92..0000000 --- a/cmake/myx/lib/FetchContentAdd.cmake +++ /dev/null @@ -1,56 +0,0 @@ -#[=======================================================================[.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 TARGET_NAME) - set(options "") - set(oneValueArgs GIT_REPOSITORY GIT_REMOTE GIT_PATH) - set(multiValueArgs "") - - cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - 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( - ${TARGET_NAME} - ${ARG_UNPARSED_ARGUMENTS} - GIT_REPOSITORY ${ARG_GIT_REPOSITORY} - GIT_SHALLOW 1 - ) - - set(FETCHCONTENT_QUIET off) - FetchContent_MakeAvailable(${TARGET_NAME}) -endfunction() diff --git a/cmake/myx/lib/TargetSetupQt.cmake b/cmake/myx/lib/TargetSetupQt.cmake new file mode 100644 index 0000000..d149fe2 --- /dev/null +++ b/cmake/myx/lib/TargetSetupQt.cmake @@ -0,0 +1,153 @@ +include_guard(GLOBAL) + +function(myx_target_setup_qt TARGET_NAME) + set(options) + set(oneValueArgs) + set(multiValueArgs COMPONENTS PRIVATE PUBLIC_MOC PRIVATE_MOC UI QRC LANGS) + + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(myx_qt_ver "5") + if(QT_DEFAULT_MAJOR_VERSION) + set(myx_qt_ver "${QT_DEFAULT_MAJOR_VERSION}") + endif() + + if(NOT (myx_qt_ver STREQUAL "5" OR myx_qt_ver STREQUAL "6")) + myx_message_fatal_error("Supported Qt versions are 5 and 6") + endif() + + get_target_property(__target_type ${TARGET_NAME} TYPE) + + foreach(iter ${ARG_COMPONENTS}) + if(__target_type STREQUAL "INTERFACE_LIBRARY") + target_include_directories(${TARGET_NAME} INTERFACE ${Qt5${iter}_INCLUDE_DIRS}) + else() + target_include_directories(${TARGET_NAME} PRIVATE ${Qt5${iter}_INCLUDE_DIRS}) + endif() + if(NOT iter STREQUAL "LinguistTools") + if(__target_type STREQUAL "EXECUTABLE") + target_link_libraries(${TARGET_NAME} PRIVATE Qt${myx_qt_ver}::${iter}) + endif() + if(__target_type STREQUAL "SHARED_LIBRARY") + target_link_libraries(${TARGET_NAME} PUBLIC Qt${myx_qt_ver}::${iter}) + endif() + if((${CMAKE_VERSION} VERSION_GREATER "3.8.0") AND (__target_type STREQUAL "OBJECT_LIBRARY")) + target_link_libraries(${TARGET_NAME} PUBLIC Qt${myx_qt_ver}::${iter}) + endif() + endif() + endforeach() + + foreach(iter ${ARG_PRIVATE}) + if(__target_type STREQUAL "INTERFACE_LIBRARY") + target_include_directories(${TARGET_NAME} INTERFACE ${Qt${myx_qt_ver}${iter}_PRIVATE_INCLUDE_DIRS}) + else() + target_include_directories(${TARGET_NAME} PRIVATE ${Qt${myx_qt_ver}${iter}_PRIVATE_INCLUDE_DIRS}) + endif() + endforeach() + + if(__target_type STREQUAL "EXECUTABLE") + target_compile_options(${TARGET_NAME} PRIVATE ${Qt${myx_qt_ver}Core_EXECUTABLE_COMPILE_FLAGS}) + endif() + + if(ARG_PUBLIC_MOC) + set_property(TARGET ${TARGET_NAME} APPEND PROPERTY PUBLIC_HEADER_FILES "${ARG_PUBLIC_MOC}") + set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_PUBLIC_MOC}) + endif() + + if(ARG_PRIVATE_MOC) + set_property(TARGET ${TARGET_NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PRIVATE_MOC}") + set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_PRIVATE_MOC}) + endif() + + if(ARG_PUBLIC_MOC OR ARG_PRIVATE_MOC) + if(myx_qt_ver EQUAL 5) + qt5_wrap_cpp(moc_cpp ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC}) + elseif(myx_qt_ver EQUAL 6) + qt6_wrap_cpp(moc_cpp ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC}) + endif() + endif() + + if(ARG_QRC) + if(myx_qt_ver EQUAL 5) + qt5_add_resources(qrc_cpp ${ARG_QRC}) + elseif(myx_qt_ver EQUAL 6) + qt6_add_resources(qrc_cpp ${ARG_QRC}) + endif() + endif() + + if(ARG_UI) + if(NOT COMMAND qt${myx_ver_qt}_wrap_ui) + message(WARNING "MyxCMake: Widgets is required to process UI") + else() + if(myx_qt_ver EQUAL 5) + qt5_wrap_ui(ui_h ${ARG_UI}) + elseif(myx_qt_ver EQUAL 6) + qt6_wrap_ui(ui_h ${ARG_UI}) + endif() + set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_UI}) + target_link_libraries(${TARGET_NAME} PRIVATE Qt${myx_qt_ver}::Widgets) + # TODO + target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_BINARY_DIR}) + endif() + endif() + + # Перечень файлов, подлежащих переводу + if(__target_type STREQUAL "INTERFACE_LIBRARY") + get_target_property(tr ${TARGET_NAME} INTERFACE_TR_FILES) + else() + get_target_property(tr ${TARGET_NAME} TR_FILES) + endif() + + # Формирование файла ресурсов с переводами + if(tr AND ARG_LANGS) + if(NOT COMMAND qt${myx_ver_qt}_create_translation) + message(WARNING "MyxCMake: LinguistTools is required to process LANGS") + else() + # Заглавие файла ресурсов + file(WRITE ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc "\n") + # Для каждого языка, указанное в параметре LANGS + foreach(iter ${ARG_LANGS}) + # Создание или обновление файла переводов в каталоге ${PROJECT_SOURCE_DIR}/l10n + # и его компиляция в каталог ${PROJECT_BINARY_DIR} + if(myx_qt_ver EQUAL 5) + qt5_create_translation(qm ${tr} + "${PROJECT_SOURCE_DIR}/l10n/${TARGET_NAME}_${iter}.ts" + OPTIONS -I ${PROJECT_SOURCE_DIR}/include -I ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}) + elseif(myx_qt_ver EQUAL 6) + qt6_create_translation(qm ${tr} + "${PROJECT_SOURCE_DIR}/l10n/${TARGET_NAME}_${iter}.ts" + OPTIONS -I ${PROJECT_SOURCE_DIR}/include -I ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}) + endif() + # Добавление записи для скомпилированного файла переводов в ресурсный файл + file(APPEND ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc + "${TARGET_NAME}_${iter}.qm\n") + # Добавление скомпилированного файла переводов к списку зависимостей для цели + target_sources(${TARGET_NAME} PRIVATE ${qm}) + endforeach() + # Окончание файла ресурсов + file(APPEND ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc "\n") + # Компиляция файла ресурсов с переводами + if(myx_qt_ver EQUAL 5) + qt5_add_resources(qrc_l10n ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc) + elseif(myx_qt_ver EQUAL 6) + qt6_add_resources(qrc_l10n ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc) + endif() + target_sources(${TARGET_NAME} PRIVATE ${qrc_l10n}) + endif() + endif() + unset(tr) + if(__target_type STREQUAL "INTERFACE_LIBRARY") + target_sources(${TARGET_NAME} INTERFACE ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC} ${moc_cpp} ${ui_h} ${qrc_cpp}) + else() + target_sources(${TARGET_NAME} PRIVATE ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC} ${moc_cpp} ${ui_h} ${qrc_cpp}) + endif() + + # Установка публичных заголовочных файлов + if(PROJECT_IS_TOP_LEVEL) + myx_install_relative(${PROJECT_SOURCE_DIR} + FILES ${ARG_PUBLIC_MOC} + DESTINATION ${CMAKE_INSTALL_PREFIX} + COMPONENT DEV + ) + endif() +endfunction() diff --git a/cmake/myx/lib/doc/Doxygen.cmake b/cmake/myx/lib/doc/Doxygen.cmake index 6cb2fe0..abc3072 100644 --- a/cmake/myx/lib/doc/Doxygen.cmake +++ b/cmake/myx/lib/doc/Doxygen.cmake @@ -2,7 +2,7 @@ if(${CMAKE_VERSION} VERSION_LESS "3.17.0") set(MYX_CMAKE_LIB_DOC_DIR_BACKPORT "${CMAKE_CURRENT_LIST_DIR}") endif() -find_package(Doxygen) +find_package(Doxygen QUIET) function(myx_doc_doxygen TARGET_NAME) if(${CMAKE_VERSION} VERSION_LESS "3.17.0") diff --git a/cmake/myx/lib/generators/GitInfo.cmake b/cmake/myx/lib/generators/GitInfo.cmake index 5b9f2a7..455ce91 100644 --- a/cmake/myx/lib/generators/GitInfo.cmake +++ b/cmake/myx/lib/generators/GitInfo.cmake @@ -7,7 +7,7 @@ set(GIT_DIFF "") set(GIT_TAG "N/A") set(GIT_BRANCH "N/A") -find_package(Git) +find_package(Git QUIET) if(GIT_EXECUTABLE) execute_process(COMMAND ${GIT_EXECUTABLE} log --pretty=format:'%h' -n 1 OUTPUT_VARIABLE GIT_REV ERROR_QUIET) diff --git a/cmake/myx/lib/macro/FindQt.cmake b/cmake/myx/lib/macro/FindQt.cmake new file mode 100644 index 0000000..27a5fb5 --- /dev/null +++ b/cmake/myx/lib/macro/FindQt.cmake @@ -0,0 +1,40 @@ +include_guard(GLOBAL) + +macro(myx_find_qt) + set(options REQUIRED) + set(oneValueArgs VERSION) + set(multiValueArgs COMPONENTS PRIVATE) + + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT ARG_VERSION) + set(ARG_VERSION "5") + if(QT_DEFAULT_MAJOR_VERSION) + set(ARG_VERSION "${QT_DEFAULT_MAJOR_VERSION}") + endif() + endif() + + if(ARG_REQUIRED) + set(ARG_REQUIRED "REQUIRED") + endif() + + if(NOT (ARG_VERSION STREQUAL "5" OR ARG_VERSION STREQUAL "6")) + message(FATAL_ERROR "Supported Qt versions are 5 and 6") + endif() + + foreach(iter ${ARG_COMPONENTS}) + find_package(Qt${ARG_VERSION} COMPONENTS ${iter} ${ARG_REQUIRED}) + endforeach() + + foreach(iter ${ARG_PRIVATE}) + find_package("Qt${ARG_VERSION}${iter}" COMPONENTS Private ${ARG_REQUIRED}) + endforeach() + + foreach(__iter IN LISTS oneValueArgs multiValueArgs) + unset(ARG_${__iter}) + endforeach() + unset(ARG_UNPARSED_ARGUMENTS) + unset(multiValueArgs) + unset(oneValueArgs) + unset(options) +endmacro() diff --git a/cmake/myx/lib/macro/QtTargetSetup.cmake b/cmake/myx/lib/macro/QtTargetSetup.cmake deleted file mode 100644 index 861e6fb..0000000 --- a/cmake/myx/lib/macro/QtTargetSetup.cmake +++ /dev/null @@ -1,176 +0,0 @@ -include_guard(GLOBAL) - -macro(myx_qt_target_setup TARGET_NAME) - set(options) - set(oneValueArgs VERSION) - set(multiValueArgs COMPONENTS PRIVATE PUBLIC_MOC PRIVATE_MOC UI QRC LANGS) - - cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT ARG_VERSION) - set(ARG_VERSION "5") - endif() - - if(NOT (ARG_VERSION STREQUAL "5" OR ARG_VERSION STREQUAL "6")) - myx_message_fatal_error("Supported Qt versions are 5 and 6") - endif() - - foreach(iter ${ARG_COMPONENTS}) - find_package(Qt${ARG_VERSION} COMPONENTS ${iter} REQUIRED) - endforeach() - - foreach(iter ${ARG_PRIVATE}) - find_package("Qt${ARG_VERSION}${iter}" COMPONENTS Private REQUIRED) - endforeach() - - myx_qt_target_setup_post(${ARGV}) - - foreach(__iter IN LISTS oneValueArgs multiValueArgs) - unset(ARG_${__iter}) - endforeach() - unset(ARG_UNPARSED_ARGUMENTS) - unset(multiValueArgs) - unset(oneValueArgs) - unset(options) -endmacro() - -function(myx_qt_target_setup_post TARGET_NAME) - set(options) - set(oneValueArgs VERSION) - set(multiValueArgs COMPONENTS PRIVATE PUBLIC_MOC PRIVATE_MOC UI QRC LANGS) - - cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT ARG_VERSION) - set(ARG_VERSION "5") - endif() - - if(NOT (ARG_VERSION STREQUAL "5" OR ARG_VERSION STREQUAL "6")) - myx_message_fatal_error("Supported Qt versions are 5 and 6") - endif() - - get_target_property(__target_type ${TARGET_NAME} TYPE) - - foreach(iter ${ARG_COMPONENTS}) - if(__target_type STREQUAL "INTERFACE_LIBRARY") - target_include_directories(${TARGET_NAME} INTERFACE ${Qt${ARG_VERSION}${iter}_INCLUDE_DIRS}) - else() - target_include_directories(${TARGET_NAME} PRIVATE ${Qt${ARG_VERSION}${iter}_INCLUDE_DIRS}) - endif() - if(NOT iter STREQUAL "LinguistTools") - if(__target_type STREQUAL "EXECUTABLE") - target_link_libraries(${TARGET_NAME} PRIVATE "Qt${ARG_VERSION}::${iter}") - endif() - if(__target_type STREQUAL "SHARED_LIBRARY") - target_link_libraries(${TARGET_NAME} PUBLIC "Qt${ARG_VERSION}::${iter}") - endif() - if((${CMAKE_VERSION} VERSION_GREATER "3.8.0") AND (__target_type STREQUAL "OBJECT_LIBRARY")) - target_link_libraries(${TARGET_NAME} PUBLIC "Qt${ARG_VERSION}::${iter}") - endif() - endif() - endforeach() - - foreach(iter ${ARG_PRIVATE}) - if(__target_type STREQUAL "INTERFACE_LIBRARY") - target_include_directories(${TARGET_NAME} INTERFACE ${Qt${ARG_VERSION}${iter}_PRIVATE_INCLUDE_DIRS}) - else() - target_include_directories(${TARGET_NAME} PRIVATE ${Qt${ARG_VERSION}${iter}_PRIVATE_INCLUDE_DIRS}) - endif() - endforeach() - - if(__target_type STREQUAL "EXECUTABLE") - target_compile_options(${TARGET_NAME} PRIVATE ${Qt${ARG_VERSION}Core_EXECUTABLE_COMPILE_FLAGS}) - endif() - - if(ARG_PUBLIC_MOC) - set_property(TARGET ${TARGET_NAME} APPEND PROPERTY PUBLIC_HEADER_FILES "${ARG_PUBLIC_MOC}") - set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_PUBLIC_MOC}) - endif() - - if(ARG_PRIVATE_MOC) - set_property(TARGET ${TARGET_NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PRIVATE_MOC}") - set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_PRIVATE_MOC}) - endif() - - if(ARG_PUBLIC_MOC OR ARG_PRIVATE_MOC) - if(ARG_VERSION STREQUAL "5") - qt5_wrap_cpp(moc_cpp ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC}) - else() - qt6_wrap_cpp(moc_cpp ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC}) - endif() - endif() - - if(ARG_QRC) - if(ARG_VERSION STREQUAL "5") - qt5_add_resources(qrc_cpp ${ARG_QRC}) - else() - qt6_add_resources(qrc_cpp ${ARG_QRC}) - endif() - endif() - - if(ARG_UI AND "Widgets" IN_LIST ARG_COMPONENTS) - if(ARG_VERSION STREQUAL "5") - qt5_wrap_ui(ui_h ${ARG_UI}) - else() - qt6_wrap_ui(ui_h ${ARG_UI}) - endif() - set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_UI}) - # TODO - target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_BINARY_DIR}) - endif() - - # Перечень файлов, подлежащих переводу - if(__target_type STREQUAL "INTERFACE_LIBRARY") - get_target_property(tr ${TARGET_NAME} INTERFACE_TR_FILES) - else() - get_target_property(tr ${TARGET_NAME} TR_FILES) - endif() - # Формирование файла ресурсов с переводами - if("LinguistTools" IN_LIST ARG_COMPONENTS AND tr) - # Заглавие файла ресурсов - file(WRITE ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc "\n") - # Для каждого языка, указанное в параметре LANGS - foreach(iter ${ARG_LANGS}) - # Создание или обновление файла переводов в каталоге ${PROJECT_SOURCE_DIR}/l10n - # и его компиляция в каталог ${PROJECT_BINARY_DIR} - if(ARG_VERSION STREQUAL "5") - qt5_create_translation(qm ${tr} - "${PROJECT_SOURCE_DIR}/l10n/${TARGET_NAME}_${iter}.ts" - OPTIONS -I ${PROJECT_SOURCE_DIR}/include -I ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}) - else() - qt6_create_translation(qm ${tr} - "${PROJECT_SOURCE_DIR}/l10n/${TARGET_NAME}_${iter}.ts" - OPTIONS -I ${PROJECT_SOURCE_DIR}/include -I ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}) - endif() - # Добавление записи для скомпилированного файла переводов в ресурсный файл - file(APPEND ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc - "${TARGET_NAME}_${iter}.qm\n") - # Добавление скомпилированного файла переводов к списку зависимостей для цели - target_sources(${TARGET_NAME} PRIVATE ${qm}) - endforeach() - # Окончание файла ресурсов - file(APPEND ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc "\n") - # Компиляция файла ресурсов с переводами - if(ARG_VERSION STREQUAL "5") - qt5_add_resources(qrc_l10n ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc) - else() - qt6_add_resources(qrc_l10n ${PROJECT_BINARY_DIR}/${TARGET_NAME}_l10n.qrc) - endif() - target_sources(${TARGET_NAME} PRIVATE ${qrc_l10n}) - endif() - unset(tr) - if(__target_type STREQUAL "INTERFACE_LIBRARY") - target_sources(${TARGET_NAME} INTERFACE ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC} ${moc_cpp} ${ui_h} ${qrc_cpp}) - else() - target_sources(${TARGET_NAME} PRIVATE ${ARG_PUBLIC_MOC} ${ARG_PRIVATE_MOC} ${moc_cpp} ${ui_h} ${qrc_cpp}) - endif() - - # Установка публичных заголовочных файлов - if(PROJECT_IS_TOP_LEVEL) - myx_install_relative(${PROJECT_SOURCE_DIR} - FILES ${ARG_PUBLIC_MOC} - DESTINATION ${CMAKE_INSTALL_PREFIX} - COMPONENT DEV - ) - endif() -endfunction() diff --git a/cmake/myx/lib/uncrustify/Uncrustify.cmake b/cmake/myx/lib/uncrustify/Uncrustify.cmake index 233dbbf..84efdde 100644 --- a/cmake/myx/lib/uncrustify/Uncrustify.cmake +++ b/cmake/myx/lib/uncrustify/Uncrustify.cmake @@ -9,10 +9,6 @@ function(myx_uncrustify TARGET_NAME) set(CMAKE_CURRENT_FUNCTION_LIST_DIR ${MYX_CMAKE_LIB_UNCRUSTIFY_DIR_BACKPORT}) endif() - if(NOT ${PROJECT_BINARY_DIR} STREQUAL ${CMAKE_BINARY_DIR}) - return() - endif() - set(options) set(oneValueArgs CONFIG) set(multiValueArgs) @@ -32,6 +28,12 @@ function(myx_uncrustify TARGET_NAME) return() endif() + get_filename_component(CONFIG_DIR ${ARG_CONFIG} DIRECTORY) + if(NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CONFIG_DIR}") + myx_message("MyxCMake: skip uncrustify for project ${PROJECT_NAME}") + return() + endif() + if(NOT TARGET myx-uncrustify) add_custom_target(myx-uncrustify) endif() diff --git a/cmake/myx_setup.cmake b/cmake/myx_setup.cmake index cd2f5a2..d4733e6 100644 --- a/cmake/myx_setup.cmake +++ b/cmake/myx_setup.cmake @@ -20,11 +20,11 @@ if(ENV{MYX_CMAKE_DIR}) set(MYX_CMAKE_DIR $ENV{MYX_CMAKE_DIR}) endif() if(MYX_CMAKE_DIR) - find_package(MyxCMake 2.4.2 REQUIRED CONFIG PATHS ${MYX_CMAKE_DIR} NO_DEFAULT_PATH) + find_package(MyxCMake 2.4.10 REQUIRED CONFIG PATHS ${MYX_CMAKE_DIR} NO_DEFAULT_PATH) myx_message_notice("== MyxCMake directory: ${MyxCMake_CONFIG} ==") else() if(MYX_CMAKE_USE_SYSTEM) - find_package(MyxCMake 2.4.2 REQUIRED) + find_package(MyxCMake 2.4.10 REQUIRED) myx_message_notice("== MyxCMake directory: ${MyxCMake_CONFIG} ==") else() include(${PROJECT_SOURCE_DIR}/cmake/myx/MyxCMakeConfig.cmake)