From 575054a11fa53021a0e1aefb4408249829abd4b0 Mon Sep 17 00:00:00 2001 From: Dennis Klein Date: Thu, 27 May 2021 00:59:35 +0200 Subject: [PATCH] Bundle and use FairCMakeModules --- .gitmodules | 3 + CMakeLists.txt | 169 +++++--------------- README.md | 39 ++--- cmake/BundlePackages.cmake | 102 ++++++++++++ cmake/FairMQLib.cmake | 308 ++++++++----------------------------- extern/FairCMakeModules | 1 + 6 files changed, 223 insertions(+), 399 deletions(-) create mode 100644 cmake/BundlePackages.cmake create mode 160000 extern/FairCMakeModules diff --git a/.gitmodules b/.gitmodules index 3d34647f..b297388b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "extern/PicoSHA2"] path = extern/PicoSHA2 url = https://github.com/okdshin/PicoSHA2 +[submodule "extern/FairCMakeModules"] + path = extern/FairCMakeModules + url = https://github.com/FairRootGroup/FairCMakeModules diff --git a/CMakeLists.txt b/CMakeLists.txt index fae1bc2d..b2f99fe2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,8 @@ # copied verbatim in the file "LICENSE" # ################################################################################ -cmake_minimum_required(VERSION 3.14 FATAL_ERROR) -cmake_policy(VERSION 3.14...3.20) +cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_policy(VERSION 3.15...3.20) # Project ###################################################################### set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) @@ -16,13 +16,25 @@ include(FairMQLib) get_git_version() project(FairMQ VERSION ${PROJECT_VERSION} LANGUAGES CXX) -message(STATUS "${BWhite}${PROJECT_NAME}${CR} ${PROJECT_GIT_VERSION} from ${PROJECT_DATE}") -set(PROJECT_MIN_CXX_STANDARD 17) +include(CTest) +include(BundlePackages) + +set(PROJECT_FairCMakeModules_VERSION 0.2) +find_package(FairCMakeModules ${PROJECT_FairCMakeModules_VERSION} QUIET) +if(NOT FairCMakeModules_FOUND) + build_bundled(FairCMakeModules extern/FairCMakeModules) + find_package(FairCMakeModules REQUIRED) +endif() + +include(FairFindPackage2) +include(FairFormattedOutput) +include(FairSummary) + +message(STATUS "${BWhite}${PROJECT_NAME}${CR} ${PROJECT_GIT_VERSION} from ${PROJECT_DATE}") set_fairmq_defaults() -include(CTest) ################################################################################ @@ -53,17 +65,17 @@ fairmq_build_option(FAIRMQ_DEBUG_MODE "Compile in debug mode (may decrease per # Dependencies ################################################################# -set(CMAKE_THREAD_PREFER_PTHREAD TRUE) -set(THREADS_PREFER_PTHREAD_FLAG TRUE) -find_package(Threads REQUIRED) +if(BUILD_FAIRMQ OR BUILD_SDK) + set(THREADS_PREFER_PTHREAD_FLAG TRUE) + find_package2(PUBLIC Threads REQUIRED) + set(Threads_PREFIX "") +endif() if(BUILD_OFI_TRANSPORT) find_package2(PRIVATE asiofi REQUIRED VERSION 0.3.1 ) - find_package2(PRIVATE OFI REQUIRED - ADD_REQUIREMENTS_OF asiofi - ) + find_package2(PRIVATE OFI REQUIRED) endif() if(BUILD_SDK_COMMANDS) @@ -89,13 +101,6 @@ if(BUILD_FAIRMQ OR BUILD_SDK) VERSION 1.6.0 ) - foreach(dep IN LISTS FairLogger_PACKAGE_DEPENDENCIES) - if(NOT dep STREQUAL "Boost") - find_package2(PUBLIC ${dep} REQUIRED VERSION ${FairLogger_${dep}_VERSION}) - set(PROJECT_${dep}_VERSION ${FairLogger_${dep}_VERSION}) - endif() - endforeach() - if(NOT DEFINED Boost_NO_BOOST_CMAKE AND CMAKE_VERSION VERSION_LESS 3.15) # Since Boost 1.70 a CMake package is shipped by default. Unfortunately, it has a number # of problems that are only fixed in Boost 1.71 or CMake 3.15. By default we skip the @@ -104,18 +109,7 @@ if(BUILD_FAIRMQ OR BUILD_SDK) endif() find_package2(PUBLIC Boost REQUIRED VERSION 1.66 - - COMPONENTS - container - program_options - filesystem - date_time - regex - - ADD_REQUIREMENTS_OF - asiofi - DDS - FairLogger + COMPONENTS container program_options filesystem date_time regex ) # Normalize Boost version @@ -138,27 +132,29 @@ if(BUILD_FAIRMQ) find_package2(PRIVATE ZeroMQ REQUIRED VERSION 4.1.4 ) - build_bundled(PicoSHA2 extern/PicoSHA2) - find_package2(PRIVATE PicoSHA2 REQUIRED) + if(NOT PicoSHA2_FOUND AND NOT PicoSHA2_BUNDLED) + set(PicoSHA2_VERSION "1.0.0") + build_bundled(PicoSHA2 extern/PicoSHA2) + endif() + find_package2(BUNDLED PicoSHA2 REQUIRED) endif() if(BUILD_TESTING) - if(USE_EXTERNAL_GTEST) - find_package2(PRIVATE GTest VERSION 1.7.0) - endif() - if(NOT GTest_FOUND) + if(NOT GTest_FOUND AND NOT GTest_BUNDLED AND NOT USE_EXTERNAL_GTEST) + set(GTest_VERSION "Apr 28 2021 @f5e592d8") build_bundled(GTest extern/googletest) - find_package2(PRIVATE GTest REQUIRED) endif() + find_package2(BUNDLED GTest REQUIRED) endif() if(BUILD_DOCS) find_package2(PRIVATE Doxygen REQUIRED VERSION 1.8.8 COMPONENTS dot - OPTIONAL_COMPONENTS mscgen dia ) endif() + +find_package2_implicit_dependencies() ################################################################################ @@ -251,99 +247,10 @@ install_cmake_package() # Summary ###################################################################### -message(STATUS " ") -message(STATUS " ${Cyan}CXX STANDARD${CR} ${BGreen}C++${CMAKE_CXX_STANDARD}${CR} (>= C++${PROJECT_MIN_CXX_STANDARD}, change with ${BMagenta}-DCMAKE_CXX_STANDARD=20${CR})") -if(CMAKE_CXX_FLAGS) - message(STATUS " ") - message(STATUS " ${Cyan}GLOBAL CXX FLAGS${CR} ${BGreen}${CMAKE_CXX_FLAGS}${CR}") -endif() -if(CMAKE_CONFIGURATION_TYPES) - message(STATUS " ") - message(STATUS " ${Cyan}BUILD TYPE CXX FLAGS${CR}") - string(TOUPPER "${CMAKE_BUILD_TYPE}" selected_type) - foreach(type IN LISTS CMAKE_CONFIGURATION_TYPES) - string(TOUPPER "${type}" type_upper) - if(type_upper STREQUAL selected_type) - pad("${type}" 18 " " type_padded) - message(STATUS "${BGreen}* ${type_padded}${CMAKE_CXX_FLAGS_${type_upper}}${CR}") - else() - pad("${type}" 18 " " type_padded) - message(STATUS " ${BWhite}${type_padded}${CR}${CMAKE_CXX_FLAGS_${type_upper}}") - endif() - unset(type_padded) - unset(type_upper) - endforeach() - message(STATUS " ") - message(STATUS " (Change the build type with ${BMagenta}-DCMAKE_BUILD_TYPE=...${CR})") -endif() -if(PROJECT_PACKAGE_DEPENDENCIES) - message(STATUS " ") - message(STATUS " ${Cyan}DEPENDENCY FOUND VERSION PREFIX${CR}") - foreach(dep IN LISTS PROJECT_PACKAGE_DEPENDENCIES) - if(${dep}_VERSION AND NOT ${dep}_VERSION STREQUAL "..") - set(version_str "${BGreen}${${dep}_VERSION}${CR}") - else() - set(version_str "${BYellow}unknown${CR}") - endif() - if(PROJECT_${dep}_VERSION) - set(version_req_str " (>= ${PROJECT_${dep}_VERSION})") - endif() - pad(${dep} 20 " " dep_padded) - if(DISABLE_COLOR) - pad("${version_str}${version_req_str}" 25 " " version_padded) - else() - pad("${version_str}${version_req_str}" 25 " " version_padded COLOR 1) - endif() - if(${dep} STREQUAL FairLogger) - if(FairLogger_PREFIX) - set(prefix ${FairLogger_PREFIX}) - else() - set(prefix ${FairLogger_ROOT}) - endif() - elseif(${dep} STREQUAL GTest) - get_filename_component(prefix ${GTEST_INCLUDE_DIRS}/.. ABSOLUTE) - elseif(${dep} STREQUAL asiofi) - set(prefix ${asiofi_ROOT}) - elseif(${dep} STREQUAL OFI) - get_filename_component(prefix ${${dep}_INCLUDE_DIRS}/.. ABSOLUTE) - elseif(${dep} STREQUAL DDS) - set(prefix "${DDS_INSTALL_PREFIX}") - elseif(${dep} STREQUAL Boost) - if(TARGET Boost::headers) - get_target_property(boost_include Boost::headers INTERFACE_INCLUDE_DIRECTORIES) - else() - get_target_property(boost_include Boost::boost INTERFACE_INCLUDE_DIRECTORIES) - endif() - get_filename_component(prefix ${boost_include}/.. ABSOLUTE) - elseif(${dep} STREQUAL Doxygen) - get_target_property(doxygen_bin Doxygen::doxygen INTERFACE_LOCATION) - get_filename_component(prefix ${doxygen_bin} DIRECTORY) - get_filename_component(prefix ${prefix}/.. ABSOLUTE) - elseif(${dep} STREQUAL fmt) - get_target_property(fmt_include fmt::fmt INTERFACE_INCLUDE_DIRECTORIES) - get_filename_component(prefix ${fmt_include}/.. ABSOLUTE) - elseif(${dep} STREQUAL Flatbuffers) - if(TARGET flatbuffers::flatbuffers) - get_target_property(flatbuffers_include flatbuffers::flatbuffers INTERFACE_INCLUDE_DIRECTORIES) - else() - get_target_property(flatbuffers_include flatbuffers::flatbuffers_shared INTERFACE_INCLUDE_DIRECTORIES) - endif() - get_filename_component(prefix ${flatbuffers_include}/.. ABSOLUTE) - else() - if(${dep}_PREFIX) - set(prefix ${${dep}_PREFIX}) - else() - get_filename_component(prefix ${${dep}_INCLUDE_DIR}/.. ABSOLUTE) - endif() - endif() - if(NOT ${dep}_BUNDLED) - message(STATUS " ${BWhite}${dep_padded}${CR}${version_padded}${prefix}") - endif() - unset(version_str) - unset(version_padded) - unset(version_req_str) - endforeach() -endif() +fair_summary_global_cxx_flags_standard() +fair_summary_build_types() +set_package_infos() +fair_summary_package_dependencies() message(STATUS " ") message(STATUS " ${Cyan}COMPONENT BUILT? INFO${CR}") if(BUILD_FAIRMQ) diff --git a/README.md b/README.md index 43ac15c4..192680c4 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Recommended: git clone https://github.com/FairRootGroup/FairMQ fairmq_source cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=fairmq_install cmake --build fairmq_build -cd fairmq_build; ctest -j4; cd .. +cmake --build fairmq_build --target test cmake --build fairmq_build --target install ``` @@ -54,39 +54,24 @@ If dependencies are not installed in standard system directories, you can hint t FairMQ ships as a CMake package, so in your `CMakeLists.txt` you can discover it like this: ```cmake -find_package(FairMQ) +find_package(FairCMakeModules 0.2 REQUIRED) +include(FairFindPackage2) +find_package2(FairMQ) +find_package2_implicit_dependencies() ``` +The [`FairFindPackage2` module](https://fairrootgroup.github.io/FairCMakeModules/latest/module/FairFindPackage2.html) is part of the [`FairCMakeModules` package](https://fairrootgroup.github.io/FairCMakeModules). + If FairMQ is not installed in system directories, you can hint the installation: ```cmake -set(CMAKE_PREFIX_PATH /path/to/FairMQ_install_prefix ${CMAKE_PREFIX_PATH}) -find_package(FairMQ) +list(PREPEND CMAKE_PREFIX_PATH /path/to/fairmq_install) ``` -`find_package(FairMQ)` will define an imported target `FairMQ::FairMQ`. - -In order to succesfully compile and link against the `FairMQ::FairMQ` target, you need to discover its public package dependencies: - -```cmake -find_package(FairMQ) -if(FairMQ_FOUND) - foreach(dep IN LISTS FairMQ_PACKAGE_DEPENDENCIES) - if(FairMQ_${dep}_COMPONENTS) - find_package(${dep} ${FairMQ_${dep}_VERSION} COMPONENTS ${FairMQ_${dep}_COMPONENTS}) - else() - find_package(${dep} ${FairMQ_${dep}_VERSION}) - endif() - endforeach() -endif() -``` - -If your project shares a dependency with FairMQ or if you want to omit a certain dependency, you may want to customize the above example code to your needs. - Optionally, you can require certain FairMQ package components and a minimum version: ```cmake -find_package(FairMQ 1.1.0 COMPONENTS dds_plugin) +find_package(FairMQ 1.4.0 COMPONENTS dds_plugin) ``` When building FairMQ, CMake will print a summary table of all available package components. @@ -99,6 +84,7 @@ When building FairMQ, CMake will print a summary table of all available package * [CMake](https://cmake.org/) * [DDS](http://dds.gsi.de) * [Doxygen](http://www.doxygen.org/) + * [FairCMakeModules](https://github.com/FairRootGroup/FairCMakeModules) (optionally bundled) * [FairLogger](https://github.com/FairRootGroup/FairLogger) * [GTest](https://github.com/google/googletest) (optionally bundled) * [PMIx](https://pmix.org/) @@ -126,9 +112,8 @@ After the `find_package(FairMQ)` call the following CMake variables are defined: | Variable | Info | | --- | --- | | `${FairMQ_PACKAGE_DEPENDENCIES}` | the list of public package dependencies | -| `${FairMQ_Boost_VERSION}` | the minimum Boost version FairMQ requires | -| `${FairMQ_Boost_COMPONENTS}` | the list of Boost components FairMQ depends on | -| `${FairMQ_FairLogger_VERSION}` | the minimum FairLogger version FairMQ requires | +| `${FairMQ__VERSION}` | the minimum `` version FairMQ requires | +| `${FairMQ__COMPONENTS}` | the list of `` components FairMQ depends on | | `${FairMQ_PACKAGE_COMPONENTS}` | the list of components FairMQ consists of | | `${FairMQ_#COMPONENT#_FOUND}` | `TRUE` if this component was built | | `${FairMQ_VERSION}` | the version in format `MAJOR.MINOR.PATCH` | diff --git a/cmake/BundlePackages.cmake b/cmake/BundlePackages.cmake new file mode 100644 index 00000000..8ea31227 --- /dev/null +++ b/cmake/BundlePackages.cmake @@ -0,0 +1,102 @@ +################################################################################ +# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # +# # +# This software is distributed under the terms of the # +# GNU Lesser General Public Licence (LGPL) version 3, # +# copied verbatim in the file "LICENSE" # +################################################################################ + +include_guard(GLOBAL) + +function(join VALUES GLUE OUTPUT) + string(REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}") + string(REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping + set(${OUTPUT} "${_TMP_STR}" PARENT_SCOPE) +endfunction() + +macro(exec cmd) + join("${ARGN}" " " args) + file(APPEND ${${package}_BUILD_LOGFILE} ">>> ${cmd} ${args}\n") + + execute_process(COMMAND ${cmd} ${ARGN} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + OUTPUT_VARIABLE log + ERROR_VARIABLE log + RESULT_VARIABLE res + ) + file(APPEND ${${package}_BUILD_LOGFILE} ${log}) + + if(res) + message(FATAL_ERROR "${res} \nSee also \"${${package}_BUILD_LOGFILE}\"") + endif() +endmacro() + +macro(exec_source cmd) + join("${ARGN}" " " args) + file(APPEND ${${package}_BUILD_LOGFILE} ">>> ${cmd} ${args}\n") + + execute_process(COMMAND ${cmd} ${ARGN} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE log + ERROR_VARIABLE log + RESULT_VARIABLE res + ) + file(APPEND ${${package}_BUILD_LOGFILE} ${log}) + + if(res) + message(FATAL_ERROR "${res} \nSee also \"${${package}_BUILD_LOGFILE}\"") + endif() +endmacro() + +function(build_bundled package bundle) + message(STATUS "Building bundled ${package}") + + set(${package}_SOURCE_DIR ${CMAKE_SOURCE_DIR}/${bundle}) + set(${package}_BINARY_DIR ${CMAKE_BINARY_DIR}/${bundle}) + file(MAKE_DIRECTORY ${${package}_BINARY_DIR}) + set(${package}_BUILD_LOGFILE ${${package}_BINARY_DIR}/build.log) + file(REMOVE ${${package}_BUILD_LOGFILE}) + + if(Git_FOUND) + exec_source(${GIT_EXECUTABLE} submodule update --init -- ${${package}_SOURCE_DIR}) + endif() + + if(${package} STREQUAL GTest) + set(${package}_INSTALL_DIR ${CMAKE_BINARY_DIR}/${bundle}_install) + file(MAKE_DIRECTORY ${${package}_INSTALL_DIR}) + set(${package}_PREFIX ${${package}_INSTALL_DIR}) + + exec(${CMAKE_COMMAND} -S ${${package}_SOURCE_DIR} -B ${${package}_BINARY_DIR} -G ${CMAKE_GENERATOR} + -DCMAKE_INSTALL_PREFIX=${${package}_INSTALL_DIR} -DBUILD_GMOCK=OFF + ) + exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR}) + exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR} --target install) + elseif(${package} STREQUAL asio) + set(${package}_INSTALL_DIR ${CMAKE_BINARY_DIR}/${bundle}_install) + file(MAKE_DIRECTORY ${${package}_INSTALL_DIR}) + set(${package}_PREFIX ${${package}_INSTALL_DIR}) + + exec(${CMAKE_COMMAND} -S ${${package}_SOURCE_DIR} -B ${${package}_BINARY_DIR} -G ${CMAKE_GENERATOR} + -DCMAKE_INSTALL_PREFIX=${${package}_INSTALL_DIR} + ) + exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR}) + exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR} --target install) + elseif(${package} STREQUAL FairCMakeModules) + set(${package}_INSTALL_DIR ${CMAKE_BINARY_DIR}/${bundle}_install) + file(MAKE_DIRECTORY ${${package}_INSTALL_DIR}) + set(${package}_PREFIX ${${package}_INSTALL_DIR}) + + exec(${CMAKE_COMMAND} -S ${${package}_SOURCE_DIR} -B ${${package}_BINARY_DIR} -G ${CMAKE_GENERATOR} + -DCMAKE_INSTALL_PREFIX=${${package}_INSTALL_DIR} + ) + exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR}) + exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR} --target install) + elseif(${package} STREQUAL PicoSHA2) + set(${package}_PREFIX ${${package}_SOURCE_DIR}) + endif() + + set(${package}_ROOT ${${package}_PREFIX} CACHE PATH "Location of bundle package ${package}") + set(${package}_BUNDLED ON CACHE BOOL "Whether bundled ${package} was used") + + message(STATUS "Building bundled ${package} - done") +endfunction() diff --git a/cmake/FairMQLib.cmake b/cmake/FairMQLib.cmake index 23b81cc7..171e4840 100644 --- a/cmake/FairMQLib.cmake +++ b/cmake/FairMQLib.cmake @@ -6,28 +6,7 @@ # copied verbatim in the file "LICENSE" # ################################################################################ -### PUBLIC - -# Defines some variables with console color escape sequences -if(NOT WIN32 AND NOT DISABLE_COLOR) - string(ASCII 27 Esc) - set(CR "${Esc}[m") - set(CB "${Esc}[1m") - set(Red "${Esc}[31m") - set(Green "${Esc}[32m") - set(Yellow "${Esc}[33m") - set(Blue "${Esc}[34m") - set(Magenta "${Esc}[35m") - set(Cyan "${Esc}[36m") - set(White "${Esc}[37m") - set(BRed "${Esc}[1;31m") - set(BGreen "${Esc}[1;32m") - set(BYellow "${Esc}[1;33m") - set(BBlue "${Esc}[1;34m") - set(BMagenta "${Esc}[1;35m") - set(BCyan "${Esc}[1;36m") - set(BWhite "${Esc}[1;37m") -endif() +include_guard(GLOBAL) find_package(Git) # get_git_version([DEFAULT_VERSION version] [DEFAULT_DATE date] [OUTVAR_PREFIX prefix]) @@ -93,6 +72,8 @@ macro(set_fairmq_defaults) set(CMAKE_BUILD_TYPE RelWithDebInfo) endif() + set(PROJECT_MIN_CXX_STANDARD 17) + # Handle C++ standard level set(CMAKE_CXX_STANDARD_REQUIRED ON) if(NOT CMAKE_CXX_STANDARD) @@ -160,7 +141,7 @@ macro(set_fairmq_defaults) (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5))) # Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support. # Rationale in https://github.com/ninja-build/ninja/issues/814 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always") + list(APPEND CMAKE_CXX_FLAGS "-fdiagnostics-color=always") endif() if(NOT PROJECT_VERSION_TWEAK) @@ -212,12 +193,6 @@ macro(set_fairmq_defaults) endif() endmacro() -function(join VALUES GLUE OUTPUT) - string(REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}") - string(REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping - set(${OUTPUT} "${_TMP_STR}" PARENT_SCOPE) -endfunction() - function(pad str width char out) cmake_parse_arguments(ARGS "" "COLOR" "" ${ARGN}) string(LENGTH ${str} length) @@ -234,34 +209,6 @@ function(pad str width char out) set(${out} ${str} PARENT_SCOPE) endfunction() -function(generate_package_dependencies) - join("${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES}" " " DEPS) - set(PACKAGE_DEPENDENCIES "\ -####### Expanded from @PACKAGE_DEPENDENCIES@ by configure_package_config_file() ####### - -set(${PROJECT_NAME}_PACKAGE_DEPENDENCIES ${DEPS}) - -") - foreach(dep IN LISTS PROJECT_INTERFACE_PACKAGE_DEPENDENCIES) - join("${PROJECT_INTERFACE_${dep}_COMPONENTS}" " " COMPS) - if(COMPS) - string(CONCAT PACKAGE_DEPENDENCIES ${PACKAGE_DEPENDENCIES} "\ -set(${PROJECT_NAME}_${dep}_COMPONENTS ${COMPS}) -") - endif() - if(PROJECT_INTERFACE_${dep}_VERSION) - string(CONCAT PACKAGE_DEPENDENCIES ${PACKAGE_DEPENDENCIES} "\ -set(${PROJECT_NAME}_${dep}_VERSION ${PROJECT_INTERFACE_${dep}_VERSION}) -") - endif() - endforeach() - string(CONCAT PACKAGE_DEPENDENCIES ${PACKAGE_DEPENDENCIES} "\ - -####################################################################################### -") -set(PACKAGE_DEPENDENCIES ${PACKAGE_DEPENDENCIES} PARENT_SCOPE) -endfunction() - function(generate_package_components) join("${PROJECT_PACKAGE_COMPONENTS}" " " COMPS) set(PACKAGE_COMPONENTS "\ @@ -319,7 +266,7 @@ macro(install_cmake_package) VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) - generate_package_dependencies() # fills ${PACKAGE_DEPENDENCIES} + fair_generate_package_dependencies() # fills ${PACKAGE_DEPENDENCIES} generate_package_components() # fills ${PACKAGE_COMPONENTS} generate_bundled_packages() # fills ${BUNDLED_PACKAGES} string(TOUPPER ${CMAKE_BUILD_TYPE} PROJECT_BUILD_TYPE_UPPER) @@ -337,190 +284,7 @@ macro(install_cmake_package) ) endmacro() -# -# find_package2(PRIVATE|PUBLIC|INTERFACE -# [VERSION ] -# [COMPONENTS ] -# [ADD_REQUIREMENTS_OF ] -# [any other option the native find_package supports]...) -# -# Wrapper around CMake's native find_package command to add some features and bookkeeping. -# -# The qualifier (PRIVATE|PUBLIC|INTERFACE|BUNDLED) to the package to populate -# the variables PROJECT_[INTERFACE]__([VERSION]|[COMPONENTS]|PACKAGE_DEPENDENCIES) -# accordingly. This bookkeeping information is used to print our dependency found summary -# table and to generate a part of our CMake package. BUNDLED decays to PUBLIC if the variable -# _BUNDLED is false and to PRIVATE otherwise. -# -# When a dependending package is listed with ADD_REQUIREMENTS_OF the variables -# __VERSION|COMPONENTS are looked up to and added to the native -# VERSION (selected highest version) and COMPONENTS (deduplicated) args. -# -# COMPONENTS and VERSION args are then just passed to the native find_package. -# -macro(find_package2 qualifier pkgname) - cmake_parse_arguments(ARGS "" "VERSION" "COMPONENTS;ADD_REQUIREMENTS_OF" ${ARGN}) - string(TOUPPER ${pkgname} pkgname_upper) - set(__old_cpp__ ${CMAKE_PREFIX_PATH}) - set(CMAKE_PREFIX_PATH ${${pkgname_upper}_ROOT} $ENV{${pkgname_upper}_ROOT} ${CMAKE_PREFIX_PATH}) - - # build lists of required versions and components - unset(__required_versions__) - unset(__components__) - if(ARGS_VERSION) - list(APPEND __required_versions__ ${ARGS_VERSION}) - endif() - if(ARGS_COMPONENTS) - list(APPEND __components__ ${ARGS_COMPONENTS}) - endif() - if(ARGS_ADD_REQUIREMENTS_OF) - foreach(dep_pkgname IN LISTS ARGS_ADD_REQUIREMENTS_OF) - if(${dep_pkgname}_${pkgname}_VERSION) - list(APPEND __required_versions__ ${${dep_pkgname}_${pkgname}_VERSION}) - endif() - if(${dep_pkgname}_${pkgname}_COMPONENTS) - list(APPEND __components__ ${${dep_pkgname}_${pkgname}_COMPONENTS}) - endif() - endforeach() - endif() - - # select highest required version - unset(__version__) - if(__required_versions__) - list(GET __required_versions__ 0 __version__) - foreach(v IN LISTS __required_versions__) - if(${v} VERSION_GREATER ${__version__}) - set(__version__ ${v}) - endif() - endforeach() - endif() - # deduplicate required component list - if(__components__) - list(REMOVE_DUPLICATES __components__) - endif() - - # call native find_package - if(__components__) - find_package(${pkgname} ${__version__} QUIET COMPONENTS ${__components__} ${ARGS_UNPARSED_ARGUMENTS}) - else() - find_package(${pkgname} ${__version__} QUIET ${ARGS_UNPARSED_ARGUMENTS}) - endif() - - if(${qualifier} STREQUAL BUNDLED) - if(${pkgname}_BUNDLED) - set(__qualifier__ PRIVATE) - else() - set(__qualifier__ PUBLIC) - endif() - else() - set(__qualifier__ ${qualifier}) - endif() - - if(${pkgname}_FOUND) - if(${__qualifier__} STREQUAL PRIVATE) - set(PROJECT_${pkgname}_VERSION ${__version__}) - set(PROJECT_${pkgname}_COMPONENTS ${__components__}) - set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname}) - elseif(${__qualifier__} STREQUAL PUBLIC) - set(PROJECT_${pkgname}_VERSION ${__version__}) - set(PROJECT_${pkgname}_COMPONENTS ${__components__}) - set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname}) - set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__}) - set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${__components__}) - set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname}) - elseif(${__qualifier__} STREQUAL INTERFACE) - set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__}) - set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${__components__}) - set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname}) - endif() - endif() - - unset(__qualifier__) - unset(__version__) - unset(__components__) - unset(__required_versions__) - set(CMAKE_PREFIX_PATH ${__old_cpp__}) - unset(__old_cpp__) -endmacro() - -macro(exec cmd) - join("${ARGN}" " " args) - file(APPEND ${${package}_BUILD_LOGFILE} ">>> ${cmd} ${args}\n") - - execute_process(COMMAND ${cmd} ${ARGN} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - OUTPUT_VARIABLE log - ERROR_VARIABLE log - RESULT_VARIABLE res - ) - file(APPEND ${${package}_BUILD_LOGFILE} ${log}) - - if(res) - message(FATAL_ERROR "${res} \nSee also \"${${package}_BUILD_LOGFILE}\"") - endif() -endmacro() - -macro(exec_source cmd) - join("${ARGN}" " " args) - file(APPEND ${${package}_BUILD_LOGFILE} ">>> ${cmd} ${args}\n") - - execute_process(COMMAND ${cmd} ${ARGN} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE log - ERROR_VARIABLE log - RESULT_VARIABLE res - ) - file(APPEND ${${package}_BUILD_LOGFILE} ${log}) - - if(res) - message(FATAL_ERROR "${res} \nSee also \"${${package}_BUILD_LOGFILE}\"") - endif() -endmacro() - -function(build_bundled package bundle) - message(STATUS "Building bundled ${package}") - - set(${package}_SOURCE_DIR ${CMAKE_SOURCE_DIR}/${bundle}) - set(${package}_BINARY_DIR ${CMAKE_BINARY_DIR}/${bundle}) - file(MAKE_DIRECTORY ${${package}_BINARY_DIR}) - set(${package}_BUILD_LOGFILE ${${package}_BINARY_DIR}/build.log) - file(REMOVE ${${package}_BUILD_LOGFILE}) - - if(Git_FOUND) - exec_source(${GIT_EXECUTABLE} submodule update --init -- ${${package}_SOURCE_DIR}) - endif() - - if(${package} STREQUAL GTest) - set(${package}_INSTALL_DIR ${CMAKE_BINARY_DIR}/${bundle}_install) - file(MAKE_DIRECTORY ${${package}_INSTALL_DIR}) - set(${package}_ROOT ${${package}_INSTALL_DIR}) - - exec(${CMAKE_COMMAND} -S ${${package}_SOURCE_DIR} -B ${${package}_BINARY_DIR} -G ${CMAKE_GENERATOR} - -DCMAKE_INSTALL_PREFIX=${${package}_INSTALL_DIR} -DBUILD_GMOCK=OFF - ) - exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR}) - exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR} --target install) - elseif(${package} STREQUAL asio) - set(${package}_INSTALL_DIR ${CMAKE_BINARY_DIR}/${bundle}_install) - file(MAKE_DIRECTORY ${${package}_INSTALL_DIR}) - set(${package}_ROOT ${${package}_INSTALL_DIR}) - - exec(${CMAKE_COMMAND} -S ${${package}_SOURCE_DIR} -B ${${package}_BINARY_DIR} -G ${CMAKE_GENERATOR} - -DCMAKE_INSTALL_PREFIX=${${package}_INSTALL_DIR} - ) - exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR}) - exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR} --target install) - elseif(${package} STREQUAL PicoSHA2) - set(${package}_ROOT ${${package}_SOURCE_DIR}) - endif() - - string(TOUPPER ${package} package_upper) - set(${package_upper}_ROOT "${${package}_ROOT}" CACHE PATH "Bundled ${package} install prefix search hint") - set(${package}_BUNDLED ON CACHE BOOL "Whether bundled ${package} was used") - - message(STATUS "Building bundled ${package} - done") -endfunction() macro(fairmq_build_option option description) cmake_parse_arguments(ARGS "" "DEFAULT" "REQUIRES" ${ARGN}) @@ -561,3 +325,65 @@ macro(fairmq_build_option option description) set(option) set(description) endmacro() + + +macro(set_package_infos) + if(PROJECT_PACKAGE_DEPENDENCIES) + foreach(dep IN LISTS PROJECT_PACKAGE_DEPENDENCIES) + string(TOUPPER ${dep} dep_upper) + if(${dep}_BUNDLED) + set(${dep}_PREFIX "") + elseif(${dep} STREQUAL FairLogger) + if(NOT FairLogger_PREFIX AND FairLogger_ROOT) + set(FairLogger_PREFIX ${FairLogger_ROOT}) + endif() + elseif(${dep} STREQUAL asiofi) + if(NOT asiofi_PREFIX AND asiofi_ROOT) + set(asiofi_PREFIX ${asiofi_ROOT}) + endif() + elseif(${dep} STREQUAL DDS) + set(DDS_PREFIX "${DDS_INSTALL_PREFIX}") + elseif(${dep} STREQUAL Boost) + if(TARGET Boost::headers) + get_target_property(boost_include Boost::headers INTERFACE_INCLUDE_DIRECTORIES) + else() + get_target_property(boost_include Boost::boost INTERFACE_INCLUDE_DIRECTORIES) + endif() + get_filename_component(Boost_PREFIX ${boost_include}/.. ABSOLUTE) + unset(boost_include) + elseif(${dep} STREQUAL Doxygen) + get_target_property(doxygen_bin Doxygen::doxygen INTERFACE_LOCATION) + get_filename_component(Doxygen_PREFIX ${doxygen_bin} DIRECTORY) + get_filename_component(Doxygen_PREFIX ${Doxygen_PREFIX}/.. ABSOLUTE) + unset(doxygen_bin) + elseif(${dep} STREQUAL Flatbuffers) + if(TARGET flatbuffers::flatbuffers) + get_target_property(flatbuffers_include flatbuffers::flatbuffers INTERFACE_INCLUDE_DIRECTORIES) + else() + get_target_property(flatbuffers_include flatbuffers::flatbuffers_shared INTERFACE_INCLUDE_DIRECTORIES) + endif() + get_filename_component(Flatbuffers_PREFIX ${flatbuffers_include}/.. ABSOLUTE) + unset(flatbuffers_include) + elseif(NOT ${dep}_PREFIX) + # try to guess + if(TARGET ${dep}::${dep}) + get_target_property(${dep}_include ${dep}::${dep} INTERFACE_INCLUDE_DIRECTORIES) + get_filename_component(${dep}_PREFIX ${${dep}_include}/.. ABSOLUTE) + unset(${dep}_include) + elseif(${dep}_INCLUDE_DIR) + get_filename_component(${dep}_PREFIX ${${dep}_INCLUDE_DIR}/.. ABSOLUTE) + elseif(${dep_upper}_INCLUDE_DIR) + get_filename_component(${dep}_PREFIX ${${dep_upper}_INCLUDE_DIR}/.. ABSOLUTE) + elseif(${dep}_INCLUDE_DIRS) + list(GET ${dep}_INCLUDE_DIRS 0 ${dep}_include) + get_filename_component(${dep}_PREFIX ${${dep}_include}/.. ABSOLUTE) + unset(${dep}_include) + elseif(${dep_upper}_INCLUDE_DIRS) + list(GET ${dep_upper}_INCLUDE_DIRS 0 ${dep}_include) + get_filename_component(${dep}_PREFIX ${${dep}_include}/.. ABSOLUTE) + unset(${dep}_include) + endif() + endif() + endforeach() + endif() +endmacro() diff --git a/extern/FairCMakeModules b/extern/FairCMakeModules new file mode 160000 index 00000000..ceecfbad --- /dev/null +++ b/extern/FairCMakeModules @@ -0,0 +1 @@ +Subproject commit ceecfbad90c9dbdb876a4562403280a7c63163f3