From 56ca4c3a1c9e16bf93074ebe61d48cec6267e50e Mon Sep 17 00:00:00 2001 From: Andrey Astafyev Date: Fri, 7 Oct 2022 15:02:38 +0300 Subject: [PATCH] update --- cmake/myx/MyxCMakeConfig.cmake | 18 ++++++--- cmake/myx/MyxCMakeConfigVersion.cmake | 2 +- cmake/myx/lib/CompilerFlags.cmake | 28 ++++++++++++++ cmake/myx/lib/DirectoriesGuards.cmake | 21 +++++++++++ cmake/myx/lib/FetchContentAdd.cmake | 4 +- cmake/myx/lib/LSBInfo.cmake | 34 +++++++++++++++++ cmake/myx/lib/TargetSetup.cmake | 37 +++++++++++++++++-- cmake/myx/lib/Toolchain.cmake | 35 ++++++++++++++++++ cmake/myx/lib/Uninstall.cmake | 13 +++++++ .../macro/CheckEnableCxxCompilerFlag.cmake | 37 +++++++++++++++++++ cmake/myx/lib/macro/FindPackages.cmake | 1 - cmake/myx/lib/uninstall.cmake.in | 31 ++++++++++++++++ cmake/myx_setup.cmake | 19 +++++++--- 13 files changed, 263 insertions(+), 17 deletions(-) create mode 100644 cmake/myx/lib/CompilerFlags.cmake create mode 100644 cmake/myx/lib/LSBInfo.cmake create mode 100644 cmake/myx/lib/Toolchain.cmake create mode 100644 cmake/myx/lib/Uninstall.cmake create mode 100644 cmake/myx/lib/macro/CheckEnableCxxCompilerFlag.cmake create mode 100644 cmake/myx/lib/uninstall.cmake.in diff --git a/cmake/myx/MyxCMakeConfig.cmake b/cmake/myx/MyxCMakeConfig.cmake index 27b091f..d450020 100644 --- a/cmake/myx/MyxCMakeConfig.cmake +++ b/cmake/myx/MyxCMakeConfig.cmake @@ -2,13 +2,15 @@ cmake_policy(PUSH) cmake_policy(SET CMP0057 NEW) # IN_LIST operator # Каталог для модулей, выполняющих поиск библиотек -list(INSERT CMAKE_MODULE_PATH 0 "${PROJECT_SOURCE_DIR}/cmake/find") +set(MYX_CMAKE_FIND_DIR "${PROJECT_SOURCE_DIR}/cmake/find") +if(IS_DIRECTORY "${MYX_CMAKE_FIND_DIR}") + if(NOT ${MYX_CMAKE_FIND_DIR} IN_LIST CMAKE_MODULE_PATH) + list(INSERT CMAKE_MODULE_PATH 0 "${MYX_CMAKE_FIND_DIR}") + endif() +endif() get_filename_component(MYX_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) -#set(MYX_CMAKE_BACKPORTS_DIR "${MYX_CMAKE_SOURCE_DIR}/backports" CACHE PATH "") -#set(MYX_CMAKE_LIB_DIR "${MYX_CMAKE_SOURCE_DIR}/lib" CACHE PATH "") - set(MYX_CMAKE_BACKPORTS_DIR "${MYX_CMAKE_SOURCE_DIR}/backports") set(MYX_CMAKE_LIB_DIR "${MYX_CMAKE_SOURCE_DIR}/lib") @@ -26,16 +28,20 @@ include(CMakeDependentOption) include(${MYX_CMAKE_LIB_DIR}/macro/CreateSymlink.cmake) include(${MYX_CMAKE_LIB_DIR}/macro/FindPackages.cmake) include(${MYX_CMAKE_LIB_DIR}/macro/InstallRelative.cmake) +include(${MYX_CMAKE_LIB_DIR}/macro/CheckEnableCxxCompilerFlag.cmake) +include(${MYX_CMAKE_LIB_DIR}/ColoredMessages.cmake) include(${MYX_CMAKE_LIB_DIR}/PopulateCMakeBinaryDir.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) 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}/LSBInfo.cmake) +include(${MYX_CMAKE_LIB_DIR}/Toolchain.cmake) +include(${MYX_CMAKE_LIB_DIR}/CompilerFlags.cmake) include(${MYX_CMAKE_LIB_DIR}/AddExecutable.cmake) include(${MYX_CMAKE_LIB_DIR}/AddLibrary.cmake) include(${MYX_CMAKE_LIB_DIR}/TargetSetup.cmake) @@ -47,6 +53,8 @@ include(${MYX_CMAKE_LIB_DIR}/doc/Doxygen.cmake) include(${MYX_CMAKE_LIB_DIR}/generators/PrivateConfigHeader.cmake) include(${MYX_CMAKE_LIB_DIR}/generators/GitInfoHeader.cmake) +include(${MYX_CMAKE_LIB_DIR}/Uninstall.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 cd17f81..a4550aa 100644 --- a/cmake/myx/MyxCMakeConfigVersion.cmake +++ b/cmake/myx/MyxCMakeConfigVersion.cmake @@ -1,4 +1,4 @@ -set(MYX_CMAKE_PACKAGE_VERSION "1.99.99") +set(MYX_CMAKE_PACKAGE_VERSION "2.0.6") if(MYX_CMAKE_PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() diff --git a/cmake/myx/lib/CompilerFlags.cmake b/cmake/myx/lib/CompilerFlags.cmake new file mode 100644 index 0000000..7108dbc --- /dev/null +++ b/cmake/myx/lib/CompilerFlags.cmake @@ -0,0 +1,28 @@ +include_guard(GLOBAL) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") +# cmake-format: off + if((MYX_CMAKE_LSB_DISTRIBUTOR_ID STREQUAL "AstraLinuxSE") AND + (MYX_CMAKE_LSB_CODENAME STREQUAL "smolensk") AND + (MYX_CMAKE_LSB_RELEASE_VERSION STREQUAL "1.5")) +# cmake-format: on + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_EXTENSIONS ON) + check_enable_cxx_compiler_flag(-Wno-shadow) + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "e2k") + 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") + endif() + if(CMAKE_COLOR_MAKEFILE) + check_enable_cxx_compiler_flag(-fdiagnostics-color=auto) + endif() +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(CMAKE_COLOR_MAKEFILE) + check_enable_cxx_compiler_flag(-fcolor-diagnostics) + endif() +endif() + diff --git a/cmake/myx/lib/DirectoriesGuards.cmake b/cmake/myx/lib/DirectoriesGuards.cmake index ce679be..57b9531 100644 --- a/cmake/myx/lib/DirectoriesGuards.cmake +++ b/cmake/myx/lib/DirectoriesGuards.cmake @@ -46,6 +46,27 @@ if(project_binary_dir STREQUAL project_source_dir) "Myx: Cannot build in source directory ${CMAKE_SOURCE_DIR}") endif() +# Очистка от сгенерированных файлов +file(GLOB_RECURSE cmakelists_files RELATIVE ${cmake_source_dir} CMakeLists.txt) +foreach(it ${cmakelists_files}) + get_filename_component(file ${it} REALPATH) + get_filename_component(dir ${file} DIRECTORY) + file(REMOVE_RECURSE + ${dir}/.cmake + ${dir}/CMakeFiles) + file(REMOVE + ${dir}/CMakeFiles + ${dir}/CMakeCache.txt + ${dir}/cmake_install.cmake + ${dir}/compile_commands.json + ${dir}/Makefile + ${dir}/.ninja_deps + ${dir}/.ninja_logs + ${dir}/build.ninja + ${dir}/rules.ninja) +endforeach() + +unset(cmakelists_files) unset(cmake_source_dir) unset(cmake_binary_dir) unset(project_source_dir) diff --git a/cmake/myx/lib/FetchContentAdd.cmake b/cmake/myx/lib/FetchContentAdd.cmake index 1b40ac2..a8a2424 100644 --- a/cmake/myx/lib/FetchContentAdd.cmake +++ b/cmake/myx/lib/FetchContentAdd.cmake @@ -51,7 +51,9 @@ function(FetchContent_Add NAME) GIT_SHALLOW 1 ) - if(NOT ${NAME}_POPULATED) + string(TOLOWER ${NAME} lower_name) + FetchContent_GetProperties(${NAME}) + if(NOT ${lower_name}_POPULATED) FetchContent_Populate(${NAME}) add_subdirectory(${${NAME}_SOURCE_DIR} ${${NAME}_BINARY_DIR}) endif() diff --git a/cmake/myx/lib/LSBInfo.cmake b/cmake/myx/lib/LSBInfo.cmake new file mode 100644 index 0000000..0f15d86 --- /dev/null +++ b/cmake/myx/lib/LSBInfo.cmake @@ -0,0 +1,34 @@ +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() diff --git a/cmake/myx/lib/TargetSetup.cmake b/cmake/myx/lib/TargetSetup.cmake index cb2236f..cd79431 100644 --- a/cmake/myx/lib/TargetSetup.cmake +++ b/cmake/myx/lib/TargetSetup.cmake @@ -73,11 +73,42 @@ function(myx_target_setup NAME) target_sources(${NAME} PUBLIC $) target_sources(${NAME} PUBLIC ${ARG_PUBLIC_HEADERS}) target_sources(${NAME} PRIVATE ${ARG_CPP} ${ARG_PCH} ${ARG_PRIVATE_HEADERS}) - if(NOT target_type STREQUAL "OBJECT_LIBRARY") - target_link_libraries(${NAME} PRIVATE ${ARG_LINK_LIBRARIES}) - endif() target_compile_definitions(${NAME} PRIVATE ${ARG_COMPILE_DEFINITIONS}) + # CMake до версии 3.12 не умеет извлекать из целей типа `OBJECT_LIBRARY` + # информацию о заголовочных файлах. Это обход. + if(${CMAKE_VERSION} VERSION_GREATER "3.11.99") + target_link_libraries(${NAME} PRIVATE ${ARG_LINK_LIBRARIES}) + else() + if((NOT ${target_type} STREQUAL "OBJECT_LIBRARY") AND + (NOT ${target_type} STREQUAL "EXECUTABLE")) + target_link_libraries(${NAME} PRIVATE ${ARG_LINK_LIBRARIES}) + else() + foreach(link_library ${ARG_LINK_LIBRARIES}) + if(TARGET ${link_library}) + get_target_property(lib_type ${link_library} TYPE) + if(lib_type) + get_target_property(include_dir ${link_library} INTERFACE_INCLUDE_DIRECTORIES) + if(include_dir) + target_include_directories(${NAME} PUBLIC ${include_dir}) + endif() + if(${target_type} STREQUAL "EXECUTABLE") + if(${lib_type} STREQUAL "OBJECT_LIBRARY") + if(TARGET ${link_library}_static) + target_link_libraries(${NAME} PRIVATE ${link_library}_static) + else() + target_link_libraries(${NAME} PRIVATE ${link_library}_shared) + endif() + else() + target_link_libraries(${NAME} PRIVATE ${link_library}) + endif() + endif() + endif() + endif() + endforeach() + endif() + endif() + # Установка публичных заголовочных файлов if(PROJECT_IS_TOP_LEVEL) install_relative(${PROJECT_SOURCE_DIR} diff --git a/cmake/myx/lib/Toolchain.cmake b/cmake/myx/lib/Toolchain.cmake new file mode 100644 index 0000000..817a113 --- /dev/null +++ b/cmake/myx/lib/Toolchain.cmake @@ -0,0 +1,35 @@ +include_guard(GLOBAL) + +# Предпочтительные пути к утилитам для компоновки +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") +# cmake-format: off + # 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_VERSION 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") + # Другие версии Linux + 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() +# cmake-format: on + + 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() diff --git a/cmake/myx/lib/Uninstall.cmake b/cmake/myx/lib/Uninstall.cmake new file mode 100644 index 0000000..f5082a6 --- /dev/null +++ b/cmake/myx/lib/Uninstall.cmake @@ -0,0 +1,13 @@ +#[=======================================================================[.rst: +Цель для удаления файлов, установленных выполнением цели `install`. +Если при установке использовалась переменная `DESTDIR`, то при удалении +файлов нужно указать то же значение. +#]=======================================================================] + +include_guard(GLOBAL) + +if(NOT TARGET uninstall) + configure_file(${CMAKE_CURRENT_LIST_DIR}/uninstall.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() diff --git a/cmake/myx/lib/macro/CheckEnableCxxCompilerFlag.cmake b/cmake/myx/lib/macro/CheckEnableCxxCompilerFlag.cmake new file mode 100644 index 0000000..c711262 --- /dev/null +++ b/cmake/myx/lib/macro/CheckEnableCxxCompilerFlag.cmake @@ -0,0 +1,37 @@ +include_guard(GLOBAL) + +# based on https://github.com/bluescarni/yacma + +include(CheckCXXCompilerFlag) + +macro(check_enable_cxx_compiler_flag flag) + set(options) + set(oneValueArgs TARGET) + set(multiValueArgs) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(CMAKE_REQUIRED_QUIET TRUE) + check_cxx_compiler_flag("${flag}" check_cxx_flag) + unset(CMAKE_REQUIRED_QUIET) + + if(check_cxx_flag) + myx_message_notice("'${flag}': flag is supported.") + if(ARG_TARGET) + target_compile_options(${ARG_TARGET} PUBLIC ${flag}) + else() + add_compile_options(${flag}) + endif() + else() + myx_message_status("'${flag}': flag is NOT supported.") + endif() + + unset(check_cxx_flag CACHE) + 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/FindPackages.cmake b/cmake/myx/lib/macro/FindPackages.cmake index 9727195..4d933d4 100644 --- a/cmake/myx/lib/macro/FindPackages.cmake +++ b/cmake/myx/lib/macro/FindPackages.cmake @@ -4,7 +4,6 @@ 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}) diff --git a/cmake/myx/lib/uninstall.cmake.in b/cmake/myx/lib/uninstall.cmake.in new file mode 100644 index 0000000..0f747a1 --- /dev/null +++ b/cmake/myx/lib/uninstall.cmake.in @@ -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() + diff --git a/cmake/myx_setup.cmake b/cmake/myx_setup.cmake index ab11dbd..173bad6 100644 --- a/cmake/myx_setup.cmake +++ b/cmake/myx_setup.cmake @@ -16,15 +16,15 @@ проекта использовать дополнительные инструменты для его сопровождения. #]=======================================================================] -if(MYX_CMAKE_DIR) - set(ENV{MYX_CMAKE_DIR} ${MYX_CMAKE_DIR}) +if(ENV{MYX_CMAKE_DIR}) + set(MYX_CMAKE_DIR $ENV{MYX_CMAKE_DIR}) endif() -if(DEFINED ENV{MYX_CMAKE_DIR}) - find_package(MyxCMake 1.99.99 REQUIRED CONFIG PATHS $ENV{MYX_CMAKE_DIR} NO_DEFAULT_PATH) +if(MYX_CMAKE_DIR) + find_package(MyxCMake 2.0.6 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 1.99.99 REQUIRED) + find_package(MyxCMake 2.0.6 REQUIRED) myx_message_notice("=== MyxCMake directory: ${MyxCMake_CONFIG} ===") else() include(${PROJECT_SOURCE_DIR}/cmake/myx/MyxCMakeConfig.cmake) @@ -32,5 +32,12 @@ else() endif() endif() -find_package(MyxxCMake CONFIG PATHS "$ENV{XDG_DATA_DIR}/cmake" QUIET) +if(ENV{MYXX_CMAKE_DIR}) + set(MYXX_CMAKE_DIR $ENV{MYXX_CMAKE_DIR}) +endif() +if(MYXX_CMAKE_DIR) + find_package(MyxxCMake CONFIG PATHS ${MYXX_CMAKE_DIR} NO_DEFAULT_PATH) +else() + find_package(MyxxCMake CONFIG PATHS "$ENV{XDG_DATA_DIR}/cmake" QUIET) +endif()