diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..378eac25 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..6162d13f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,70 @@ +################################################################################ +# Copyright (C) 2018 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" # +################################################################################ + +cmake_minimum_required(VERSION 3.9.4 FATAL_ERROR) + + +# Project ###################################################################### +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) +include(FairMQLib) + +set_fairmq_cmake_policies() +get_git_version(OUTVAR_PREFIX FairMQ) + +project(FairMQ VERSION ${FairMQ_VERSION} LANGUAGES CXX) +message("${BWhite}${PROJECT_NAME}${CR} ${FairMQ_GIT_VERSION} from ${FairMQ_DATE}") + +set_fairmq_defaults() +################################################################################ + + +# Build options ################################################################ +option(BUILD_OFI_TRANSPORT "Build OFI transport." OFF) +################################################################################ + + +# Dependencies ################################################################# +if(Boost_INCLUDE_DIR) # Silence output, if Boost was found already + set(SILENCE_BOOST QUIET) +endif() +find_package(Boost 1.64 ${SILENCE_BOOST} REQUIRED COMPONENTS system) + +if(BUILD_OFI_TRANSPORT) + find_package(OFI 1.6.0 REQUIRED COMPONENTS fi_sockets) +endif() +################################################################################ + + +# Targets ###################################################################### +# Configure Version.hpp +configure_file(${PROJECT_NAME_LOWER}/Version.h.in + ${CMAKE_BINARY_DIR}/${PROJECT_NAME_LOWER}/Version.h + @ONLY +) + +add_subdirectory(fairmq) +################################################################################ + + +# Installation ################################################################# +install_fairmq_cmake_package() +################################################################################ + + +# Summary ###################################################################### +message(" ") +message(" ${Cyan}COMPONENT BUILT? INFO${CR}") +message(" ${BWhite}library${CR} ${BGreen}YES${CR} (default, always built)") +if(BUILD_OFI_TRANSPORT) + set(ofi_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_OFI_TRANSPORT=OFF${CR})") +else() + set(ofi_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_OFI_TRANSPORT=ON${CR})") +endif() +message(" ${BWhite}OFI transport${CR} ${ofi_summary}") +message(" ") +################################################################################ diff --git a/README.md b/README.md index 5de37c59..8701fe42 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,42 @@ cmake -DCMAKE_INSTALL_PREFIX=./fairmq_install ../fairmq cmake --build . --target install ``` -# Documentation +## Usage + +In your `CMakeLists.txt`: + +```cmake +find_package(FairMQ) +``` + +If FairMQ is not installed in system directories, you can hint the installation: + +```cmake +set(CMAKE_PREFIX_PATH /path/to/FairMQ/installation ${CMAKE_PREFIX_PATH}) +find_package(FairMQ) +``` + +`find_package(FairMQ)` will define an imported target `FairMQ::FairMQ` (An alias `FairRoot::FairMQ` is also defined, but it is deprecated). + +By default, `find_package(FairMQ)` will also invoke `find_package` commands for all its dependencies. You can override this behaviour though, e.g.: + +```cmake +set(FairMQ_PACKAGE_DEPENDENCIES_DISABLED ON) +find_package(FairMQ) + +find_package(Boost COMPONENTS ${FairMQ_BOOST_COMPONENTS}) +find_package(ZeroMQ) +# ... +``` + +The above allows you to customize the `find_package` calls in the case, you project also has a direct dependency to FairMQ's dependencies. Check the next section for more options on how to customize dependency discovery. + +## CMake options + + * `-DDISABLE_COLOR=ON` disables coloured console output. + * `-DFairMQ_PACKAGE_DEPENDENCIES_DISABLED=ON` disables transitive package dependency discovery. + +## Documentation Standard [FairRoot](https://github.com/FairRootGroup/FairRoot) is running all the different analysis tasks within one process. FairMQ ([Message Queue](http://en.wikipedia.org/wiki/Message_queue)) allows starting tasks on different processes and provides the communication layer between these processes. diff --git a/cmake/FairMQConfig.cmake.in b/cmake/FairMQConfig.cmake.in new file mode 100644 index 00000000..fcaac6d6 --- /dev/null +++ b/cmake/FairMQConfig.cmake.in @@ -0,0 +1,65 @@ +################################################################################ +# Copyright (C) 2018 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" # +################################################################################ + +cmake_minimum_required(VERSION 3.9.4 FATAL_ERROR) + +@PACKAGE_INIT@ + +### General variables for project discovery/inspection +set(FAIRMQ_VERSION @PROJECT_VERSION@) +set(FAIRMQ_GIT_VERSION @FAIRMQ_GIT_VERSION@) + +set_and_check(FairMQ_ROOT @PACKAGE_CMAKE_INSTALL_PREFIX@) +set_and_check(FairMQ_BINDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@FairMQ_INSTALL_BINDIR@) +set_and_check(FairMQ_INCDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@FairMQ_INSTALL_INCDIR@) +set_and_check(FairMQ_LIBDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@FairMQ_INSTALL_LIBDIR@) +set_and_check(FairMQ_DATADIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@FairMQ_INSTALL_DATADIR@) +set_and_check(FairMQ_CMAKEMODDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@FairMQ_INSTALL_CMAKEMODDIR@) + +### Import cmake modules +set(CMAKE_MODULE_PATH ${FairMQ_CMAKEMODDIR} ${CMAKE_MODULE_PATH}) + +### Package dependencies +include(CMakeFindDependencyMacro) + +if( NOT (FairMQ_BOOST_DISABLED OR FairMQ_PACKAGE_DEPENDENCIES_DISABLED) + AND (@Boost_FOUND@ OR FairMQ_Boost_REQUIRED)) + set(FairMQ_Boost_COMPONENTS system) + if(FairMQ_ADDITIONAL_Boost_COMPONENTS) + list(APPEND FairMQ_Boost_COMPONENTS ${FairMQ_ADDITIONAL_Boost_COMPONENTS}) + list(REMOVE_DUPLICATES FairMQ_Boost_COMPONENTS) + endif() + if(Boost_INCLUDE_DIR) # checks for cached boost variable which indicates if Boost is already found + set(SILENCE_BOOST QUIET) + endif() + find_dependency(Boost 1.64 ${SILENCE_BOOST} + COMPONENTS ${FairMQ_Boost_COMPONENTS} + ) +endif() + +if( NOT (FairMQ_OFI_DISABLED OR FairMQ_PACKAGE_DEPENDENCIES_DISABLED) + AND (@OFI_FOUND@ OR FairMQ_OFI_REQUIRED)) + set(FairMQ_OFI_COMPONENTS fi_sockets) + if(FairMQ_ADDITIONAL_OFI_COMPONENTS) + list(APPEND FairMQ_OFI_COMPONENTS ${FairMQ_ADDITIONAL_OFI_COMPONENTS}) + list(REMOVE_DUPLICATES FairMQ_OFI_COMPONENTS) + endif() + find_dependency(OFI 1.6.0 + COMPONENTS ${FairMQ_OFI_COMPONENTS} + ) +endif() + +### Import targets +include(@PACKAGE_CMAKE_INSTALL_PREFIX@/@PACKAGE_INSTALL_DESTINATION@/FairMQTargets.cmake) + +### Alias target for backwards compat (DEPRECATED) +if(NOT TARGET FairRoot::FairMQ) + add_library(FairRoot::FairMQ ALIAS FairMQ::FairMQ) +endif() + +check_required_components(FairMQ) diff --git a/cmake/FairMQLib.cmake b/cmake/FairMQLib.cmake new file mode 100644 index 00000000..de02b832 --- /dev/null +++ b/cmake/FairMQLib.cmake @@ -0,0 +1,172 @@ +################################################################################ +# Copyright (C) 2018 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" # +################################################################################ + +### 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() + +# set_fairmq_cmake_policies() +# +# Sets CMake policies. +macro(set_fairmq_cmake_policies) + # Find more details to each policy with cmake --help-policy CMPXXXX + foreach(policy + CMP0028 # Double colon in target name means ALIAS or IMPORTED target. + CMP0048 # The ``project()`` command manages VERSION variables. + CMP0054 # Only interpret ``if()`` arguments as variables or keywords when unquoted. + ) + if(POLICY ${policy}) + cmake_policy(SET ${policy} NEW) + endif() + endforeach() +endmacro() + + +find_package(Git) +# get_git_version([DEFAULT_VERSION version] [DEFAULT_DATE date] [OUTVAR_PREFIX prefix]) +# +# Sets variables #prefix#_VERSION, #prefix#_GIT_VERSION, #prefix#_DATE, #prefix#_GIT_DATE +function(get_git_version) + cmake_parse_arguments(ARGS "" "DEFAULT_VERSION;DEFAULT_DATE;OUTVAR_PREFIX" "" ${ARGN}) + + if(NOT ARGS_OUTVAR_PREFIX) + set(ARGS_OUTVAR_PREFIX FairMQ) + endif() + + if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git) + execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --dirty --match "v*" + OUTPUT_VARIABLE ${ARGS_OUTVAR_PREFIX}_GIT_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + if(${ARGS_OUTVAR_PREFIX}_GIT_VERSION) + # cut first two characters "v-" + string(SUBSTRING ${${ARGS_OUTVAR_PREFIX}_GIT_VERSION} 1 -1 ${ARGS_OUTVAR_PREFIX}_GIT_VERSION) + endif() + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%cd + OUTPUT_VARIABLE ${ARGS_OUTVAR_PREFIX}_GIT_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + endif() + + if(NOT ${ARGS_OUTVAR_PREFIX}_GIT_VERSION) + if(ARGS_DEFAULT_VERSION) + set(${ARGS_OUTVAR_PREFIX}_GIT_VERSION ${ARGS_DEFAULT_VERSION}) + else() + set(${ARGS_OUTVAR_PREFIX}_GIT_VERSION 0.0.0.0) + endif() + endif() + + if(NOT ${ARGS_OUTVAR_PREFIX}_GIT_DATE) + if(ARGS_DEFAULT_DATE) + set(${ARGS_OUTVAR_PREFIX}_GIT_DATE ${ARGS_DEFAULT_DATE}) + else() + set(${ARGS_OUTVAR_PREFIX}_GIT_DATE "Thu Jan 1 00:00:00 1970 +0000") + endif() + endif() + + string(REGEX MATCH "^([^-]*)" blubb ${${ARGS_OUTVAR_PREFIX}_GIT_VERSION}) + + # return values + set(${ARGS_OUTVAR_PREFIX}_VERSION ${CMAKE_MATCH_0} PARENT_SCOPE) + set(${ARGS_OUTVAR_PREFIX}_DATE ${${ARGS_OUTVAR_PREFIX}_GIT_DATE} PARENT_SCOPE) + set(${ARGS_OUTVAR_PREFIX}_GIT_VERSION ${${ARGS_OUTVAR_PREFIX}_GIT_VERSION} PARENT_SCOPE) + set(${ARGS_OUTVAR_PREFIX}_GIT_DATE ${${ARGS_OUTVAR_PREFIX}_GIT_DATE} PARENT_SCOPE) +endfunction() + + +# Set defaults +macro(set_fairmq_defaults) + string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER) + + # Set a default build type + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE RelWithDebInfo) + endif() + + # Handle C++ standard level + set(CMAKE_CXX_STANDARD_REQUIRED ON) + if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) + elseif(${CMAKE_CXX_STANDARD} LESS 11) + message(FATAL_ERROR "A minimum CMAKE_CXX_STANDARD of 11 is required.") + endif() + if(NOT CMAKE_CXX_EXTENSIONS) + set(CMAKE_CXX_EXTENSIONS OFF) + endif() + + # Generate compile_commands.json file (https://clang.llvm.org/docs/JSONCompilationDatabase.html) + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + + # Define CMAKE_INSTALL_*DIR family of variables + include(GNUInstallDirs) + + # Define install dirs + set(FairMQ_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR}) + set(FairMQ_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME_LOWER}) + set(FairMQ_INSTALL_INCDIR ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME_LOWER}) + set(FairMQ_INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME_LOWER}) + set(FairMQ_INSTALL_CMAKEMODDIR ${FairMQ_INSTALL_DATADIR}/cmake) + + # Define export set, only one for now + set(FairMQ_EXPORT_SET ${PROJECT_NAME}Targets) +endmacro() + + +# Configure/Install CMake package +macro(install_fairmq_cmake_package) + # Install cmake modules + install( FILES cmake/FindOFI.cmake + DESTINATION ${FairMQ_INSTALL_CMAKEMODDIR} + ) + + include(CMakePackageConfigHelpers) + set(PACKAGE_INSTALL_DESTINATION + ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION} + ) + install(EXPORT ${FairMQ_EXPORT_SET} + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${PACKAGE_INSTALL_DESTINATION} + EXPORT_LINK_INTERFACE_LIBRARIES + ) + write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + COMPATIBILITY AnyNewerVersion + ) + configure_package_config_file( + ${CMAKE_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION ${PACKAGE_INSTALL_DESTINATION} + PATH_VARS CMAKE_INSTALL_PREFIX + ) + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${PACKAGE_INSTALL_DESTINATION} + ) +endmacro() diff --git a/cmake/FindOFI.cmake b/cmake/FindOFI.cmake new file mode 100644 index 00000000..652089ac --- /dev/null +++ b/cmake/FindOFI.cmake @@ -0,0 +1,89 @@ +################################################################################ +# Copyright (C) 2018 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" # +################################################################################ + +# According to the docs the modification of the PKG_CONFIG_PATH environment should +# not be necessary, but it does not work otherwise. +if(OFI_ROOT) + list(APPEND CMAKE_PREFIX_PATH "${OFI_ROOT}/lib/pkgconfig") + set(ENV{PKG_CONFIG_PATH} "${OFI_ROOT}/lib/pkgconfig:" $ENV{PKG_CONFIG_PATH}) +endif() + +if(ENV{OFI_ROOT}) + list(APPEND CMAKE_PREFIX_PATH "$ENV{OFI_ROOT}/lib/pkgconfig") + set(ENV{PKG_CONFIG_PATH} "$ENV{OFI_ROOT}/lib/pkgconfig:" $ENV{PKG_CONFIG_PATH}) +endif() + +# This should be the default as of CMake 3.1, but it is not set. BUG? Also, it does not work +set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH 1) +find_package(PkgConfig) + +if(PKG_CONFIG_FOUND) + # Find include dir and dependencies from pkgconfig + pkg_check_modules(_OFI libfabric QUIET) + + # Retrieve version from pkgconfig + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} libfabric --modversion + OUTPUT_VARIABLE OFI_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # The IMPORTED_TARGET option of the pkg_check_modules() function is useless, + # so let's build it ourselves + find_library(OFI_LIBFABRIC + NAMES libfabric.so libfabric.dylib + HINTS ${OFI_ROOT} $ENV{OFI_ROOT} + PATH_SUFFIXES lib + ) + + # Just take the include dirs found by the PkgConfig module + set(OFI_INCLUDE_DIRS ${_OFI_INCLUDE_DIRS}) + + # Find fi_info command to be able to check required features of the OFI installation + find_program(OFI_INFO_EXECUTABLE + NAMES fi_info + HINTS ${OFI_ROOT} $ENV{OFI_ROOT} + PATH_SUFFIXES bin + ) + + # Detect ofi providers, they can be required via the COMPONENTS argument of find_package + if(OFI_INFO_EXECUTABLE) + execute_process( + COMMAND ${OFI_INFO_EXECUTABLE} -l + OUTPUT_VARIABLE output + ) + string(REPLACE "\n" ";" lines ${output}) + foreach(line IN LISTS lines) + string(REGEX + MATCH "^([a-zA-Z0-9_]+):" + found "${line}" + ) + if(found) + string(TOLOWER "${CMAKE_MATCH_1}" provider) + set(OFI_fi_${provider}_FOUND TRUE) + endif() + endforeach() + endif() + + # Check search result, check version constraints and print status + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(OFI + REQUIRED_VARS OFI_LIBFABRIC OFI_INCLUDE_DIRS OFI_INFO_EXECUTABLE + VERSION_VAR OFI_VERSION + HANDLE_COMPONENTS + ) +endif() + +if(OFI_FOUND) + # Define an imported target + add_library(OFI::libfabric SHARED IMPORTED GLOBAL) + set_target_properties(OFI::libfabric PROPERTIES + IMPORTED_LOCATION ${OFI_LIBFABRIC} + INTERFACE_INCLUDE_DIRECTORIES ${OFI_INCLUDE_DIRS} + ) +endif() diff --git a/fairmq/Version.h.in b/fairmq/Version.h.in new file mode 100644 index 00000000..7e07f861 --- /dev/null +++ b/fairmq/Version.h.in @@ -0,0 +1,20 @@ +/******************************************************************************** + * Copyright (C) 2018 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" * + ********************************************************************************/ + +#ifndef FAIR_MQ_VERSION_H + +#define FAIRMQ_VERSION "@PROJECT_VERSION@" +#define FAIRMQ_VERSION_DEC (@PROJECT_VERSION_MAJOR@ * 10000) + (@PROJECT_VERSION_MINOR@ * 100) + @PROJECT_VERSION_PATCH@ +#define FAIRMQ_VERSION_HEX (@PROJECT_VERSION_MAJOR@ << 16) + (@PROJECT_VERSION_MINOR@ << 8) + @PROJECT_VERSION_PATCH@ +#define FAIRMQ_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define FAIRMQ_VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define FAIRMQ_VERSION_PATCH @PROJECT_VERSION_PATCH@ +#define FAIRMQ_GIT_VERSION "@FairMQ_GIT_VERSION@" +#define FAIRMQ_GIT_DATE "@FairMQ_GIT_DATE@" + +#endif // FAIR_MQ_VERSION_H