From 9214b8adf034251fcf70e9e19951794b19a9376a Mon Sep 17 00:00:00 2001 From: Andrey Astafyev Date: Sun, 30 Jul 2023 12:35:20 +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/lib/AddExternalTarget.cmake | 79 +++++++++++++++++++ cmake/myx/lib/Toolchains.cmake | 56 +++++++++++++ cmake/myx/lib/macro/GTest.cmake | 30 +++++++ cmake/myx/lib/macro/QTest.cmake | 40 ++++++++++ .../myx/lib/toolchains/AstraLinuxSE-1.5.cmake | 8 ++ cmake/myx/lib/toolchains/Clang.cmake | 3 + cmake/myx/lib/toolchains/ElbrusD-1.4.cmake | 9 +++ cmake/myx/lib/toolchains/GCC.cmake | 3 + 8 files changed, 228 insertions(+) create mode 100644 cmake/myx/lib/AddExternalTarget.cmake create mode 100644 cmake/myx/lib/Toolchains.cmake create mode 100644 cmake/myx/lib/macro/GTest.cmake create mode 100644 cmake/myx/lib/macro/QTest.cmake create mode 100644 cmake/myx/lib/toolchains/AstraLinuxSE-1.5.cmake create mode 100644 cmake/myx/lib/toolchains/Clang.cmake create mode 100644 cmake/myx/lib/toolchains/ElbrusD-1.4.cmake create mode 100644 cmake/myx/lib/toolchains/GCC.cmake diff --git a/cmake/myx/lib/AddExternalTarget.cmake b/cmake/myx/lib/AddExternalTarget.cmake new file mode 100644 index 0000000..b1f562b --- /dev/null +++ b/cmake/myx/lib/AddExternalTarget.cmake @@ -0,0 +1,79 @@ +#[=======================================================================[.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/Toolchains.cmake b/cmake/myx/lib/Toolchains.cmake new file mode 100644 index 0000000..963098d --- /dev/null +++ b/cmake/myx/lib/Toolchains.cmake @@ -0,0 +1,56 @@ +include_guard(GLOBAL) + +if(CMAKE_SYSTEM_NAME STREQUAL Linux) + set(MYX_CMAKE_LSB_DISTRIBUTOR_ID "unknown") + set(MYX_CMAKE_LSB_CODENAME "unknown") + set(MYX_CMAKE_LSB_RELEASE_VERSION "unknown") + + if(CMAKE_CROSSCOMPILING) + return() + endif() + + 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_VERSION + 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_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + # cmake-format: on + endif() +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + include("${MYX_CMAKE_TOOLCHAINS_DIR}/GCC.cmake") +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + include("${MYX_CMAKE_TOOLCHAINS_DIR}/Clang.cmake") +endif() + +if((MYX_CMAKE_LSB_DISTRIBUTOR_ID STREQUAL "AstraLinuxSE") AND + (MYX_CMAKE_LSB_CODENAME STREQUAL "smolensk") AND + (MYX_CMAKE_LSB_RELEASE_VERSION STREQUAL "1.5")) + include("${MYX_CMAKE_TOOLCHAINS_DIR}/AstraLinuxSE-1.5.cmake") + return() +endif() + +if((MYX_CMAKE_LSB_DISTRIBUTOR_ID STREQUAL "ElbrusD") AND + (MYX_CMAKE_LSB_CODENAME STREQUAL "Jessie") AND + (MYX_CMAKE_LSB_RELEASE_VERSION VERSION_GREATER "1.4")) + include("${MYX_CMAKE_TOOLCHAINS_DIR}/ElbrusD-1.4.cmake") + return() +endif() diff --git a/cmake/myx/lib/macro/GTest.cmake b/cmake/myx/lib/macro/GTest.cmake new file mode 100644 index 0000000..9ff6b92 --- /dev/null +++ b/cmake/myx/lib/macro/GTest.cmake @@ -0,0 +1,30 @@ +include_guard(GLOBAL) + +macro(myx_add_gtest TARGET_NAME) + set(options) + set(oneValueArgs) + set(multiValueArgs) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + add_executable(${TARGET_NAME} ${ARG_UNPARSED_ARGUMENTS}) + + find_package(GTest) + if(GTest_FOUND) + target_link_libraries(${TARGET_NAME} PRIVATE GTest::GTest GTest::Main) + else() + if((NOT TARGET gtest) AND (NOT TARGET gtest_main)) + add_subdirectory(/usr/src/googletest/googletest ${CMAKE_BINARY_DIR}/gtest) + endif() + target_link_libraries(${TARGET_NAME} PRIVATE gtest gtest_main) + endif() + + add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME}) + 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/QTest.cmake b/cmake/myx/lib/macro/QTest.cmake new file mode 100644 index 0000000..f77cf04 --- /dev/null +++ b/cmake/myx/lib/macro/QTest.cmake @@ -0,0 +1,40 @@ +include_guard(GLOBAL) + +macro(myx_add_qtest TARGET_NAME) + set(options) + set(oneValueArgs) + set(multiValueArgs) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + find_package(Qt5 COMPONENTS Core Test REQUIRED) + if(NOT Qt5Test_FOUND) + myx_message_fatal_error("Qt testing framework is not found") + return() + endif() + + foreach(filename ${ARG_UNPARSED_ARGUMENTS}) + get_filename_component(basename ${filename} NAME_WE) + list(APPEND cpps "${basename}.cpp") + list(APPEND hpps "${basename}.hpp") + qt5_wrap_cpp(moc "${basename}.hpp") + list(APPEND mocs "${moc}") + endforeach() + + add_executable(${TARGET_NAME} ${mocs} ${cpps} ${hpps}) + target_link_libraries(${TARGET_NAME} Qt5::Core Qt5::Test) + + add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME}) + + unset(cpps) + unset(hpps) + unset(moc) + unset(mocs) + 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/toolchains/AstraLinuxSE-1.5.cmake b/cmake/myx/lib/toolchains/AstraLinuxSE-1.5.cmake new file mode 100644 index 0000000..df9db4a --- /dev/null +++ b/cmake/myx/lib/toolchains/AstraLinuxSE-1.5.cmake @@ -0,0 +1,8 @@ +find_program(CMAKE_AR NAMES "/usr/bin/x86_64-linux-gnu-gcc-ar-4.7") +find_program(CMAKE_NM NAMES "/usr/bin/x86_64-linux-gnu-gcc-nm-4.7") +find_program(CMAKE_RANLIB NAMES "/usr/bin/x86_64-linux-gnu-gcc-ranlib-4.7") + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_EXTENSIONS ON) +check_enable_cxx_compiler_flag(-Wno-shadow) + diff --git a/cmake/myx/lib/toolchains/Clang.cmake b/cmake/myx/lib/toolchains/Clang.cmake new file mode 100644 index 0000000..e5f1d62 --- /dev/null +++ b/cmake/myx/lib/toolchains/Clang.cmake @@ -0,0 +1,3 @@ +if(CMAKE_COLOR_MAKEFILE) + check_enable_cxx_compiler_flag(-fcolor-diagnostics) +endif() diff --git a/cmake/myx/lib/toolchains/ElbrusD-1.4.cmake b/cmake/myx/lib/toolchains/ElbrusD-1.4.cmake new file mode 100644 index 0000000..29b46c6 --- /dev/null +++ b/cmake/myx/lib/toolchains/ElbrusD-1.4.cmake @@ -0,0 +1,9 @@ +find_program(CMAKE_AR NAMES "/usr/${CMAKE_SYSTEM_PROCESSOR}-linux/bin/ar") +find_program(CMAKE_NM NAMES "/usr/${CMAKE_SYSTEM_PROCESSOR}-linux/bin/nm") +find_program(CMAKE_RANLIB NAMES "/usr/${CMAKE_SYSTEM_PROCESSOR}-linux/bin/ranlib") + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_EXTENSIONS ON) +check_enable_cxx_compiler_flag(-Wno-invalid-offsetof) +list(APPEND CMAKE_LIBRARY_PATH "/usr/lib/e2k-linux-gnu") + diff --git a/cmake/myx/lib/toolchains/GCC.cmake b/cmake/myx/lib/toolchains/GCC.cmake new file mode 100644 index 0000000..3ac7ec8 --- /dev/null +++ b/cmake/myx/lib/toolchains/GCC.cmake @@ -0,0 +1,3 @@ +if(CMAKE_COLOR_MAKEFILE) + check_enable_cxx_compiler_flag(-fdiagnostics-color=auto) +endif()