Compare commits

..

No commits in common. "master" and "v1.4.31" have entirely different histories.

424 changed files with 25030 additions and 13786 deletions

View File

@ -1,3 +1,3 @@
---
Checks: 'cppcoreguidelines-*,misc-unused-alias-decls,misc-unused-parameters,modernize-pass-by-value,modernize-deprecated-headers,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-using,performance-faster-string-find,performance-for-range-copy,performance-unnecessary-copy-initialization,readability-avoid-const-params-in-decls,readability-braces-around-statements,readability-container-size-empty,readability-delete-null-pointer,readability-redundant-member-init,readability-redundant-string-init,readability-static-accessed-through-instance,readability-string-compare'
Checks: '*,-google-*,-fuchsia-*,-cert-*,-llvm-header-guard,-readability-named-parameter,-misc-non-private-member-variables-in-classes,-*-magic-numbers,-llvm-include-order,-hicpp-no-array-decay,-performance-unnecessary-value-param,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-modernize-use-trailing-return-type,-readability-redundant-member-init'
HeaderFilterRegex: '/(fairmq/)'

3
.codecov.yml Normal file
View File

@ -0,0 +1,3 @@
comment:
layout: "diff, files"
behavior: once

View File

@ -1,5 +0,0 @@
{
"image": "ghcr.io/fairrootgroup/fairmq-dev/fedora-38:latest",
"features": {
}
}

View File

@ -1,12 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "dev"
schedule:
interval: "monthly"
- package-ecosystem: "gitsubmodule"
directory: "/"
target-branch: "dev"
schedule:
interval: "monthly"

View File

@ -1,29 +0,0 @@
# SPDX-FileCopyrightText: 2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH, Darmstadt, Germany
#
# SPDX-License-Identifier: CC0-1.0
name: Check AUTHORS and CONTRIBUTORS in metadata
on:
push:
paths:
- AUTHORS
- CONTRIBUTORS
- codemeta.json
- .zenodo.json
pull_request:
paths:
- AUTHORS
- CONTRIBUTORS
- codemeta.json
- .zenodo.json
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Try updating metadata
run: python meta_update.py
- name: Check for Updates
run: git diff --exit-code

View File

@ -1,21 +0,0 @@
name: validate codemeta
on:
push:
paths:
- codemeta.json
- .github/workflows/codemeta_validate.yaml
pull_request:
paths:
- codemeta.json
- .github/workflows/codemeta_validate.yaml
jobs:
build:
runs-on: ubuntu-latest
container:
image: gitlab-registry.in2p3.fr/escape2020/wp3/eossr:v1.0
steps:
- uses: actions/checkout@v4
- name: validate codemeta
run: eossr-metadata-validator codemeta.json

View File

@ -1,16 +0,0 @@
name: fair-software
on: push
jobs:
verify:
name: "fair-software"
runs-on: ubuntu-latest
if: github.repository == 'FairRootGroup/FairMQ'
steps:
- uses: fair-software/howfairis-github-action@0.2.1
name: Measure compliance with fair-software.eu recommendations
env:
PYCHARM_HOSTED: "Trick colorama into displaying colored output"
with:
MY_REPO_URL: "https://github.com/${{ github.repository }}"

7
.gitignore vendored
View File

@ -1,8 +1,5 @@
build
install
.DS_Store
.vscode
/compile_commands.json
.cache
.spack-env
spack.lock

View File

@ -1,14 +0,0 @@
[general]
ignore=body-is-missing
contrib=contrib-title-conventional-commits
ignore-merge-commits=false
ignore-revert-commits=false
ignore-fixup-commits=false
ignore-squash-commits=false
[title-max-length]
line-length=75
[contrib-title-conventional-commits]
types=fix,feat,build,ci,docs,style,refactor,perf,test

6
.gitmodules vendored
View File

@ -1,9 +1,9 @@
[submodule "extern/googletest"]
path = extern/googletest
url = https://github.com/google/googletest
[submodule "extern/asio"]
path = extern/asio
url = https://github.com/chriskohlhoff/asio
[submodule "extern/PicoSHA2"]
path = extern/PicoSHA2
url = https://github.com/okdshin/PicoSHA2
[submodule "extern/FairCMakeModules"]
path = extern/FairCMakeModules
url = https://github.com/FairRootGroup/FairCMakeModules

View File

@ -1,88 +0,0 @@
{
"creators": [
{
"orcid": "0000-0002-8071-4497",
"name": "Al-Turany, Mohammad"
},
{
"orcid": "0000-0003-3787-1910",
"name": "Klein, Dennis"
},
{
"name": "Kollegger, Thorsten"
},
{
"orcid": "0000-0002-6249-155X",
"name": "Rybalchenko, Alexey"
},
{
"name": "Winckler, Nicolas"
}
],
"contributors": [
{
"type": "Other",
"name": "Aphecetche, Laurent"
},
{
"type": "Other",
"name": "Binet, Sebastien"
},
{
"type": "Other",
"name": "Eulisse, Giulio"
},
{
"type": "Other",
"name": "Karabowicz, Radoslaw"
},
{
"type": "Other",
"name": "Kretz, Matthias"
},
{
"type": "Other",
"name": "Krzewicki, Mikolaj"
},
{
"type": "Other",
"name": "Lebedev, Andrey"
},
{
"type": "Other",
"name": "Mrnjavac, Teo"
},
{
"type": "Other",
"name": "Neskovic, Gvozden"
},
{
"type": "Other",
"name": "Richter, Matthias"
},
{
"type": "Other",
"orcid": "0000-0002-5321-8404",
"name": "Tacke, Christian"
},
{
"type": "Other",
"name": "Uhlig, Florian"
},
{
"type": "Other",
"name": "Wenzel, Sandro"
}
],
"description": "<p>C++ Message Queuing Library and Framework</p>",
"related_identifiers": [
{
"identifier": "https://github.com/FairRootGroup/FairMQ/",
"relation": "isSupplementTo",
"resource_type": "software",
"scheme": "url"
}
],
"title": "FairMQ",
"license": "LGPL-3.0-only"
}

View File

@ -1,5 +1,5 @@
Al-Turany, Mohammad [https://orcid.org/0000-0002-8071-4497]
Klein, Dennis [https://orcid.org/0000-0003-3787-1910]
Al-Turany, Mohammad
Klein, Dennis
Kollegger, Thorsten
Rybalchenko, Alexey [https://orcid.org/0000-0002-6249-155X]
Rybalchenko, Alexey
Winckler, Nicolas

View File

@ -1,37 +1,52 @@
################################################################################
# Copyright (C) 2018-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# 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.12 FATAL_ERROR)
cmake_policy(VERSION 3.12...3.15)
# Project ######################################################################
cmake_minimum_required(VERSION 3.15...3.30 FATAL_ERROR)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
include(FairMQLib)
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
include(GitHelper)
get_git_version()
project(FairMQ VERSION ${PROJECT_VERSION} LANGUAGES CXX)
include(FairMQProjectSettings)
message(STATUS "${BWhite}${PROJECT_NAME}${CR} ${PROJECT_GIT_VERSION} from ${PROJECT_DATE}")
set(PROJECT_MIN_CXX_STANDARD 17)
set_fairmq_defaults()
include(CTest)
################################################################################
# Build options ################################################################
include(FairMQBuildOption)
fairmq_build_option(BUILD_FAIRMQ "Build FairMQ library and devices."
DEFAULT ON)
fairmq_build_option(BUILD_TESTING "Build tests."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_OFI_TRANSPORT "Build experimental OFI transport."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_SDK_COMMANDS "Build the FairMQ SDK commands."
DEFAULT OFF)
fairmq_build_option(BUILD_DDS_PLUGIN "Build DDS plugin."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_PMIX_PLUGIN "Build PMIx plugin."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
DEFAULT ON REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_TIDY_TOOL "Build the fairmq-tidy tool."
DEFAULT OFF)
fairmq_build_option(BUILD_SDK "Build the FairMQ controller SDK."
DEFAULT OFF REQUIRES "BUILD_DDS_PLUGIN;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
DEFAULT OFF)
fairmq_build_option(FAST_BUILD "Fast production build. Not recommended for development."
DEFAULT OFF)
fairmq_build_option(USE_EXTERNAL_GTEST "Do not use bundled GTest. Not recommended."
DEFAULT OFF)
fairmq_build_option(FAIRMQ_DEBUG_MODE "Compile in debug mode (may decrease performance)."
@ -40,13 +55,121 @@ fairmq_build_option(FAIRMQ_DEBUG_MODE "Compile in debug mode (may decrease per
# Dependencies #################################################################
include(CTest)
include(FairMQDependencies)
if(FAST_BUILD)
include(cotire)
endif()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
if(BUILD_OFI_TRANSPORT)
find_package2(PRIVATE asiofi REQUIRED
VERSION 0.3.1
)
find_package2(PRIVATE OFI REQUIRED
ADD_REQUIREMENTS_OF asiofi
)
endif()
if(BUILD_SDK_COMMANDS)
find_package2(PRIVATE Flatbuffers REQUIRED)
endif()
if(BUILD_DDS_PLUGIN OR BUILD_SDK)
find_package2(PRIVATE DDS REQUIRED
VERSION 3.5.3
)
set(DDS_Boost_COMPONENTS system log log_setup regex filesystem thread)
set(DDS_Boost_VERSION 1.67)
endif()
if(BUILD_PMIX_PLUGIN)
find_package2(PRIVATE PMIx REQUIRED
VERSION 2.1.4
)
endif()
if(BUILD_FAIRMQ OR BUILD_SDK)
find_package2(PUBLIC FairLogger REQUIRED
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
# BoostConfig lookup. This can be overridden on the command line via -DBoost_NO_BOOST_CMAKE=OFF
set(Boost_NO_BOOST_CMAKE ON)
endif()
find_package2(PUBLIC Boost REQUIRED
VERSION 1.66
COMPONENTS
container
program_options
filesystem
date_time
regex
ADD_REQUIREMENTS_OF
asiofi
DDS
FairLogger
)
# Normalize Boost version
if(CMAKE_VERSION VERSION_LESS 3.15)
set(Boost_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
endif()
endif()
if(BUILD_SDK)
find_package2(BUNDLED asio
VERSION 1.18.0
)
if(NOT asio_FOUND)
build_bundled(asio extern/asio)
find_package2(PRIVATE asio REQUIRED)
endif()
endif()
if(BUILD_FAIRMQ)
find_package2(PRIVATE ZeroMQ REQUIRED
VERSION 4.1.4
)
build_bundled(PicoSHA2 extern/PicoSHA2)
find_package2(PRIVATE PicoSHA2 REQUIRED)
endif()
if(BUILD_TESTING)
if(USE_EXTERNAL_GTEST)
find_package2(PRIVATE GTest VERSION 1.7.0)
endif()
if(NOT GTest_FOUND)
build_bundled(GTest extern/googletest)
find_package2(PRIVATE GTest REQUIRED)
endif()
endif()
if(BUILD_DOCS)
find_package2(PRIVATE Doxygen REQUIRED
VERSION 1.8.8
COMPONENTS dot
OPTIONAL_COMPONENTS mscgen dia
)
endif()
################################################################################
# Targets ######################################################################
if(BUILD_FAIRMQ)
if(BUILD_FAIRMQ OR BUILD_SDK)
add_subdirectory(fairmq)
endif()
@ -67,10 +190,6 @@ if(BUILD_DOCS)
doxygen_add_docs(doxygen README.md fairmq)
add_custom_target(docs ALL DEPENDS doxygen)
endif()
if(BUILD_TIDY_TOOL)
add_subdirectory(fairmq/tidy)
endif()
################################################################################
@ -81,14 +200,26 @@ endif()
if(BUILD_TESTING)
list(APPEND PROJECT_PACKAGE_COMPONENTS tests)
endif()
if(BUILD_DDS_PLUGIN)
list(APPEND PROJECT_PACKAGE_COMPONENTS dds_plugin)
endif()
if(BUILD_PMIX_PLUGIN)
list(APPEND PROJECT_PACKAGE_COMPONENTS pmix_plugin)
endif()
if(BUILD_OFI_TRANSPORT)
list(APPEND PROJECT_PACKAGE_COMPONENTS ofi_transport)
endif()
if(BUILD_EXAMPLES)
list(APPEND PROJECT_PACKAGE_COMPONENTS examples)
endif()
if(BUILD_DOCS)
list(APPEND PROJECT_PACKAGE_COMPONENTS docs)
endif()
if(BUILD_TIDY_TOOL)
list(APPEND PROJECT_PACKAGE_COMPONENTS tidy_tool)
if(BUILD_SDK)
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk)
endif()
if(BUILD_SDK_COMMANDS)
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk_commands)
endif()
################################################################################
@ -104,28 +235,202 @@ if(BUILD_DOCS)
DESTINATION ${PROJECT_INSTALL_DATADIR}/docs
)
endif()
if(BUILD_TIDY_TOOL)
install(FILES cmake/FairMQTidy.cmake
if(BUILD_SDK)
install(FILES cmake/Findasio.cmake
DESTINATION ${PROJECT_INSTALL_CMAKEMODDIR}
)
if(asio_BUNDLED)
install(TARGETS bundled_asio_headers EXPORT ${PROJECT_EXPORT_SET})
install(DIRECTORY "${asio_BUILD_INCLUDE_DIR}/asio"
DESTINATION ${asio_INSTALL_INCLUDE_DIR}
PATTERN "Makefile.am" EXCLUDE
PATTERN ".gitignore" EXCLUDE
)
install(FILES "${asio_BUILD_INCLUDE_DIR}/asio.hpp"
DESTINATION ${asio_INSTALL_INCLUDE_DIR}
)
endif()
endif()
include(FairMQPackage)
install_cmake_package()
################################################################################
# Summary ######################################################################
include(FairMQSummary)
message(STATUS "${BWhite}${PROJECT_NAME}${CR} ${PROJECT_GIT_VERSION} from ${PROJECT_DATE}")
fair_summary_global_cxx_flags_standard()
fair_summary_build_types()
fair_summary_package_dependencies()
fairmq_summary_components()
fairmq_summary_static_analysis()
fairmq_summary_install_prefix()
fairmq_summary_debug_mode()
fairmq_summary_compile_definitions()
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()
get_filename_component(prefix ${${dep}_INCLUDE_DIR}/.. ABSOLUTE)
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()
message(STATUS " ")
message(STATUS " ${Cyan}COMPONENT BUILT? INFO${CR}")
if(BUILD_FAIRMQ)
set(fairmq_summary "${BGreen}YES${CR} (default, disable with ${BMagenta}-DBUILD_FAIRMQ=OFF${CR})")
else()
set(fairmq_summary "${BRed} NO${CR} (enable with ${BMagenta}-DBUILD_FAIRMQ=ON${CR})")
endif()
message(STATUS " ${BWhite}fairmq${CR} ${fairmq_summary}")
if(BUILD_TESTING)
set(tests_summary "${BGreen}YES${CR} (default, disable with ${BMagenta}-DBUILD_TESTING=OFF${CR})")
else()
set(tests_summary "${BRed} NO${CR} (enable with ${BMagenta}-DBUILD_TESTING=ON${CR})")
endif()
message(STATUS " ${BWhite}tests${CR} ${tests_summary}")
if(BUILD_OFI_TRANSPORT)
set(ofi_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_OFI_TRANSPORT=OFF${CR})")
else()
set(ofi_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_OFI_TRANSPORT=ON${CR})")
endif()
message(STATUS " ${BWhite}ofi_transport${CR} ${ofi_summary}")
if(BUILD_DDS_PLUGIN)
set(dds_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_DDS_PLUGIN=OFF${CR})")
else()
set(dds_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_DDS_PLUGIN=ON${CR})")
endif()
message(STATUS " ${BWhite}dds_plugin${CR} ${dds_summary}")
if(BUILD_PMIX_PLUGIN)
set(pmix_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_PMIX_PLUGIN=OFF${CR})")
else()
set(pmix_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_PMIX_PLUGIN=ON${CR})")
endif()
message(STATUS " ${BWhite}pmix_plugin${CR} ${pmix_summary}")
if(BUILD_EXAMPLES)
set(examples_summary "${BGreen}YES${CR} (default, disable with ${BMagenta}-DBUILD_EXAMPLES=OFF${CR})")
else()
set(examples_summary "${BRed} NO${CR} (enable with ${BMagenta}-DBUILD_EXAMPLES=ON${CR})")
endif()
message(STATUS " ${BWhite}examples${CR} ${examples_summary}")
if(BUILD_DOCS)
set(docs_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_DOCS=OFF${CR})")
else()
set(docs_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_DOCS=ON${CR})")
endif()
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
if(BUILD_SDK)
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
else()
set(sdk_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_SDK=ON${CR})")
endif()
message(STATUS " ${BWhite}sdk${CR} ${sdk_summary}")
if(BUILD_SDK_COMMANDS)
set(sdk_commands_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_SDK_COMMANDS=OFF${CR})")
else()
set(sdk_commands_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_SDK_COMMANDS=ON${CR})")
endif()
message(STATUS " ${BWhite}sdk_commands${CR} ${sdk_commands_summary}")
message(STATUS " ")
if(RUN_STATIC_ANALYSIS)
list(LENGTH PROJECT_STATIC_ANALYSERS size)
unset(analyser_list)
set(count 0)
foreach(analyser IN LISTS PROJECT_STATIC_ANALYSERS)
if(${analyser}_FOUND)
set(${analyser}_status "${analyser} ${BGreen}YES${CR}")
else()
set(${analyser}_status "${analyser} ${BRed}NO${CR}")
endif()
math(EXPR count "${count} + 1")
string(APPEND analyser_list "${${analyser}_status}")
if(count LESS size)
string(APPEND analyser_list "${BWhite},${CR} ")
endif()
endforeach()
set(static_ana_summary "${BWhite}(${CR}${analyser_list}${BWhite})${CR} (disable with ${BMagenta}-DRUN_STATIC_ANALYSIS=OFF${CR})")
else()
set(static_ana_summary "${BRed}OFF${CR} (default, enable with ${BMagenta}-DRUN_STATIC_ANALYSIS=ON${CR})")
endif()
message(STATUS " ${Cyan}INSTALL PREFIX${CR} ${BGreen}${CMAKE_INSTALL_PREFIX}${CR} (change with ${BMagenta}-DCMAKE_INSTALL_PREFIX=...${CR})")
message(STATUS " ")
message(STATUS " ${Cyan}RUN STATIC ANALYSIS ${static_ana_summary}")
message(STATUS " ")
if(FAIRMQ_DEBUG_MODE)
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BGreen}${FAIRMQ_DEBUG_MODE}${CR} (disable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=OFF${CR})")
else()
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BRed}${FAIRMQ_DEBUG_MODE}${CR} (enable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=ON${CR})")
endif()
message(STATUS " ")
################################################################################

View File

@ -3,11 +3,11 @@ Binet, Sebastien
Eulisse, Giulio
Karabowicz, Radoslaw
Kretz, Matthias <kretz@kde.org>
Krzewicki, Mikolaj
Krzewicki, Mikolaj
Lebedev, Andrey
Mrnjavac, Teo <teo.m@cern.ch>
Neskovic, Gvozden
Richter, Matthias
Tacke, Christian [https://orcid.org/0000-0002-5321-8404]
Tacke, Christian
Uhlig, Florian
Wenzel, Sandro

View File

@ -4,19 +4,23 @@ Upstream-Contact: Mohammad Al-Turany <m.al-turany@gsi.de>
Source: https://github.com/FairRootGroup/FairMQ
Files: *
Copyright: 2012-2022, GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
Copyright: 2012-2022, [see AUTHORS file]
Copyright: 2012-2022, [see CONTRIBUTORS file]
Copyright: 2012-2019, GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
Copyright: 2012-2019, [see AUTHORS file]
Copyright: 2012-2019, [see CONTRIBUTORS file]
Comment: The copyright of individual contributors is documented in the
Git history.
License: LGPL-3.0-only
Files: cmake/cotire.cmake
Copyright: 2012-2018 Sascha Kratky
License: COTIRE
Files: extern/googletest
Copyright: 2008-2022, Google Inc.
Copyright: 2008, Google Inc.
License: GOOGLE
Files: extern/asio
Copyright: 2003-2022, Christopher M. Kohlhoff (chris at kohlhoff dot com)
Copyright: 2003-2019, Christopher M. Kohlhoff (chris at kohlhoff dot com)
License: BSL-1.0
Files: extern/PicoSHA2
@ -26,6 +30,28 @@ License: MIT
License: LGPL-3.0-only
[see LICENSE file]
License: COTIRE
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
License: GOOGLE
Copyright 2008, Google Inc.
All rights reserved.

View File

@ -1,3 +1,9 @@
set(CTEST_PROJECT_NAME "FairMQ")
set(CTEST_NIGHTLY_START_TIME "00:00:00 CEST")
set(CTEST_SUBMIT_URL "https://cdash.gsi.de/submit.php?project=FairMQ")
set(CTEST_DROP_METHOD "https")
set(CTEST_DROP_SITE "cdash.gsi.de")
set(CTEST_DROP_LOCATION "/submit.php?project=FairMQ")
set(CTEST_DROP_SITE_CDASH TRUE)
set(CTEST_TESTING_TIMEOUT 60)

145
Dart.sh Executable file
View File

@ -0,0 +1,145 @@
#!/bin/bash
function print_example(){
echo "##################################################################"
echo "# To set the required parameters as source and the build #"
echo "# directory for ctest, the linux flavour and the SIMPATH #"
echo "# put the export commands below to a separate file which is read #"
echo "# during execution and which is defined on the command line. #"
echo "# Set all parameters according to your needs. #"
echo "# LINUX_FLAVOUR should be set to the distribution you are using #"
echo "# eg Debian, SuSe etc. #"
echo "# An additional varibale NCPU can overwrite the default number #"
echo "# of parallel processes used to compile the project. #"
echo "# This can be usefull if one can use a distributed build system #"
echo "# like icecream. #"
echo "# For example #"
echo "#!/bin/bash #"
echo "export LINUX_FLAVOUR=<your linux flavour> #"
echo "export FAIRSOFT_VERSION=<version of FairSoft> #"
echo "export SIMPATH=<path to your FairSoft version> #"
echo "export GIT_BRANCH=< master or dev> #"
echo "export BUILDDIR=<dir where the build files go> #"
echo "export SOURCEDIR=<location of the FairRoot sources> #"
echo "#export NCPU=100 #"
echo "##################################################################"
}
if [ "$#" -lt "2" ]; then
echo ""
echo "-- Error -- Please start script with two parameters"
echo "-- Error -- The first parameter is the ctest model."
echo "-- Error -- Possible arguments are Nightly, Experimental, "
echo "-- Error -- Continuous or Profile."
echo "-- Error -- The second parameter is the file containg the"
echo "-- Error -- Information about the setup at the client"
echo "-- Error -- installation (see example below)."
echo ""
print_example
exit 1
fi
# test if a valid ctest model is defined
case "$1" in
Experimental|Nightly|Continuous|Profile|alfa_ci|codecov)
;;
*)
echo "-- Error -- This ctest model is not supported."
echo "-- Error -- Possible arguments are Nightly, Experimental, Continuous or Profile."
exit 1
;;
esac
# test if the input file exists and execute it
if [ -e "$2" ];then
source $2
else
echo "-- Error -- Input file does not exist."
echo "-- Error -- Please choose existing input file."
exit 1
fi
# set the ctest model to command line parameter
if [ "$1" == "alfa_ci" ]; then
export ctest_model=Experimental
elif [ "$1" == "codecov" ]; then
export ctest_model=Profile
export do_codecov_upload=0
else
export ctest_model=$1
fi
# test for architecture
arch=$(uname -s | tr '[A-Z]' '[a-z]')
chip=$(uname -m | tr '[A-Z]' '[a-z]')
# extract information about the system and the machine and set
# environment variables used by ctest
SYSTEM=$arch-$chip
if test -z $CXX ; then
if [ "$arch" == "darwin" ]; then
COMPILER=$(clang --version | head -n 1 | cut -d' ' -f1,2,4 | tr -d ' ')
else
COMPILER=gcc$(gcc -dumpversion)
fi
else
COMPILER=$CXX$($CXX -dumpversion)
fi
case "$1" in
alfa_ci)
export LABEL1=alfa_ci-$COMPILER-FairMQ_$GIT_BRANCH
export LABEL=$(echo $LABEL1 | sed -e 's#/#_#g')
;;
codecov)
export LABEL1=codecov-$COMPILER-FairMQ_$GIT_BRANCH
export LABEL=$(echo $LABEL1 | sed -e 's#/#_#g')
;;
*)
export LABEL1=${LINUX_FLAVOUR}-$chip-$COMPILER-FairMQ_$GIT_BRANCH
export LABEL=$(echo $LABEL1 | sed -e 's#/#_#g')
;;
esac
# get the number of processors
# and information about the host
if [ "$arch" = "linux" ];
then
if [ "$NCPU" != "" ];
then
export number_of_processors=$NCPU
else
export number_of_processors=$(cat /proc/cpuinfo | grep processor | wc -l)
fi
if [ -z "$SITE" ]; then
export SITE=$(hostname -f)
if [ -z "$SITE" ]; then
export SITE=$(uname -n)
fi
fi
elif [ "$arch" = "darwin" ];
then
if [ "$NCPU" != "" ];
then
export number_of_processors=$NCPU
else
export number_of_processors=$(sysctl -n hw.ncpu)
fi
if [ -z "$SITE" ]; then
export SITE=$(hostname -s)
fi
fi
echo "************************"
date
echo "LABEL: " $LABEL
echo "SITE: " $SITE
echo "Model: " ${ctest_model}
echo "Nr. of processes: " $number_of_processors
echo "************************"
cd $SOURCEDIR
ctest -S FairMQTest.cmake -V --VV

View File

@ -1,93 +1,88 @@
################################################################################
# Copyright (C) 2021-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# 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" #
################################################################################
Set(CTEST_SOURCE_DIRECTORY $ENV{SOURCEDIR})
Set(CTEST_BINARY_DIRECTORY $ENV{BUILDDIR})
Set(CTEST_SITE $ENV{SITE})
Set(CTEST_BUILD_NAME $ENV{LABEL})
Set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
Set(CTEST_PROJECT_NAME "FairMQ")
cmake_host_system_information(RESULT fqdn QUERY FQDN)
Find_Program(CTEST_GIT_COMMAND NAMES git)
Set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}")
set(CTEST_SOURCE_DIRECTORY .)
set(CTEST_BINARY_DIRECTORY build)
set(CTEST_CMAKE_GENERATOR "Ninja")
set(CTEST_USE_LAUNCHERS ON)
set(CTEST_CONFIGURATION_TYPE "RelWithDebInfo")
set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 102400)
Set(BUILD_COMMAND "make")
Set(CTEST_BUILD_COMMAND "${BUILD_COMMAND} -j$ENV{number_of_processors}")
if(NOT NCPUS)
if(ENV{SLURM_CPUS_PER_TASK})
set(NCPUS $ENV{SLURM_CPUS_PER_TASK})
else()
include(ProcessorCount)
ProcessorCount(NCPUS)
if(NCPUS EQUAL 0)
set(NCPUS 1)
endif()
endif()
endif()
String(TOUPPER $ENV{ctest_model} _Model)
Set(configure_options "-DCMAKE_BUILD_TYPE=$ENV{ctest_model}")
if ("$ENV{CTEST_SITE}" STREQUAL "")
set(CTEST_SITE "${fqdn}")
else()
set(CTEST_SITE $ENV{CTEST_SITE})
endif()
Set(CTEST_USE_LAUNCHERS 1)
Set(configure_options "${configure_options};-DCTEST_USE_LAUNCHERS=${CTEST_USE_LAUNCHERS}")
if ("$ENV{LABEL}" STREQUAL "")
set(CTEST_BUILD_NAME "build")
else()
set(CTEST_BUILD_NAME $ENV{LABEL})
endif()
Set(configure_options "${configure_options};-DDISABLE_COLOR=ON")
Set(configure_options "${configure_options};-DCMAKE_PREFIX_PATH=$ENV{SIMPATH}")
# Set(configure_options "${configure_options};-DBUILD_OFI_TRANSPORT=ON")
Set(configure_options "${configure_options};-DBUILD_DDS_PLUGIN=ON")
Set(configure_options "${configure_options};-DBUILD_SDK=ON")
Set(configure_options "${configure_options};-DBUILD_SDK_COMMANDS=ON")
ctest_start(Continuous)
Set(EXTRA_FLAGS $ENV{EXTRA_FLAGS})
If(EXTRA_FLAGS)
Set(configure_options "${configure_options};${EXTRA_FLAGS}")
EndIf()
list(APPEND options "-DDISABLE_COLOR=ON" "-DBUILD_EXAMPLES=ON" "-DBUILD_TESTING=ON")
if(RUN_STATIC_ANALYSIS)
list(APPEND options "-DRUN_STATIC_ANALYSIS=ON")
endif()
if(CMAKE_BUILD_TYPE)
set(CTEST_CONFIGURATION_TYPE ${CMAKE_BUILD_TYPE})
endif()
if(ENABLE_SANITIZER_ADDRESS)
list(APPEND options "-DENABLE_SANITIZER_ADDRESS=ON")
endif()
if(ENABLE_SANITIZER_LEAK)
list(APPEND options "-DENABLE_SANITIZER_LEAK=ON")
endif()
if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR)
list(APPEND options "-DENABLE_SANITIZER_UNDEFINED_BEHAVIOR=ON")
endif()
if(ENABLE_SANITIZER_MEMORY)
list(APPEND options "-DENABLE_SANITIZER_MEMORY=ON")
endif()
if(ENABLE_SANITIZER_THREAD)
list(APPEND options "-DENABLE_SANITIZER_THREAD=ON")
endif()
if(CMAKE_CXX_COMPILER)
list(APPEND options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
endif()
if(CMAKE_CXX_FLAGS)
list(APPEND options "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}")
endif()
list(REMOVE_DUPLICATES options)
list(JOIN options ";" optionsstr)
ctest_configure(OPTIONS "${optionsstr}")
If($ENV{ctest_model} MATCHES Profile)
Find_Program(GCOV_COMMAND gcov)
If(GCOV_COMMAND)
Message("Found GCOV: ${GCOV_COMMAND}")
Set(CTEST_COVERAGE_COMMAND ${GCOV_COMMAND})
set(CTEST_COVERAGE_EXTRA_FLAGS "-p")
EndIf(GCOV_COMMAND)
EndIf()
ctest_submit()
If($ENV{ctest_model} MATCHES Nightly OR $ENV{ctest_model} MATCHES Profile)
Ctest_Empty_Binary_Directory(${CTEST_BINARY_DIRECTORY})
EndIf()
ctest_build(FLAGS "-j${NCPUS}")
Ctest_Start($ENV{ctest_model})
ctest_submit()
Ctest_Configure(BUILD "${CTEST_BINARY_DIRECTORY}"
OPTIONS "${configure_options}"
)
if(NOT RUN_STATIC_ANALYSIS)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}"
PARALLEL_LEVEL ${NCPUS}
SCHEDULE_RANDOM ON
RETURN_VALUE _ctest_test_ret_val)
Ctest_Build(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_submit()
unset(exclude_tests)
if($ENV{EXCLUDE_UNSTABLE_DDS_TESTS})
set(exclude_tests EXCLUDE ".*\\.localhost$")
endif()
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
# PARALLEL_LEVEL $ENV{number_of_processors}
${exclude_tests}
PARALLEL_LEVEL $ENV{number_of_processors}
RETURN_VALUE _ctest_test_ret_val
)
if(_ctest_test_ret_val)
If(GCOV_COMMAND)
Ctest_Coverage(BUILD "${CTEST_BINARY_DIRECTORY}" LABELS coverage)
EndIf()
If("$ENV{do_codecov_upload}")
Execute_Process(COMMAND curl https://codecov.io/bash -o codecov_uploader.sh
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
TIMEOUT 60)
Execute_Process(COMMAND bash ./codecov_uploader.sh -X gcov
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
TIMEOUT 60)
EndIf()
Ctest_Submit()
if (_ctest_test_ret_val)
Message(FATAL_ERROR "Some tests failed.")
endif()

152
Jenkinsfile vendored
View File

@ -1,75 +1,69 @@
#!groovy
def jobMatrix(String type, List specs) {
def specToLabel(Map spec) {
return "${spec.os}-${spec.arch}-${spec.compiler}-FairSoft_${spec.fairsoft}"
}
def jobMatrix(String prefix, List specs, Closure callback) {
def nodes = [:]
for (spec in specs) {
def job = ""
def selector = "slurm"
def os = ""
def ver = ""
if (type == 'build') {
job = "${spec.os}-${spec.ver}-${spec.arch}-${spec.compiler}"
if (spec.os =~ /^macos/) {
selector = "${spec.os}-${spec.ver}-${spec.arch}"
}
os = spec.os
ver = spec.ver
} else { // == 'check'
job = "${spec.name}"
os = 'fedora'
ver = '36'
def label = specToLabel(spec)
def node_tag = label
if (spec.os =~ /macOS/) {
node_tag = spec.os
}
def label = "${job}"
def extra = spec.extra
nodes[label] = {
node(selector) {
githubNotify(context: "${label}", description: 'Building ...', status: 'PENDING')
def fairsoft = spec.fairsoft
def os = spec.os
def compiler = spec.compiler
nodes["${prefix}/${label}"] = {
node(node_tag) {
githubNotify(context: "${prefix}/${label}", description: 'Building ...', status: 'PENDING')
try {
deleteDir()
checkout scm
def jobscript = 'job.sh'
def ctestcmd = "ctest ${extra} -S FairMQTest.cmake -V --output-on-failure"
sh "echo \"set -e\" >> ${jobscript}"
sh "echo \"export LABEL=\\\"\${JOB_BASE_NAME} ${label}\\\"\" >> ${jobscript}"
if (selector =~ /^macos/) {
sh """\
echo \"${ctestcmd}\" >> ${jobscript}
"""
sh "cat ${jobscript}"
sh "bash ${jobscript}"
} else { // selector == "slurm"
def imageurl = "oras://ghcr.io/fairrootgroup/fairmq-dev/${os}-${ver}-sif:latest"
def execopts = "--ipc --uts --pid -B/shared"
def containercmd = "singularity exec ${execopts} ${imageurl} bash -l -c \\\"${ctestcmd} ${extra}\\\""
sh """\
echo \"echo \\\"*** Job started at .......: \\\$(date -R)\\\"\" >> ${jobscript}
echo \"echo \\\"*** Job ID ...............: \\\${SLURM_JOB_ID}\\\"\" >> ${jobscript}
echo \"echo \\\"*** Compute node .........: \\\$(hostname -f)\\\"\" >> ${jobscript}
echo \"unset http_proxy\" >> ${jobscript}
echo \"unset HTTP_PROXY\" >> ${jobscript}
echo \"${containercmd}\" >> ${jobscript}
"""
sh "cat ${jobscript}"
sh "test/ci/slurm-submit.sh \"FairMQ \${JOB_BASE_NAME} ${label}\" ${jobscript}"
if (job == "static-analyzers") {
recordIssues(enabledForFailure: true,
tools: [gcc(pattern: 'build/Testing/Temporary/*.log')],
filters: [excludeFile('extern/*'), excludeFile('usr/*')],
skipBlames: true,
skipPublishingChecks: true)
}
sh """\
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
"""
if (os =~ /Debian/ && compiler =~ /gcc9/) {
sh '''\
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
'''
}
if (os =~ /[Mm]acOS/) {
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=clang++'\" >> Dart.cfg"
} else {
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=g++'\" >> Dart.cfg"
}
sh '''\
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
echo "export SOURCEDIR=$PWD" >> Dart.cfg
echo "export PATH=\\\$SIMPATH/bin:\\\$PATH" >> Dart.cfg
echo "export GIT_BRANCH=$JOB_BASE_NAME" >> Dart.cfg
echo "echo \\\$PATH" >> Dart.cfg
'''
if (os =~ /macOS10.14/) {
sh "echo \"export EXCLUDE_UNSTABLE_DDS_TESTS=1\" >> Dart.cfg"
}
sh 'cat Dart.cfg'
callback.call(spec, label)
deleteDir()
githubNotify(context: "${label}", description: 'Success', status: 'SUCCESS')
githubNotify(context: "${prefix}/${label}", description: 'Success', status: 'SUCCESS')
} catch (e) {
def tarball = "${prefix}_${label}_dds_logs.tar.gz"
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
archiveArtifacts tarball
deleteDir()
githubNotify(context: "${label}", description: 'Error', status: 'ERROR')
githubNotify(context: "${prefix}/${label}", description: 'Error', status: 'ERROR')
throw e
}
}
@ -81,36 +75,26 @@ def jobMatrix(String type, List specs) {
pipeline{
agent none
stages {
stage("CI") {
stage("Run CI Matrix") {
steps{
script {
def builds = jobMatrix('build', [
[os: 'ubuntu', ver: '20.04', arch: 'x86_64', compiler: 'gcc-9'],
[os: 'ubuntu', ver: '22.04', arch: 'x86_64', compiler: 'gcc-11'],
[os: 'ubuntu', ver: '24.04', arch: 'x86_64', compiler: 'gcc-13'],
[os: 'fedora', ver: '33', arch: 'x86_64', compiler: 'gcc-10'],
[os: 'fedora', ver: '34', arch: 'x86_64', compiler: 'gcc-11'],
[os: 'fedora', ver: '35', arch: 'x86_64', compiler: 'gcc-11'],
[os: 'fedora', ver: '36', arch: 'x86_64', compiler: 'gcc-12'],
[os: 'fedora', ver: '37', arch: 'x86_64', compiler: 'gcc-12'],
[os: 'fedora', ver: '38', arch: 'x86_64', compiler: 'gcc-13'],
[os: 'fedora', ver: '39', arch: 'x86_64', compiler: 'gcc-13'],
[os: 'fedora', ver: '40', arch: 'x86_64', compiler: 'gcc-14'],
[os: 'macos', ver: '14', arch: 'x86_64', compiler: 'apple-clang-16'],
[os: 'macos', ver: '15', arch: 'x86_64', compiler: 'apple-clang-16'],
[os: 'macos', ver: '15', arch: 'arm64', compiler: 'apple-clang-16'],
])
def build_jobs = jobMatrix('build', [
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
[os: 'macOS10.14', arch: 'x86_64', compiler: 'AppleClang11.0', fairsoft: 'fairmq_dev'],
[os: 'macOS10.15', arch: 'x86_64', compiler: 'AppleClang12.0', fairsoft: 'fairmq_dev'],
]) { spec, label ->
sh './Dart.sh alfa_ci Dart.cfg'
}
def all_debug = "-DCMAKE_BUILD_TYPE=Debug"
def profile_jobs = jobMatrix('codecov', [
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
]) { spec, label ->
withCredentials([string(credentialsId: 'fairmq_codecov_token', variable: 'CODECOV_TOKEN')]) {
sh './Dart.sh codecov Dart.cfg'
}
}
def checks = jobMatrix('check', [
[name: 'static-analyzers', extra: "${all_debug} -DRUN_STATIC_ANALYSIS=ON"],
[name: '{address,leak,ub}-sanitizers',
extra: "${all_debug} -DENABLE_SANITIZER_ADDRESS=ON -DENABLE_SANITIZER_LEAK=ON -DENABLE_SANITIZER_UNDEFINED_BEHAVIOUR=ON -DCMAKE_CXX_FLAGS='-O1 -fno-omit-frame-pointer'"],
[name: 'thread-sanitizer', extra: "${all_debug} -DENABLE_SANITIZER_THREAD=ON -DCMAKE_CXX_COMPILER=clang++"],
])
parallel(builds + checks)
parallel(build_jobs + profile_jobs)
}
}
}

81
Jenkinsfile.nightly Normal file
View File

@ -0,0 +1,81 @@
#!groovy
def specToLabel(Map spec) {
return "${spec.os}-${spec.arch}-${spec.compiler}-FairSoft_${spec.fairsoft}"
}
def buildMatrix(List specs, Closure callback) {
def nodes = [:]
for (spec in specs) {
def label = specToLabel(spec)
def fairsoft = spec.fairsoft
def os = spec.os
def compiler = spec.compiler
nodes[label] = {
node(label) {
try {
deleteDir()
checkout scm
sh """\
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
"""
if (os =~ /Debian/ && compiler =~ /gcc9/) {
sh '''\
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
'''
}
if (os =~ /MacOS/) {
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=clang++'\" >> Dart.cfg"
} else {
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=g++'\" >> Dart.cfg"
}
sh '''\
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
echo "export SOURCEDIR=$PWD" >> Dart.cfg
echo "export PATH=\\\$SIMPATH/bin:\\\$PATH" >> Dart.cfg
echo "export GIT_BRANCH=dev" >> Dart.cfg
echo "echo \\\$PATH" >> Dart.cfg
'''
sh 'cat Dart.cfg'
callback.call(spec, label)
deleteDir()
} catch (e) {
def tarball = "${label}_dds_logs.tar.gz"
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
archiveArtifacts tarball
deleteDir()
throw e
}
}
}
}
return nodes
}
pipeline{
agent none
triggers { cron('H 2 * * *') }
stages {
stage("Run Nightly Build/Test Matrix") {
steps{
script {
parallel(buildMatrix([
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
]) { spec, label ->
sh './Dart.sh Nightly Dart.cfg'
sh './Dart.sh Profile Dart.cfg'
})
}
}
}
}
}

119
README.md
View File

@ -1,15 +1,12 @@
<!-- {#mainpage} -->
# FairMQ
[![license](https://alfa-ci.gsi.de/shields/badge/license-LGPL--3.0-orange.svg)](COPYRIGHT)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1689985.svg)](https://doi.org/10.5281/zenodo.1689985)
[![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/6915/badge)](https://bestpractices.coreinfrastructure.org/projects/6915)
[![fair-software.eu](https://img.shields.io/badge/fair--software.eu-%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8B%20%20%E2%97%8F%20%20%E2%97%8F-yellow)](https://github.com/FairRootGroup/FairMQ/actions/workflows/fair-software.yml)
[![Spack package](https://repology.org/badge/version-for-repo/spack/fairmq.svg)](https://repology.org/project/fairmq/versions)
# FairMQ [![license](https://alfa-ci.gsi.de/shields/badge/license-LGPL--3.0-orange.svg)](COPYRIGHT) [![build status](https://alfa-ci.gsi.de/buildStatus/icon?job=FairRootGroup/FairMQ/master)](https://alfa-ci.gsi.de/blue/organizations/jenkins/FairRootGroup%2FFairMQ/branches) [![test coverage master branch](https://codecov.io/gh/FairRootGroup/FairMQ/branch/master/graph/badge.svg)](https://codecov.io/gh/FairRootGroup/FairMQ/branch/master) [![Coverity Badge](https://alfa-ci.gsi.de/shields/coverity/scan/fairrootgroup-fairmq.svg)](https://scan.coverity.com/projects/fairrootgroup-fairmq) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/6b648d95d68d4c4eae833b84f84d299c)](https://www.codacy.com/app/dennisklein/FairMQ?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=FairRootGroup/FairMQ&amp;utm_campaign=Badge_Grade)
C++ Message Queuing Library and Framework
Docs: [Book](https://github.com/FairRootGroup/FairMQ/blob/dev/README.md#documentation)
| Release | Version | Docs |
| :---: | :--- | :--- |
| `stable` | [![release](https://alfa-ci.gsi.de/shields/github/release/FairRootGroup/FairMQ.svg)](https://github.com/FairRootGroup/FairMQ/releases/latest) | [API](https://fairrootgroup.github.io/FairMQ/latest), [Book](https://github.com/FairRootGroup/FairMQ/blob/master/README.md#documentation) |
| `testing` | [![dev tag](https://alfa-ci.gsi.de/shields/github/tag/FairRootGroup/FairMQ.svg)](https://github.com/FairRootGroup/FairMQ/tags) | [Book](https://github.com/FairRootGroup/FairMQ/blob/dev/README.md#documentation) |
Find all FairMQ releases [here](https://github.com/FairRootGroup/FairMQ/releases).
@ -24,17 +21,14 @@ FairMQ is designed to help implementing large-scale data processing workflows ne
The core of FairMQ provides an abstract asynchronous message passing API with scalability protocols
inspired by [ZeroMQ](https://github.com/zeromq/libzmq) (e.g. PUSH/PULL, PUB/SUB).
FairMQ provides multiple implementations for its API (so-called "transports",
e.g. `zeromq` and `shmem` (latest release of the `ofi` transport in v1.4.56, removed since v1.5+)) to cover
a variety of use cases
e.g. `zeromq`, `shmem` and `ofi` (in development)) to cover a variety of use cases
(e.g. inter-thread, inter-process, inter-node communication) and machines (e.g. Ethernet, Infiniband).
In addition to this core functionality FairMQ provides a framework for creating "devices" - actors which
are communicating through message passing. FairMQ does not only allow the user to use different transport
but also to mix them; i.e: A Device can communicate using different transport on different channels at the
same time. Device execution is modelled as a simple state machine that shapes the integration points for
the user task. Devices also incorporate a plugin system for runtime configuration and control.
Next to the provided [devices](https://github.com/FairRootGroup/FairMQ/tree/master/fairmq/devices) and
[plugins](https://github.com/FairRootGroup/FairMQ/tree/master/fairmq/plugins) the user can extend FairMQ
by developing his own plugins to integrate his devices with external configuration and control services.
are communicating through message passing. FairMQ does not only allow the user to use different transport but also to mix them; i.e: A Device can communicate using different transport on different channels at the same time. Device execution is modelled as a simple state machine that
shapes the integration points for the user task. Devices also incorporate a plugin system for runtime configuration and control.
Next to the provided devices and plugins (e.g. [DDS](https://github.com/FairRootGroup/DDS))
the user can extend FairMQ by developing his own plugins to integrate his devices with external
configuration and control services.
FairMQ has been developed in the context of its mother project [FairRoot](https://github.com/FairRootGroup/FairRoot) -
a simulation, reconstruction and analysis framework.
@ -45,68 +39,74 @@ Recommended:
```bash
git clone https://github.com/FairRootGroup/FairMQ fairmq_source
cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Release [-DBUILD_TESTING=ON]
cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=fairmq_install
cmake --build fairmq_build
[ctest --test-dir fairmq_build --output-on-failure --schedule-random -j<ncpus>] # needs -DBUILD_TESTING=ON
cmake --install fairmq_build --prefix $(pwd)/fairmq_install
cd fairmq_build; ctest -j4; cd ..
cmake --build fairmq_build --target install
```
Please consult the [manpages of your CMake version](https://cmake.org/cmake/help/latest/manual/cmake.1.html) for more options.
If dependencies are not installed in standard system directories, you can hint the installation location via
`-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...` (`*_ROOT` variables can also be environment variables).
## Installation via Spack
Prerequisite: [Spack](https://spack.readthedocs.io/en/latest/getting_started.html)
```bash
spack info fairmq # inspect build options
spack install fairmq # build latest packaged version with default options
```
Build FairMQ's dependencies via Spack for development:
```bash
git clone -b dev https://github.com/FairRootGroup/FairMQ fairmq_source
spack --env fairmq_source install # installs deps declared in fairmq_source/spack.yaml
spack env activate fairmq_source # sets $CMAKE_PREFIX_PATH which is used by CMake to find FairMQ's deps
cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
# develop, compile, test
spack env deactivate # at end of dev session, or simply close the shell
```
If dependencies are not installed in standard system directories, you can hint the installation location via `-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...`. `{DEPENDENCY}` can be `GTEST`, `BOOST`, `FAIRLOGGER`, `ZEROMQ`, `OFI`, `PMIX`, `ASIO`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
## Usage
FairMQ ships as a CMake package, so in your `CMakeLists.txt` you can discover it like this:
```cmake
find_package(FairCMakeModules 1.0 REQUIRED)
include(FairFindPackage2)
find_package2(FairMQ)
find_package2_implicit_dependencies()
find_package(FairMQ)
```
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
list(PREPEND CMAKE_PREFIX_PATH /path/to/fairmq_install)
set(CMAKE_PREFIX_PATH /path/to/FairMQ_install_prefix ${CMAKE_PREFIX_PATH})
find_package(FairMQ)
```
`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)
```
When building FairMQ, CMake will print a summary table of all available package components.
## Dependencies
* [asio](https://github.com/chriskohlhoff/asio) (optionally bundled)
* [asiofi](https://github.com/FairRootGroup/asiofi)
* [Boost](https://www.boost.org/)
* [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/)
* [ZeroMQ](http://zeromq.org/)
Which dependencies are required depends on which components are built.
Supported platform is Linux. macOS is supported on a best-effort basis.
Supported platforms: Linux and MacOS.
## CMake options
@ -115,8 +115,10 @@ On command line:
* `-DDISABLE_COLOR=ON` disables coloured console output.
* `-DBUILD_TESTING=OFF` disables building of tests.
* `-DBUILD_EXAMPLES=OFF` disables building of examples.
* `-DBUILD_OFI_TRANSPORT=ON` enables building of the experimental OFI transport.
* `-DBUILD_DDS_PLUGIN=ON` enables building of the DDS plugin.
* `-DBUILD_PMIX_PLUGIN=ON` enables building of the PMIx plugin.
* `-DBUILD_DOCS=ON` enables building of API docs.
* `-DFAIRMQ_CHANNEL_DEFAULT_AUTOBIND=OFF` disable channel `autoBind` by default
* You can hint non-system installations for dependent packages, see the #installation-from-source section above
After the `find_package(FairMQ)` call the following CMake variables are defined:
@ -124,8 +126,9 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
| Variable | Info |
| --- | --- |
| `${FairMQ_PACKAGE_DEPENDENCIES}` | the list of public package dependencies |
| `${FairMQ_<dep>_VERSION}` | the minimum `<dep>` version FairMQ requires |
| `${FairMQ_<dep>_COMPONENTS}` | the list of `<dep>` components FairMQ depends on |
| `${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_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` |
@ -136,6 +139,9 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
| `${FairMQ_LIBDIR}` | the installation lib directory |
| `${FairMQ_DATADIR}` | the installation data directory (`../share/fairmq`) |
| `${FairMQ_CMAKEMODDIR}` | the installation directory of shipped CMake find modules |
| `${FairMQ_CXX_STANDARD_REQUIRED}` | the value of `CMAKE_CXX_STANDARD_REQUIRED` at build-time |
| `${FairMQ_CXX_STANDARD}` | the value of `CMAKE_CXX_STANDARD` at build-time |
| `${FairMQ_CXX_EXTENSIONS}` | the values of `CMAKE_CXX_EXTENSIONS` at build-time |
| `${FairMQ_BUILD_TYPE}` | the value of `CMAKE_BUILD_TYPE` at build-time |
| `${FairMQ_CXX_FLAGS}` | the values of `CMAKE_CXX_FLAGS` and `CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}` at build-time |
@ -159,9 +165,6 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
3. [Introspection](docs/Configuration.md#33-introspection)
4. [Development](docs/Development.md#4-development)
1. [Testing](docs/Development.md#41-testing)
2. [Static Analysis](docs/Development.md#42-static-analysis)
1. [CMake Integration](docs/Development.md#421-cmake-integration)
2. [Extra Compiler Arguments](docs/Development.md#422-extra-compiler-arguments)
5. [Logging](docs/Logging.md#5-logging)
1. [Log severity](docs/Logging.md#51-log-severity)
2. [Log verbosity](docs/Logging.md#52-log-verbosity)
@ -173,4 +176,6 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
1. [Usage](docs/Plugins.md#71-usage)
2. [Development](docs/Plugins.md#72-development)
3. [Provided Plugins](docs/Plugins.md#73-provided-plugins)
1. [PMIx](docs/Plugins.md#731-pmix)
1. [DDS](docs/Plugins.md#731-dds)
2. [PMIx](docs/Plugins.md#732-pmix)
8. [Controller SDK](docs/SDK.md)

View File

@ -1,19 +0,0 @@
################################################################################
# Copyright (C) 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)
include(FairMQBundlePackageHelper)
set(PROJECT_FairCMakeModules_VERSION 0.2)
find_package(FairCMakeModules ${PROJECT_FairCMakeModules_VERSION} QUIET)
if(NOT FairCMakeModules_FOUND AND NOT FairCMakeModules_BUNDLED)
build_bundled(FairCMakeModules extern/FairCMakeModules)
find_package(FairCMakeModules REQUIRED)
endif()

View File

@ -1,50 +0,0 @@
################################################################################
# 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)
include(CMakeDependentOption)
macro(fairmq_build_option option description)
cmake_parse_arguments(ARGS "" "DEFAULT" "REQUIRES" ${ARGN})
if(ARGS_DEFAULT)
set(__default__ ON)
else()
set(__default__ OFF)
endif()
if(ARGS_REQUIRES)
set(__requires__ ${ARGS_REQUIRES})
foreach(d ${__requires__})
string(REGEX REPLACE " +" ";" __requires_condition__ "${d}")
if(${__requires_condition__})
else()
if(${option})
message(FATAL_ERROR "Cannot enable build option ${option}, depending option is not set: ${__requires_condition__}")
endif()
endif()
endforeach()
else()
set(__requires__)
endif()
if(__requires__)
cmake_dependent_option(${option} ${description} ${__default__} "${__requires__}" OFF)
else()
option(${option} ${description} ${__default__})
endif()
set(__default__)
set(__requires__)
set(__requires_condition__)
set(ARGS_DEFAULT)
set(ARGS_REQUIRES)
set(option)
set(description)
endmacro()

View File

@ -1,92 +0,0 @@
################################################################################
# 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)
if(NOT DEFINED ${GIT_EXECUTABLE})
find_program(GIT_EXECUTABLE NAMES git)
endif()
# TODO Deduplicate code
macro(exec cmd)
list(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)
list(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_EXECUTABLE)
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 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()

View File

@ -1,5 +1,5 @@
################################################################################
# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# 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, #
@ -20,6 +20,9 @@ set(@PROJECT_NAME@_LIBDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_LIBDIR
set(@PROJECT_NAME@_DATADIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_DATADIR@)
set(@PROJECT_NAME@_CMAKEMODDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_CMAKEMODDIR@)
set(@PROJECT_NAME@_CXX_STANDARD_REQUIRED @CMAKE_CXX_STANDARD_REQUIRED@)
set(@PROJECT_NAME@_CXX_STANDARD @CMAKE_CXX_STANDARD@)
set(@PROJECT_NAME@_CXX_EXTENSIONS @CMAKE_CXX_EXTENSIONS@)
set(@PROJECT_NAME@_VERSION_HOTFIX @PROJECT_VERSION_HOTFIX@)
set(@PROJECT_NAME@_BUILD_TYPE @CMAKE_BUILD_TYPE@)
set(@PROJECT_NAME@_BUILD_TYPE_UPPER @PROJECT_BUILD_TYPE_UPPER@)
@ -33,4 +36,6 @@ set(CMAKE_MODULE_PATH ${@PROJECT_NAME@_CMAKEMODDIR} ${CMAKE_MODULE_PATH})
### Import targets
include(@PACKAGE_CMAKE_INSTALL_PREFIX@/@PACKAGE_INSTALL_DESTINATION@/@PROJECT_EXPORT_SET@.cmake)
@BUNDLED_PACKAGES@
@PACKAGE_COMPONENTS@

View File

@ -1,107 +0,0 @@
################################################################################
# Copyright (C) 2018-2025 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)
include(FairCMakeModules)
include(FairFindPackage2)
include(FairMQBundlePackageHelper)
if(BUILD_FAIRMQ)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package2(PUBLIC Threads REQUIRED)
set(Threads_PREFIX "<system>")
endif()
if(BUILD_FAIRMQ OR BUILD_TIDY_TOOL)
find_package2(PUBLIC FairLogger REQUIRED VERSION 1.6.0)
find_package2(PUBLIC Boost REQUIRED VERSION 1.66
COMPONENTS container program_options filesystem date_time regex
)
endif()
if(BUILD_FAIRMQ)
find_package2(PRIVATE ZeroMQ REQUIRED VERSION 4.1.4)
if(NOT PicoSHA2_BUNDLED)
build_bundled(PicoSHA2 extern/PicoSHA2)
endif()
find_package2(BUNDLED PicoSHA2 REQUIRED)
set(PicoSHA2_VERSION "1.0.0")
set(PicoSHA2_PREFIX "<bundled>")
endif()
if(BUILD_TESTING)
if(NOT GTest_FOUND AND NOT GTest_BUNDLED AND NOT USE_EXTERNAL_GTEST)
build_bundled(GTest extern/googletest)
endif()
find_package2(BUNDLED GTest REQUIRED)
if(GTest_BUNDLED)
set(GTest_VERSION "Dec 26 2024 @7d76a23")
set(GTest_PREFIX "<bundled>")
endif()
endif()
if(BUILD_DOCS)
find_package2(PRIVATE Doxygen REQUIRED VERSION 1.8.8
COMPONENTS dot
)
endif()
if(BUILD_TIDY_TOOL)
find_package2(PRIVATE LLVM REQUIRED)
find_package2(PRIVATE Clang REQUIRED)
set(Clang_VERSION ${LLVM_VERSION})
find_package2(PRIVATE CLI11 REQUIRED)
endif()
find_package2_implicit_dependencies() # Always call last after latest find_package2
if(PROJECT_PACKAGE_DEPENDENCIES)
foreach(dep IN LISTS PROJECT_PACKAGE_DEPENDENCIES)
string(TOUPPER ${dep} dep_upper)
if(${dep}_BUNDLED)
set(${dep}_PREFIX "<bundled>")
elseif(${dep} STREQUAL FairLogger)
if(NOT FairLogger_PREFIX AND FairLogger_ROOT)
set(FairLogger_PREFIX ${FairLogger_ROOT})
endif()
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(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()

550
cmake/FairMQLib.cmake Normal file
View File

@ -0,0 +1,550 @@
################################################################################
# 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()
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 PROJECT)
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)
string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPER)
# 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 ${PROJECT_MIN_CXX_STANDARD})
elseif(${CMAKE_CXX_STANDARD} LESS ${PROJECT_MIN_CXX_STANDARD})
message(FATAL_ERROR "A minimum CMAKE_CXX_STANDARD of ${PROJECT_MIN_CXX_STANDARD} is required.")
endif()
set(CMAKE_CXX_EXTENSIONS OFF)
if(NOT BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON CACHE BOOL "Whether to build shared libraries or static archives")
endif()
# Set -fPIC as default for all library types
if(NOT CMAKE_POSITION_INDEPENDENT_CODE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
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(PROJECT_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR})
set(PROJECT_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR})
set(PROJECT_INSTALL_INCDIR ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME_LOWER})
set(PROJECT_INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME_LOWER})
set(PROJECT_INSTALL_CMAKEMODDIR ${PROJECT_INSTALL_DATADIR}/cmake)
# https://cmake.org/Wiki/CMake_RPATH_handling
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR}" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-Wl,--enable-new-dtags")
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-Wl,--enable-new-dtags")
set(CMAKE_INSTALL_RPATH "$ORIGIN/../${PROJECT_INSTALL_LIBDIR}")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(CMAKE_INSTALL_RPATH "@loader_path/../${PROJECT_INSTALL_LIBDIR}")
else()
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR}")
endif()
endif()
# Define export set, only one for now
set(PROJECT_EXPORT_SET ${PROJECT_NAME}Targets)
# Configure build types
set(CMAKE_CONFIGURATION_TYPES "Debug" "Release" "RelWithDebInfo" "Nightly" "Profile" "Experimental" "AddressSan" "ThreadSan")
set(_warnings "-Wshadow -Wall -Wextra -Wpedantic")
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g ${_warnings}")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${_warnings} -DNDEBUG")
set(CMAKE_CXX_FLAGS_NIGHTLY "-O2 -g ${_warnings}")
set(CMAKE_CXX_FLAGS_PROFILE "-g3 ${_warnings} -fno-inline -ftest-coverage -fprofile-arcs")
set(CMAKE_CXX_FLAGS_EXPERIMENTAL "-O2 -g ${_warnings} -DNDEBUG")
set(CMAKE_CXX_FLAGS_ADDRESSSAN "-O2 -g ${_warnings} -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS_THREADSAN "-O2 -g ${_warnings} -fsanitize=thread")
unset(_warnings)
if(CMAKE_GENERATOR STREQUAL "Ninja" AND
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR
(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")
endif()
if(NOT PROJECT_VERSION_TWEAK)
set(PROJECT_VERSION_HOTFIX 0)
else()
set(PROJECT_VERSION_HOTFIX ${PROJECT_VERSION_TWEAK})
endif()
if(NOT DEFINED RUN_STATIC_ANALYSIS)
set(RUN_STATIC_ANALYSIS OFF)
endif()
unset(PROJECT_STATIC_ANALYSERS)
if(RUN_STATIC_ANALYSIS)
set(analyser "clang-tidy")
find_program(${analyser}_FOUND "${analyser}")
if(${analyser}_FOUND)
set(CMAKE_CXX_CLANG_TIDY "${${analyser}_FOUND}")
endif()
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
set(analyser "iwyu")
find_program(${analyser}_FOUND "${analyser}")
if(${analyser}_FOUND)
set(CMAKE_CXX_IWYU "${${analyser}_FOUND}")
endif()
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
set(analyser "cpplint")
find_program(${analyser}_FOUND "${analyser}")
if(${analyser}_FOUND)
set(CMAKE_CXX_CPPLINT "${${analyser}_FOUND}")
endif()
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
endif()
if(CMAKE_GENERATOR STREQUAL Ninja AND ENABLE_CCACHE)
find_program(CCACHE ccache)
if(CCACHE)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
endif()
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)
if(ARGS_COLOR)
math(EXPR padding "${width}-(${length}-10*${ARGS_COLOR})")
else()
math(EXPR padding "${width}-${length}")
endif()
if(padding GREATER 0)
foreach(i RANGE ${padding})
set(str "${str}${char}")
endforeach()
endif()
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 "\
####### Expanded from @PACKAGE_COMPONENTS@ by configure_package_config_file() #########
set(${PROJECT_NAME}_PACKAGE_COMPONENTS ${COMPS})
")
foreach(comp IN LISTS PROJECT_PACKAGE_COMPONENTS)
string(CONCAT PACKAGE_COMPONENTS ${PACKAGE_COMPONENTS} "\
set(${PROJECT_NAME}_${comp}_FOUND TRUE)
")
endforeach()
string(CONCAT PACKAGE_COMPONENTS ${PACKAGE_COMPONENTS} "\
check_required_components(${PROJECT_NAME})
")
set(PACKAGE_COMPONENTS ${PACKAGE_COMPONENTS} PARENT_SCOPE)
endfunction()
function(generate_bundled_packages)
if(asio_BUNDLED)
set(BUNDLED_PACKAGES "\
####### Expanded from @BUNDLED_PACKAGES@ by configure_package_config_file() #########
if(\"\${CMAKE_MAJOR_VERSION}.\${CMAKE_MINOR_VERSION}\" VERSION_LESS 3.11)
message(FATAL_ERROR \"CMake >= 3.11 required\")
endif()
set_target_properties(${PROJECT_NAME}::bundled_asio_headers PROPERTIES IMPORTED_GLOBAL TRUE)
add_library(asio::headers ALIAS ${PROJECT_NAME}::bundled_asio_headers)
set(asio_VERSION ${asio_VERSION})
")
endif()
set(BUNDLED_PACKAGES ${BUNDLED_PACKAGES} PARENT_SCOPE)
endfunction()
# Configure/Install CMake package
macro(install_cmake_package)
list(SORT PROJECT_PACKAGE_DEPENDENCIES)
list(SORT PROJECT_INTERFACE_PACKAGE_DEPENDENCIES)
include(CMakePackageConfigHelpers)
set(PACKAGE_INSTALL_DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION}
)
if(BUILD_FAIRMQ)
install(EXPORT ${PROJECT_EXPORT_SET}
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${PACKAGE_INSTALL_DESTINATION}
EXPORT_LINK_INTERFACE_LIBRARIES
)
endif()
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
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)
set(PROJECT_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${PROJECT_BUILD_TYPE_UPPER}})
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()
#
# find_package2(PRIVATE|PUBLIC|INTERFACE <pkgname>
# [VERSION <version>]
# [COMPONENTS <list of components>]
# [ADD_REQUIREMENTS_OF <list of dep_pgkname>]
# [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]_<pkgname>_([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
# <pkgname>_BUNDLED is false and to PRIVATE otherwise.
#
# When a dependending package is listed with ADD_REQUIREMENTS_OF the variables
# <dep_pkgname>_<pkgname>_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}_BUILD_INCLUDE_DIR ${${package}_SOURCE_DIR}/asio/include CACHE PATH "Bundled ${package} build-interface include dir")
set(${package}_INSTALL_INCLUDE_DIR ${PROJECT_INSTALL_INCDIR}/bundled CACHE PATH "Bundled ${package} install-interface include dir")
set(${package}_ROOT ${${package}_SOURCE_DIR}/asio)
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})
if(ARGS_DEFAULT)
set(__default__ ON)
else()
set(__default__ OFF)
endif()
if(ARGS_REQUIRES)
include(CMakeDependentOption)
set(__requires__ ${ARGS_REQUIRES})
foreach(d ${__requires__})
string(REGEX REPLACE " +" ";" __requires_condition__ "${d}")
if(${__requires_condition__})
else()
if(${option})
message(FATAL_ERROR "Cannot enable build option ${option}, depending option is not set: ${__requires_condition__}")
endif()
endif()
endforeach()
else()
set(__requires__)
endif()
if(__requires__)
cmake_dependent_option(${option} ${description} ${__default__} "${__requires__}" OFF)
else()
option(${option} ${description} ${__default__})
endif()
set(__default__)
set(__requires__)
set(__requires_condition__)
set(ARGS_DEFAULT)
set(ARGS_REQUIRES)
set(option)
set(description)
endmacro()

View File

@ -1,68 +0,0 @@
################################################################################
# Copyright (C) 2018-2023 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)
include(FairCMakeModules)
include(FairFindPackage2)
include(FairMQBundlePackageHelper)
function(generate_package_components)
list(JOIN PROJECT_PACKAGE_COMPONENTS} " " COMPS)
set(PACKAGE_COMPONENTS "\
####### Expanded from @PACKAGE_COMPONENTS@ by configure_package_config_file() #########
set(${PROJECT_NAME}_PACKAGE_COMPONENTS ${COMPS})
")
foreach(comp IN LISTS PROJECT_PACKAGE_COMPONENTS)
string(CONCAT PACKAGE_COMPONENTS ${PACKAGE_COMPONENTS} "\
set(${PROJECT_NAME}_${comp}_FOUND TRUE)
")
endforeach()
string(CONCAT PACKAGE_COMPONENTS ${PACKAGE_COMPONENTS} "\
check_required_components(${PROJECT_NAME})
")
set(PACKAGE_COMPONENTS ${PACKAGE_COMPONENTS} PARENT_SCOPE)
endfunction()
# Configure/Install CMake package
macro(install_cmake_package)
include(CMakePackageConfigHelpers)
set(PACKAGE_INSTALL_DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION}
)
if(BUILD_FAIRMQ)
install(EXPORT ${PROJECT_EXPORT_SET}
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${PACKAGE_INSTALL_DESTINATION}
EXPORT_LINK_INTERFACE_LIBRARIES
)
endif()
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
fair_generate_package_dependencies() # fills ${PACKAGE_DEPENDENCIES}
generate_package_components() # fills ${PACKAGE_COMPONENTS}
string(TOUPPER ${CMAKE_BUILD_TYPE} PROJECT_BUILD_TYPE_UPPER)
set(PROJECT_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${PROJECT_BUILD_TYPE_UPPER}})
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()

View File

@ -1,189 +0,0 @@
################################################################################
# Copyright (C) 2018-2023 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)
include(GNUInstallDirs)
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)
string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPER)
# Set a default build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
set(PROJECT_MIN_CXX_STANDARD 17)
# Handle C++ standard level
if(CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD VERSION_LESS PROJECT_MIN_CXX_STANDARD)
message(FATAL_ERROR "A minimum CMAKE_CXX_STANDARD of ${PROJECT_MIN_CXX_STANDARD} is required.")
endif()
if(NOT DEFINED CMAKE_CXX_EXTENSIONS)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
if(NOT BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON CACHE BOOL "Whether to build shared libraries or static archives")
endif()
# Set -fPIC as default for all library types
if(NOT CMAKE_POSITION_INDEPENDENT_CODE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
# Generate compile_commands.json file (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
# Define install dirs
set(PROJECT_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR})
set(PROJECT_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR})
set(PROJECT_INSTALL_INCDIR ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME_LOWER})
set(PROJECT_INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME_LOWER})
set(PROJECT_INSTALL_CMAKEMODDIR ${PROJECT_INSTALL_DATADIR}/cmake)
# https://cmake.org/Wiki/CMake_RPATH_handling
if(NOT DEFINED CMAKE_INSTALL_RPATH_USE_LINK_PATH)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON)
endif()
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR}" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-new-dtags")
list(APPEND CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-new-dtags")
list(PREPEND CMAKE_INSTALL_RPATH "$ORIGIN/../${PROJECT_INSTALL_LIBDIR}")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
list(PREPEND CMAKE_INSTALL_RPATH "@loader_path/../${PROJECT_INSTALL_LIBDIR}")
else()
list(PREPEND CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR}")
endif()
endif()
# Define export set, only one for now
set(PROJECT_EXPORT_SET ${PROJECT_NAME}Targets)
# Sanitizers
set(_sanitizers "")
option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" FALSE)
if(ENABLE_SANITIZER_ADDRESS)
list(APPEND _sanitizers "address")
endif()
option(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" FALSE)
if(ENABLE_SANITIZER_LEAK)
list(APPEND _sanitizers "leak")
endif()
option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" FALSE)
if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR)
list(APPEND _sanitizers "undefined")
endif()
option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" FALSE)
if(ENABLE_SANITIZER_THREAD)
if("address" IN_LIST _sanitizers OR "leak" IN_LIST _sanitizers)
message(WARNING "Thread sanitizer does not work with Address and Leak sanitizer enabled")
else()
list(APPEND _sanitizers "thread")
endif()
endif()
option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" FALSE)
if(ENABLE_SANITIZER_MEMORY AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
if("address" IN_LIST _sanitizers
OR "thread" IN_LIST _sanitizers
OR "leak" IN_LIST _sanitizers)
message(WARNING "Memory sanitizer does not work with Address, Thread and Leak sanitizer enabled")
else()
list(APPEND _sanitizers "memory")
endif()
endif()
list(JOIN _sanitizers "," _sanitizers)
if(_sanitizers)
set(_sanitizers "-fsanitize=${_sanitizers}")
endif()
# Configure build types
set(CMAKE_CONFIGURATION_TYPES "Debug" "Release" "RelWithDebInfo")
set(_warnings "-Wshadow -Wall -Wextra -Wpedantic")
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g ${_warnings} ${_sanitizers}")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g ${_warnings} -DNDEBUG ${_sanitizers}")
unset(_warnings)
unset(_sanitizers)
if(DISABLE_COLOR)
set(CMAKE_COLOR_MAKEFILE OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=never")
else()
set(CMAKE_COLOR_MAKEFILE ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
endif()
if(NOT DEFINED PROJECT_VERSION_TWEAK)
set(PROJECT_VERSION_HOTFIX 0)
else()
set(PROJECT_VERSION_HOTFIX ${PROJECT_VERSION_TWEAK})
endif()
if(NOT DEFINED RUN_STATIC_ANALYSIS)
set(RUN_STATIC_ANALYSIS OFF)
endif()
unset(PROJECT_STATIC_ANALYSERS)
if(RUN_STATIC_ANALYSIS)
set(analyser "clang-tidy")
find_program(${analyser}_FOUND "${analyser}")
if(${analyser}_FOUND)
set(CMAKE_CXX_CLANG_TIDY ${analyser} "--extra-arg=-std=c++17")
endif()
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
set(analyser "iwyu")
find_program(${analyser}_FOUND "${analyser}")
if(${analyser}_FOUND)
set(CMAKE_CXX_IWYU "${${analyser}_FOUND}")
endif()
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
set(analyser "cpplint")
find_program(${analyser}_FOUND "${analyser}")
if(${analyser}_FOUND)
set(CMAKE_CXX_CPPLINT "${${analyser}_FOUND}")
endif()
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
endif()
if(CMAKE_GENERATOR STREQUAL Ninja AND ENABLE_CCACHE)
find_program(CCACHE ccache)
if(CCACHE)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
endif()
endif()
if(NOT DEFINED FAIRMQ_HAS_STD_FILESYSTEM)
if( ( CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
OR ( CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9))
set(FAIRMQ_HAS_STD_FILESYSTEM 0)
else()
set(FAIRMQ_HAS_STD_FILESYSTEM 1)
endif()
endif()
if(NOT DEFINED FAIRMQ_HAS_STD_PMR)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Clang (to be more precise: libc++) currently does not implement <memory_resource>
set(FAIRMQ_HAS_STD_PMR 0)
else()
set(FAIRMQ_HAS_STD_PMR 1)
endif()
endif()

View File

@ -1,105 +0,0 @@
################################################################################
# Copyright (C) 2018-2023 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)
include(FairCMakeModules)
include(FairFormattedOutput)
include(FairSummary)
macro(fairmq_summary_components)
message(STATUS " ")
message(STATUS " ${Cyan}COMPONENT BUILT? INFO${CR}")
if(BUILD_FAIRMQ)
set(fairmq_summary "${BGreen}YES${CR} (default, disable with ${BMagenta}-DBUILD_FAIRMQ=OFF${CR})")
else()
set(fairmq_summary "${BRed} NO${CR} (enable with ${BMagenta}-DBUILD_FAIRMQ=ON${CR})")
endif()
message(STATUS " ${BWhite}fairmq${CR} ${fairmq_summary}")
if(BUILD_TESTING)
set(tests_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_TESTING=OFF${CR})")
else()
set(tests_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_TESTING=ON${CR})")
endif()
message(STATUS " ${BWhite}tests${CR} ${tests_summary}")
if(BUILD_EXAMPLES)
set(examples_summary "${BGreen}YES${CR} (default, disable with ${BMagenta}-DBUILD_EXAMPLES=OFF${CR})")
else()
set(examples_summary "${BRed} NO${CR} (enable with ${BMagenta}-DBUILD_EXAMPLES=ON${CR})")
endif()
message(STATUS " ${BWhite}examples${CR} ${examples_summary}")
if(BUILD_DOCS)
set(docs_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_DOCS=OFF${CR})")
else()
set(docs_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_DOCS=ON${CR})")
endif()
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
if(BUILD_TIDY_TOOL)
set(sdk_tidy_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_TIDY_TOOL=OFF${CR})")
else()
set(sdk_tidy_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_TIDY_TOOL=ON${CR})")
endif()
message(STATUS " ${BWhite}tidy_tool${CR} ${sdk_tidy_summary}")
endmacro()
macro(fairmq_summary_static_analysis)
message(STATUS " ")
if(RUN_STATIC_ANALYSIS)
list(LENGTH PROJECT_STATIC_ANALYSERS size)
unset(analyser_list)
set(count 0)
foreach(analyser IN LISTS PROJECT_STATIC_ANALYSERS)
if(${analyser}_FOUND)
set(${analyser}_status "${analyser} ${BGreen}YES${CR}")
else()
set(${analyser}_status "${analyser} ${BRed}NO${CR}")
endif()
math(EXPR count "${count} + 1")
string(APPEND analyser_list "${${analyser}_status}")
if(count LESS size)
string(APPEND analyser_list "${BWhite},${CR} ")
endif()
endforeach()
set(static_ana_summary "${BWhite}(${CR}${analyser_list}${BWhite})${CR} (disable with ${BMagenta}-DRUN_STATIC_ANALYSIS=OFF${CR})")
else()
set(static_ana_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DRUN_STATIC_ANALYSIS=ON${CR})")
endif()
message(STATUS " ${Cyan}RUN STATIC ANALYSIS ${static_ana_summary}")
if(BUILD_TIDY_TOOL)
if(RUN_FAIRMQ_TIDY)
set(tidy_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DRUN_FAIRMQ_TIDY=OFF${CR})")
else()
set(tidy_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DRUN_FAIRMQ_TIDY=ON${CR})")
endif()
message(STATUS " ${Cyan}RUN fairmq-tidy ${tidy_summary}")
endif()
endmacro()
macro(fairmq_summary_install_prefix)
message(STATUS " ")
message(STATUS " ${Cyan}INSTALL PREFIX${CR} ${BGreen}${CMAKE_INSTALL_PREFIX}${CR} (change with ${BMagenta}-DCMAKE_INSTALL_PREFIX=...${CR})")
endmacro()
macro(fairmq_summary_debug_mode)
message(STATUS " ")
if(FAIRMQ_DEBUG_MODE)
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BGreen}${FAIRMQ_DEBUG_MODE}${CR} (disable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=OFF${CR})")
else()
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BRed}${FAIRMQ_DEBUG_MODE}${CR} (enable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=ON${CR})")
endif()
endmacro()
macro(fairmq_summary_compile_definitions)
message(STATUS " ")
message(STATUS " ${Cyan}COMPILE DEFINITION VALUE${CR}")
message(STATUS " ${BWhite}FAIRMQ_HAS_STD_FILESYSTEM${CR} ${FAIRMQ_HAS_STD_FILESYSTEM} (overridable with ${BMagenta}-DFAIRMQ_HAS_STD_FILESYSTEM=0|1${CR})")
message(STATUS " ${BWhite}FAIRMQ_HAS_STD_PMR${CR} ${FAIRMQ_HAS_STD_PMR} (overridable with ${BMagenta}-DFAIRMQ_HAS_STD_PMR=0|1${CR})")
if(DEFINED FAIRMQ_CHANNEL_DEFAULT_AUTOBIND)
message(STATUS " ${BWhite}FAIRMQ_CHANNEL_DEFAULT_AUTOBIND${CR} ${FAIRMQ_CHANNEL_DEFAULT_AUTOBIND}")
endif()
endmacro()

View File

@ -1,103 +0,0 @@
################################################################################
# Copyright (C) 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)
#[=======================================================================[.rst:
``fairmq_target_tidy()``
========================
Runs the FairMQ static analyzer ``fairmq-tidy`` on source files in given
target.
.. code-block:: cmake
fairmq_target_tidy(TARGET <target> [EXTRA_ARGS <args>]
[CLANG_EXECUTABLE <clang>])
Registers a custom command that depends on ``<target>`` which runs ``fairmq-tidy``
on the source files that belong to ``<target>``. Optional extra arguments
``<args>`` are passed to the ``fairmq-tidy`` command-line.
Requires ``CMAKE_EXPORT_COMPILE_COMMANDS`` to be enabled.
#]=======================================================================]
function(fairmq_target_tidy)
cmake_parse_arguments(PARSE_ARGV 0 ARG "" "TARGET;EXTRA_ARGS;CLANG_EXECUTABLE" "")
if(NOT CMAKE_EXPORT_COMPILE_COMMANDS)
message(AUTHOR_WARNING "CMAKE_EXPORT_COMPILE_COMMANDS is not enabled. Skipping.")
return()
endif()
if(NOT ARG_TARGET)
message(AUTHOR_WARNING "TARGET argument is required. Skipping.")
return()
endif()
if(NOT TARGET ${ARG_TARGET})
message(AUTHOR_WARNING "Given TARGET argument `${ARG_TARGET}` is not a target. Skipping.")
return()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(NOT fairmq_tidy_clang_resource_dir)
if(ARG_CLANG_EXECUTABLE)
set(clang_exe ${ARG_CLANG_EXECUTABLE})
else()
if(TARGET clang)
get_property(clang_exe TARGET clang PROPERTY LOCATION)
else()
set(clang_exe "clang")
endif()
endif()
execute_process(
COMMAND ${clang_exe} -print-resource-dir
OUTPUT_VARIABLE clang_resource_dir
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(fairmq_tidy_clang_resource_dir ${clang_resource_dir}
CACHE PATH "fairmq_target_tidy() internal state" FORCE)
endif()
list(APPEND ARG_EXTRA_ARGS
"--extra-arg-before=-I${fairmq_tidy_clang_resource_dir}/include")
endif()
if(ARG_EXTRA_ARGS)
set(extra 1)
else()
set(extra 0)
endif()
get_target_property(sources ${ARG_TARGET} SOURCES)
list(FILTER sources INCLUDE REGEX "\.(cpp|cxx)$")
string(REPLACE ":" "-" target_nocolon "${ARG_TARGET}")
set(src_deps)
foreach(source IN LISTS sources)
string(REPLACE "\/" "-" source_noslash "${source}")
set(src_stamp "${CMAKE_CURRENT_BINARY_DIR}/${target_nocolon}-${source_noslash}.fairmq-tidy")
add_custom_command(
OUTPUT ${src_stamp}
COMMAND $<TARGET_FILE:FairMQ::fairmq-tidy> -p=${CMAKE_BINARY_DIR}
$<${extra}:${ARG_EXTRA_ARGS}> ${source}
COMMAND ${CMAKE_COMMAND} -E touch ${src_stamp}
COMMENT "fairmq-tidy: Analyzing source file '${source}' of target '${ARG_TARGET}'"
DEPENDS ${ARG_TARGET}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND_EXPAND_LISTS VERBATIM
)
list(APPEND src_deps ${src_stamp})
endforeach()
if(src_deps)
add_custom_target("fairmq-tidy-${target_nocolon}" ALL DEPENDS ${src_deps})
endif()
endfunction()

74
cmake/FindPMIx.cmake Normal file
View File

@ -0,0 +1,74 @@
################################################################################
# Copyright (C) 2019 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" #
################################################################################
# The "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix" part in all
# the PATH_SUFFIXES is here to be able to find Debian's
# libpmix-dev package. It installs everything below
# /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix
find_path(PMIx_INCLUDE_DIR
NAMES pmix.h
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
PATH_SUFFIXES include lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/include
)
find_path(PMIx_LIBRARY_DIR
NAMES libpmix.dylib libpmix.so
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
PATH_SUFFIXES lib lib64 lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/lib
)
find_library(PMIx_LIBRARY_SHARED
NAMES libpmix.dylib libpmix.so
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
PATH_SUFFIXES lib lib64 lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/lib
)
find_file(PMIx_VERSION_FILE
NAMES pmix_version.h
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
PATH_SUFFIXES include lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/include
)
file(READ "${PMIx_VERSION_FILE}" __version_raw)
string(REGEX MATCH "#define PMIX_VERSION_MAJOR ([0-9]?)L?"
__version_major_raw "${__version_raw}"
)
set(PMIx_VERSION_MAJOR "${CMAKE_MATCH_1}")
string(REGEX MATCH "#define PMIX_VERSION_MINOR ([0-9]?)L?"
__version_minor_raw "${__version_raw}"
)
set(PMIx_VERSION_MINOR "${CMAKE_MATCH_1}")
string(REGEX MATCH "#define PMIX_VERSION_RELEASE ([0-9]?)L?"
__version_patch_raw "${__version_raw}"
)
set(PMIx_VERSION_PATCH "${CMAKE_MATCH_1}")
set(PMIx_VERSION "${PMIx_VERSION_MAJOR}.${PMIx_VERSION_MINOR}.${PMIx_VERSION_PATCH}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PMIx
REQUIRED_VARS
PMIx_INCLUDE_DIR
PMIx_LIBRARY_DIR
PMIx_LIBRARY_SHARED
VERSION_VAR PMIx_VERSION
)
if(NOT TARGET PMIx::libpmix AND PMIx_FOUND)
add_library(PMIx::libpmix SHARED IMPORTED)
set_target_properties(PMIx::libpmix PROPERTIES
IMPORTED_LOCATION ${PMIx_LIBRARY_SHARED}
INTERFACE_INCLUDE_DIRECTORIES ${PMIx_INCLUDE_DIR}
)
endif()

View File

@ -1,5 +1,5 @@
################################################################################
# Copyright (C) 2019-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# #
# This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, #
@ -36,10 +36,17 @@ find_package_handle_standard_args(asio
HANDLE_COMPONENTS
)
if(asio_FOUND AND NOT TARGET asio::asio)
add_library(asio::asio INTERFACE IMPORTED)
set_target_properties(asio::asio PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "ASIO_STANDALONE"
if(asio_FOUND AND asio_BUNDLED)
add_library(bundled_asio_headers INTERFACE)
target_include_directories(bundled_asio_headers INTERFACE
$<BUILD_INTERFACE:${asio_BUILD_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${asio_INSTALL_INCLUDE_DIR}>
)
add_library(asio::headers ALIAS bundled_asio_headers)
endif()
if(asio_FOUND AND NOT TARGET asio::headers)
add_library(asio::headers INTERFACE IMPORTED)
set_target_properties(asio::headers PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${asio_INCLUDE_DIR}"
)
endif()

View File

@ -1,5 +1,5 @@
################################################################################
# Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# Copyright (C) 2017-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# #
# This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, #
@ -20,7 +20,6 @@
# [DEPENDS dep1 [dep2 ...]]
# [LINKS linklib1 [linklib2 ...]
# [INCLUDES dir1 [dir2 ...]
# [ENVIRONMENT var1=op:val1[;var2=op:val2 ...]]
# [TIMEOUT seconds]
# [RUN_SERIAL ON/OFF])
#
@ -49,15 +48,12 @@
#
include(GoogleTest)
if(BUILD_TIDY_TOOL)
include(FairMQTidy)
endif()
function(add_testsuite suitename)
cmake_parse_arguments(testsuite
""
"TIMEOUT;RUN_SERIAL"
"SOURCES;LINKS;DEPENDS;INCLUDES;DEFINITIONS;ENVIRONMENT"
"SOURCES;LINKS;DEPENDS;INCLUDES;DEFINITIONS"
${ARGN}
)
@ -78,12 +74,6 @@ function(add_testsuite suitename)
if(testsuite_DEFINITIONS)
target_compile_definitions("${target}" PUBLIC ${testsuite_DEFINITIONS})
endif()
if(testsuite_ENVIRONMENT AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
set(env "ENVIRONMENT_MODIFICATION" ${testsuite_ENVIRONMENT})
endif()
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
fairmq_target_tidy(TARGET ${target})
endif()
# add_test(NAME "${suitename}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${target})
if(testsuite_TIMEOUT)
@ -101,7 +91,6 @@ function(add_testsuite suitename)
TEST_PREFIX ${suitename}.
PROPERTIES RUN_SERIAL ${testsuite_RUN_SERIAL}
TIMEOUT ${testsuite_TIMEOUT}
${env}
)
list(APPEND ALL_TEST_TARGETS ${target})
@ -131,9 +120,6 @@ function(add_testhelper helpername)
if(testhelper_DEFINITIONS)
target_compile_definitions(${target} PUBLIC ${testhelper_DEFINITIONS})
endif()
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
fairmq_target_tidy(TARGET ${target})
endif()
list(APPEND ALL_TEST_TARGETS ${target})
set(ALL_TEST_TARGETS ${ALL_TEST_TARGETS} PARENT_SCOPE)
@ -168,9 +154,6 @@ function(add_testlib libname)
if(testlib_DEFINITIONS)
target_compile_definitions(${target} PUBLIC ${testlib_DEFINITIONS})
endif()
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
fairmq_target_tidy(TARGET ${target})
endif()
list(APPEND ALL_TEST_TARGETS ${target})
set(ALL_TEST_TARGETS ${ALL_TEST_TARGETS} PARENT_SCOPE)

View File

@ -1,65 +0,0 @@
################################################################################
# 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)
if(NOT DEFINED ${GIT_EXECUTABLE})
find_program(GIT_EXECUTABLE NAMES git)
endif()
# 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 PROJECT)
endif()
if(GIT_EXECUTABLE 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()

4190
cmake/cotire.cmake Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
{
"@context": "https://doi.org/10.5063/schema/codemeta-2.0",
"@type": "SoftwareSourceCode",
"name": "FairMQ",
"description": "C++ Message Queuing Library and Framework",
"license": "./COPYRIGHT",
"datePublished": "2018-04-15",
"developmentStatus": "active",
"softwareVersion": "master",
"releaseNotes": "https://github.com/FairRootGroup/FairMQ/releases",
"codeRepository": "https://github.com/FairRootGroup/FairMQ/",
"readme": "https://github.com/FairRootGroup/FairMQ/#readme",
"issueTracker": "https://github.com/FairRootGroup/FairMQ/issues",
"identifier": "https://doi.org/10.5281/zenodo.1689985",
"maintainer": [
{
"@type": "ResearchOrganisation",
"@id": "https://ror.org/02k8cbn47",
"name": "GSI Helmholtz Centre for Heavy Ion Research"
}
],
"author": [
{
"@type": "Person",
"@id": "https://orcid.org/0000-0002-8071-4497",
"givenName": "Mohammad",
"familyName": "Al-Turany"
},
{
"@type": "Person",
"@id": "https://orcid.org/0000-0003-3787-1910",
"givenName": "Dennis",
"familyName": "Klein"
},
{
"@type": "Person",
"givenName": "Thorsten",
"familyName": "Kollegger"
},
{
"@type": "Person",
"@id": "https://orcid.org/0000-0002-6249-155X",
"givenName": "Alexey",
"familyName": "Rybalchenko"
},
{
"@type": "Person",
"givenName": "Nicolas",
"familyName": "Winckler"
}
],
"contributor": [
{
"@type": "Person",
"givenName": "Laurent",
"familyName": "Aphecetche"
},
{
"@type": "Person",
"givenName": "Sebastien",
"familyName": "Binet"
},
{
"@type": "Person",
"givenName": "Giulio",
"familyName": "Eulisse"
},
{
"@type": "Person",
"givenName": "Radoslaw",
"familyName": "Karabowicz"
},
{
"@type": "Person",
"givenName": "Matthias",
"familyName": "Kretz",
"email": "kretz@kde.org"
},
{
"@type": "Person",
"givenName": "Mikolaj",
"familyName": "Krzewicki"
},
{
"@type": "Person",
"givenName": "Andrey",
"familyName": "Lebedev"
},
{
"@type": "Person",
"givenName": "Teo",
"familyName": "Mrnjavac",
"email": "teo.m@cern.ch"
},
{
"@type": "Person",
"givenName": "Gvozden",
"familyName": "Neskovic"
},
{
"@type": "Person",
"givenName": "Matthias",
"familyName": "Richter"
},
{
"@type": "Person",
"@id": "https://orcid.org/0000-0002-5321-8404",
"givenName": "Christian",
"familyName": "Tacke"
},
{
"@type": "Person",
"givenName": "Florian",
"familyName": "Uhlig"
},
{
"@type": "Person",
"givenName": "Sandro",
"familyName": "Wenzel"
}
]
}

View File

@ -16,18 +16,20 @@ Here is an overview of the device/channel options and when they are applied:
| Property | Applied in |
| --- | --- |
| `severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<fairmq/runDevice.h>`)) |
| `file-severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<fairmq/runDevice.h>`)) |
| `verbosity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<fairmq/runDevice.h>`)) |
| `color` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<fairmq/runDevice.h>`)) |
| `log-to-file` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<fairmq/runDevice.h>`)) |
| `severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
| `file-severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
| `verbosity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
| `color` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
| `log-to-file` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
| `id` | at the end of `fair::mq::State::InitializingDevice` |
| `io-threads` | at the end of `fair::mq::State::InitializingDevice` |
| `transport` | at the end of `fair::mq::State::InitializingDevice` |
| `network-interface` | at the end of `fair::mq::State::InitializingDevice` |
| `init-timeout` | at the end of `fair::mq::State::InitializingDevice` |
| `max-run-time` | at the end of `fair::mq::State::InitializingDevice` |
| `shm-segment-size` | at the end of `fair::mq::State::InitializingDevice` |
| `shm-monitor` | at the end of `fair::mq::State::InitializingDevice` |
| `ofi-size-hint` | at the end of `fair::mq::State::InitializingDevice` |
| `rate` | at the end of `fair::mq::State::InitializingDevice` |
| `session` | at the end of `fair::mq::State::InitializingDevice` |
| `chan.*` | at the end of `fair::mq::State::InitializingDevice` (channel addresses can be also applied during `fair::mq::State::Binding`/`fair::mq::State::Connecting`) |

View File

@ -6,53 +6,8 @@
For unit testing it is often not feasible to boot up a full-blown distributed system with dozens of processes.
In some scenarios it is useful to not even instantiate a `fair::mq::Device` at all. Please see [this example](../test/protocols/_push_pull_multipart.cxx) for single and multi threaded unit test without a device instance. If you store your transport factories and channels on the heap, pls make sure, you destroy the channels before you destroy the related transport factory for proper shutdown. Channels provide all the `Send/Receive` and `New*Message/New*Poller` APIs provided by the device too.
In some scenarios it is useful to not even instantiate a `FairMQDevice` at all. Please see [this example](../test/protocols/_push_pull_multipart.cxx) for single and multi threaded unit test without a device instance. If you store your transport factories and channels on the heap, pls make sure, you destroy the channels before you destroy the related transport factory for proper shutdown. Channels provide all the `Send/Receive` and `New*Message/New*Poller` APIs provided by the device too.
## 4.2 Static Analysis
With `-DBUILD_TIDY_TOOL=ON` you can build the `fairmq-tidy` tool that implements static checks on your source code. To use it, enable the generation of a [compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) in your project via `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` (generates a file `<builddir>/compile_commands.json`):
```
fairmq-tidy -p <builddir> mysourcefile.cpp
```
If you find any issue (e.g. false positives) with this tool, please tell us by opening an issue on github.
### 4.2.1 CMake Integration
When discovering a FairMQ installation in your project, explicitely state, that you want one with the `fairmq-tidy` tool included:
```
find_package(FairMQ COMPONENTS tidy_tool)
```
Now the CMake module [`FairMQTidy.cmake`](../cmake/FairMQTidy.cmake) is available for inclusion:
```
include(FairMQTidy)
```
It provides the CMake function `fairmq_target_tidy()` which attaches appropriate `fairmq-tidy` build rules to each source file contained in the passed library or executable target, e.g. if you have an executable that uses FairMQ:
```
add_executable(myexe mysource1.cpp mysource2.cpp)
target_link_libraries(myexe PRIVATE FairMQ::FairMQ)
fairmq_target_tidy(TARGET myexe)
```
### 4.2.2 Extra Compiler Arguments
On most Linux distros you are likely to use GCC to compile your projects, so the resulting `compile_commands.json` contains the command-line tuned for GCC which might be missing options needed to successfully invoke the Clang frontend which is used internally by `fairmq-tidy`. In general, you can pass extra `clang` options via the following options:
```
--extra-arg=<string> - Additional argument to append to the compiler command line
--extra-arg-before=<string> - Additional argument to prepend to the compiler command line
```
E.g. if standard headers are not found, you can hint the location like this:
```
fairmq-top -p <builddir> --extra-arg-before=-I$(clang -print-resource-dir)/include mysourcefile.cpp
```
TODO Multiple devices in one process.
← [Back](../README.md)

View File

@ -2,7 +2,7 @@
# 1. Device
The components encapsulating the tasks are called **devices** and derive from the common base class `fair::mq::Device`. FairMQ provides ready to use devices to organize the dataflow between the components (without touching the contents of a message), providing functionality like merging and splitting of the data stream (see subdirectory `devices`).
The components encapsulating the tasks are called **devices** and derive from the common base class `FairMQDevice`. FairMQ provides ready to use devices to organize the dataflow between the components (without touching the contents of a message), providing functionality like merging and splitting of the data stream (see subdirectory `devices`).
## 1.1 Topology

View File

@ -35,7 +35,7 @@ Plugin Manager:
see man ld.so(8) for details.
-P [ --plugin ] arg List of plugin names to load in
order,e.g. if the file is called
'libfairmq-plugin-example.so', just list
'libFairMQPlugin_example.so', just list
'example' or 'd:example' here.To load a
prelinked plugin, list 'p:example'
here.
@ -54,8 +54,40 @@ A more complete example which may serve as a start including example CMake code
## 7.3 Provided Plugins
### 7.3.1 PMIx
### 7.3.1 DDS
The [PMIx](https://pmix.org/) plugin enables launching a FairMQ topology with any PMIx capable launcher, e.g. the [Open Run-Time Environment (ORTE) of OpenMPI](https://www.open-mpi.org/doc/v4.0/man1/mpirun.1.php) or the [Slurm workload manager](https://slurm.schedmd.com/srun.html). This experimental plugin has been last released in v1.4.56 and is removed in v1.5+. For now there are no plans to pick up development of it again.
When launching a FairMQ topology via [DDS](http://dds.gsi.de/) the DDS plugin enables FairMQ devices to interact with DDS' custom command and property subsystems - enable the plugin by passing `-P dds` on the command line.
Via the property subsystem a FairMQ topology may exchange channel connection data (essentially to do service discovery) needed to connect/bind all FairMQ channels appropriately. DDS is highly optimized for this use case. See [examples/dds](examples/dds/README.md) for more details.
Via the custom command subsystem a FairMQ device can receive a number of commands. FairMQ provides a convenient command line tool `fairmq-dds-command-ui` that allows interactive or scripted control of a running FairMQ topology managed via DDS. If one develops directly against the custom command DDS API, the following table lists all the commands the DDS plugin currently understands:
| Custom Command | Response | Error | Description |
| --- | --- | --- | --- |
| `check-state` | `<ID>: <STATE> (pid: <PID>)` | n/a | Query current device state, see state machine for possible states |
| `dump-config` | `(<ID>: <PKEY> -> <PVALUE>\n)+` | n/a | Query current device config (list property key/value pairs) |
| `INIT DEVICE` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `BIND` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `CONNECT` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `INIT TASK` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `RUN` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `STOP` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `RESET TASK` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `RESET DEVICE` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `END` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
| `subscribe-to-heartbeats` | `heartbeat-subscription: <ID>,OK` | n/a | Subscribe to heartbeats |
| on heartbeat subscription | `heartbeat: <ID>,<PID>` | n/a | Heartbeat every 100ms |
| `unsubscribe-from-heartbeats` | `heartbeat-unsubscription: <ID>,OK` | n/a | Unsubscribe from heartbeats |
| `subscribe-to-state-changes` | `state-changes-subscription: <ID>,OK` | n/a | Subscribe to state changes |
| on state changes subscription | `state-change: <ID>,<STATE>` | n/a | State change notification |
| `unsubscribe-from-state-changes` | `state-changes-unsubscription: <ID>,OK` | n/a | Unsubscribe from state changes |
If unknown commands are received the plugin will print a warning.
### 7.3.2 PMIx
The [PMIx](https://pmix.org/) plugin enables launching a FairMQ topology with any PMIx capable launcher, e.g. the [Open Run-Time Environment (ORTE) of OpenMPI](https://www.open-mpi.org/doc/v4.0/man1/mpirun.1.php) or the [Slurm workload manager](https://slurm.schedmd.com/srun.html). This plugin is not (yet) very mature and serves as a proof of concept at the moment.
TODO example usage
← [Back](../README.md)

34
docs/SDK.md Normal file
View File

@ -0,0 +1,34 @@
← [Back](../README.md)
# 8. Controller SDK
The FairMQ Controller Software Development Kit (`-DBUILD_SDK=ON`) contains a (as of today still experimental) set of C++ APIs that provide essential functionality to the implementer of a global controller.
The FairMQ core library only provides two local controllers - `static` (a fixed sequence of state transitions) and `interactive` (a read-eval-print-loop which reads keyboard commands from standard input). A local controller only knows how steer a single [FairMQ device](Device.md) - in fact, it runs in a thread within the device process.
A global controller has knowledge about the full topology of connected FairMQ devices. Its responsibility is to facilitate the lifecycle of a distributed FairMQ-based application (*executing a topology*), such as
* allocating/releasing compute resources from a resource management system,
* launching/setting up the run-time environment and the FairMQ devices,
* driving the device state machines in lock-step across the full topology,
* pushing the device configuration,
* monitoring (some aspects of the application's) operation,
* and handling/reporting (some) error cases.
The low-level hook to integrate FairMQ devices with such a global contoller is the [plugin mechanism](Plugins.md) in the FairMQ core library. The FairMQ Controller SDK provides C++ APIs that communicate to the endpoints exposed by such a FairMQ plugin.
At the moment, the Controller SDK only supports [DDS](https://dds.gsi.de) as resource manager and run-time environment. A second implementation based on [PMIx](https://pmix.org/) (targeting its implementation in [Slurm](https://slurm.schedmd.com/documentation.html) and [OpenRTE](https://www-lb.open-mpi.org/papers/euro-pvmmpi-2005-orte/)) is in development.
The following section give a short overview on the APIs provided.
## RMS and run-time environment
The classes [`fair::mq::sdk::DDSEnvironment`](../fairmq/sdk/DDSEnvironment.h), [`fair::mq::sdk::DDSSession`](../fairmq/sdk/DDSSession.h), and [`fair::mq::sdk::DDSTopology`](../fairmq/sdk/DDSTopology.h) are thin wrappers of most of the synchronous APIs exposed by DDS ([`dds::tools_api`](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1tools__api.html) and [`dds::topology_api`](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1topology__api.html)). E.g. they allow to [start a DDS session](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L26-L28), [allocate resources](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L34) and [launch a topology](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L39) from a C++ program.
## Driving the global state machine
The class [`fair::mq::sdk::Topology`](../fairmq/sdk/Topology.h) adds a FairMQ-specific view on an existing DDS session that is executing a topology of FairMQ devices. One can e.g. [initiate a state transition on all devices in the topology simultaneously](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L48-L49). This topology transition completes once a topology-wide barrier is passed (all devices completed the transition). This effectively exposes the device state machine as a topology state machine. The implementation is based on remote procedure calls over the [DDS intercom service](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1intercom__api.html) between the controller and the DDS plugin shipped with FairMQ (`-DBUILD_DDS_PLUGIN=ON`).
For future versions of the SDK new APIs are planned to inspect and modify the device configurations and also operate only on subsets of a given topology.
← [Back](../README.md)

View File

@ -27,34 +27,34 @@ The next table shows the supported address types for each transport implementati
## 2.1 Message
Devices transport data between each other in form of `fair::mq::Message`s. These can be filled with arbitrary content. Message can be initialized in three different ways by calling `NewMessage()`:
Devices transport data between each other in form of `FairMQMessage`s. These can be filled with arbitrary content. Message can be initialized in three different ways by calling `NewMessage()`:
```cpp
fair::mq::MessagePtr NewMessage() const;
FairMQMessagePtr NewMessage() const;
```
**with no parameters**: Initializes an empty message (typically used for receiving).
```cpp
fair::mq::MessagePtr NewMessage(const size_t size) const;
FairMQMessagePtr NewMessage(const size_t size) const;
```
**given message size**: Initializes message body with a given size. Fill the created contents via buffer pointer.
```cpp
using fairmq_free_fn = void(void* data, void* hint);
fair::mq::MessagePtr NewMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) const;
FairMQMessagePtr NewMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) const;
```
**given existing buffer and a size**: Initialize the message from an existing buffer. In case of ZeroMQ this is a zero-copy operation.
Additionally, FairMQ provides two more message factories for convenience:
```cpp
template<typename T>
fair::mq::MessagePtr NewSimpleMessage(const T& data) const
FairMQMessagePtr NewSimpleMessage(const T& data) const
```
**copy and own**: Copy the `data` argument into the returned message and take ownership (free memory after message is sent). This interface is useful for small, [trivially copyable](http://en.cppreference.com/w/cpp/concept/TriviallyCopyable) data.
```cpp
template<typename T>
fair::mq::MessagePtr NewStaticMessage(const T& data) const
FairMQMessagePtr NewStaticMessage(const T& data) const
```
**point to existing memory**: The returned message will point to the `data` argument, but not take ownership (someone else must destruct this variable). Make sure that `data` lives long enough to be successfully sent. This interface is most useful for third party managed, contiguous memory (Be aware of shallow types with internal pointer references! These will not be sent.)
@ -65,19 +65,19 @@ The component of a program, that is reponsible for the allocation or destruction
After queuing a message for sending in FairMQ, the transport takes ownership over the message body and will free it with `free()` after it is no longer used. A callback can be passed to the message object, to be called instead of the destruction with `free()` (for initialization via buffer+size).
```cpp
static void fair::mq::NoCleanup(void* /*data*/, void* /*obj*/) {}
static void FairMQNoCleanup(void* /*data*/, void* /*obj*/) {}
template<typename T>
static void fair::mq::SimpleMsgCleanup(void* /*data*/, void* obj) { delete static_cast<T*>(obj); }
static void FairMQSimpleMsgCleanup(void* /*data*/, void* obj) { delete static_cast<T*>(obj); }
```
For convenience, two common deleter callbacks are already defined in the `fair::mq::TransportFactory` class to aid the user in controlling ownership of the data.
For convenience, two common deleter callbacks are already defined in the `FairMQTransportFactory` class to aid the user in controlling ownership of the data.
## 2.2 Channel
A channel represents a communication endpoint in FairMQ. Usage is similar to a traditional Unix network socket. A device usually contains a number of channels that can either listen for incoming connections from channels of other devices or they can connect to other listening channels. Channels are organized by a channel name and a subchannel index.
```cpp
const fair::mq::Channel& GetChannel(const std::string& channelName, const int index = 0) const;
const FairMQChannel& GetChannel(const std::string& channelName, const int index = 0) const;
```
All subchannels with a common channel name need to be of the same transport type.
@ -87,7 +87,7 @@ All subchannels with a common channel name need to be of the same transport type
A poller allows to wait on multiple channels either to receive or send a message.
```cpp
fair::mq::PollerPtr NewPoller(const std::vector<const fair::mq::Channel*>& channels)
FairMQPollerPtr NewPoller(const std::vector<const FairMQChannel*>& channels)
```
**list channels**: This poller waits on all supplied channels. Currently, it is limited to channels of the same transport type only.

View File

@ -1,9 +1,60 @@
################################################################################
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# Copyright (C) 2014 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" #
################################################################################
add_example(NAME 1-1 DEVICE sampler sink)
add_library(Example11Lib STATIC
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(Example11Lib PUBLIC FairMQ)
add_executable(fairmq-ex-1-1-sampler runSampler.cxx)
target_link_libraries(fairmq-ex-1-1-sampler PRIVATE Example11Lib)
add_executable(fairmq-ex-1-1-sink runSink.cxx)
target_link_libraries(fairmq-ex-1-1-sink PRIVATE Example11Lib)
add_custom_target(Example11 DEPENDS fairmq-ex-1-1-sampler fairmq-ex-1-1-sink)
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh)
# test
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh)
add_test(NAME Example.1-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh zeromq)
set_tests_properties(Example.1-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
add_test(NAME Example.1-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh shmem)
set_tests_properties(Example.1-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
# install
install(
TARGETS
fairmq-ex-1-1-sampler
fairmq-ex-1-1-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-1-1.sh
)

View File

@ -3,7 +3,7 @@
A simple topology of two devices - **Sampler** and **Sink**. **Sampler** sends data to **Sink** via the **PUSH-PULL** pattern.
`sampler.cxx` and `sink.cxx` configure and run the devices.
`runSampler.cxx` and `runSink.cxx` configure and run the devices.
The executables take two command line parameters: `--id` and `--channel-config`. The value of `--id` should be a unique identifier and the value for `--channel-config` is the configuration of the communication channel. .

59
examples/1-1/Sampler.cxx Normal file
View File

@ -0,0 +1,59 @@
/********************************************************************************
* Copyright (C) 2014-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" *
********************************************************************************/
#include "Sampler.h"
using namespace std;
namespace example_1_1
{
Sampler::Sampler()
: fText()
, fMaxIterations(0)
, fNumIterations(0)
{}
void Sampler::InitTask()
{
// Get the fText and fMaxIterations values from the command line options (via fConfig)
fText = fConfig->GetProperty<string>("text");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool Sampler::ConditionalRun()
{
// create a copy of the data with new(), that will be deleted after the transfer is complete
string* text = new string(fText);
// create message object with a pointer to the data buffer, its size,
// custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer
FairMQMessagePtr msg(NewMessage(
const_cast<char*>(text->c_str()),
text->length(),
[](void* /*data*/, void* object) { delete static_cast<string*>(object); },
text));
LOG(info) << "Sending \"" << fText << "\"";
// in case of error or transfer interruption, return false to go to the Ready state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
if (Send(msg, "data") < 0) {
return false;
} else if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
return true;
}
Sampler::~Sampler() {}
} // namespace example_1_1

42
examples/1-1/Sampler.h Normal file
View File

@ -0,0 +1,42 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sampler.h
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#ifndef FAIRMQEXAMPLE11SAMPLER_H
#define FAIRMQEXAMPLE11SAMPLER_H
#include <string>
#include "FairMQDevice.h"
namespace example_1_1
{
class Sampler : public FairMQDevice
{
public:
Sampler();
virtual ~Sampler();
protected:
std::string fText;
uint64_t fMaxIterations;
uint64_t fNumIterations;
void InitTask() override;
bool ConditionalRun() override;
};
} // namespace example_1_1
#endif /* FAIRMQEXAMPLE11SAMPLER_H */

54
examples/1-1/Sink.cxx Normal file
View File

@ -0,0 +1,54 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sink.cxx
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#include "Sink.h"
using namespace std;
namespace example_1_1
{
Sink::Sink()
: fMaxIterations(0)
, fNumIterations(0)
{
// register a handler for data arriving on "data" channel
OnData("data", &Sink::HandleData);
}
void Sink::InitTask()
{
// Get the fMaxIterations value from the command line options (via fConfig)
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
// handler is called whenever a message arrives on "data", with a reference to the message and a
// sub-channel index (here 0)
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
{
LOG(info) << "Received: \"" << string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
// return true if you want the handler to be called again (otherwise return false go to the
// Ready state)
return true;
}
Sink::~Sink() {}
} // namespace example_1_1

40
examples/1-1/Sink.h Normal file
View File

@ -0,0 +1,40 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sink.h
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#ifndef FAIRMQEXAMPLE11SINK_H
#define FAIRMQEXAMPLE11SINK_H
#include "FairMQDevice.h"
namespace example_1_1
{
class Sink : public FairMQDevice
{
public:
Sink();
virtual ~Sink();
protected:
virtual void InitTask();
bool HandleData(FairMQMessagePtr&, int);
private:
uint64_t fMaxIterations;
uint64_t fNumIterations;
};
} // namespace example_1_1
#endif /* FAIRMQEXAMPLE11SINK_H */

View File

@ -0,0 +1,24 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Sampler.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("text", bpo::value<std::string>()->default_value("Hello"), "Text to send out")
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_1_1::Sampler();
}

23
examples/1-1/runSink.cxx Normal file
View File

@ -0,0 +1,23 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Sink.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_1_1::Sink();
}

View File

@ -1,69 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <string>
namespace bpo = boost::program_options;
struct Sampler : fair::mq::Device
{
void InitTask() override
{
// Get the fText and fMaxIterations values from the command line options (via fConfig)
fText = fConfig->GetProperty<std::string>("text");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool ConditionalRun() override
{
// create a copy of the data with new(), that will be deleted after the transfer is complete
std::string* text = new std::string(fText);
// create message object with a pointer to the data buffer, its size,
// custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer
fair::mq::MessagePtr msg(NewMessage(
const_cast<char*>(text->c_str()),
text->length(),
[](void* /*data*/, void* object) { delete static_cast<std::string*>(object); },
text));
LOG(info) << "Sending \"" << fText << "\"";
// in case of error or transfer interruption, return false to go to the Ready state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
if (Send(msg, "data") < 0) {
return false;
} else if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
return true;
}
private:
std::string fText;
uint64_t fMaxIterations = 0;
uint64_t fNumIterations = 0;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("text", bpo::value<std::string>()->default_value("Hello"), "Text to send out")
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Sampler>();
}

View File

@ -1,58 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <string>
namespace bpo = boost::program_options;
struct Sink : fair::mq::Device
{
Sink()
{
// register a handler for data arriving on "data" channel
OnData("data", &Sink::HandleData);
}
void InitTask() override
{
// Get the fMaxIterations value from the command line options (via fConfig)
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool HandleData(fair::mq::MessagePtr& msg, int)
{
LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
// return true if you want the handler to be called again (otherwise return false go to the
// Ready state)
return true;
}
private:
uint64_t fMaxIterations = 0;
uint64_t fNumIterations = 0;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Sink>();
}

View File

@ -1,7 +1,5 @@
#!/bin/bash
set -e
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
transport="zeromq"
@ -10,24 +8,20 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1
fi
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan="data"
chanAddr="/tmp/fmq_$session""_""$chan""_""$transport"
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
# setup a trap to kill everything if the test fails/timeouts
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; rm $chanAddr; exit 0' TERM
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID;' TERM
SAMPLER="fairmq-ex-1-1-sampler"
SAMPLER+=" --id sampler1"
SAMPLER+=" --rate 1"
SAMPLER+=" --transport $transport"
SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --session $session"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --shm-monitor true"
SAMPLER+=" --session $SESSION"
SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 1"
SAMPLER+=" --channel-config name=$chan,type=push,method=bind,address=ipc://$chanAddr,rateLogging=0"
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://*:5555,rateLogging=0"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$!
@ -35,19 +29,13 @@ SINK="fairmq-ex-1-1-sink"
SINK+=" --id sink1"
SINK+=" --transport $transport"
SINK+=" --verbosity veryhigh"
SINK+=" --session $session"
SINK+=" --shm-segment-size 100000000"
SINK+=" --shm-monitor true"
SINK+=" --session $SESSION"
SINK+=" --control static --color false"
SINK+=" --max-iterations 1"
SINK+=" --channel-config name=$chan,type=pull,method=connect,address=ipc://$chanAddr,rateLogging=0"
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://localhost:5555,rateLogging=0"
@CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$!
# wait for sampler and sink to finish
wait $SAMPLER_PID
wait $SINK_PID
set +e
rm $chanAddr
exit 0

View File

@ -1,9 +1,75 @@
################################################################################
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# Copyright (C) 2014 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" #
################################################################################
add_example(NAME 1-n-1 DEVICE sampler processor sink CONFIG)
add_library(Example1N1Lib STATIC
"Sampler.cxx"
"Sampler.h"
"Processor.cxx"
"Processor.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(Example1N1Lib PUBLIC FairMQ)
add_executable(fairmq-ex-1-n-1-sampler runSampler.cxx)
target_link_libraries(fairmq-ex-1-n-1-sampler PRIVATE Example1N1Lib)
add_executable(fairmq-ex-1-n-1-processor runProcessor.cxx)
target_link_libraries(fairmq-ex-1-n-1-processor PRIVATE Example1N1Lib)
add_executable(fairmq-ex-1-n-1-sink runSink.cxx)
target_link_libraries(fairmq-ex-1-n-1-sink PRIVATE Example1N1Lib)
add_custom_target(Example1N1 DEPENDS fairmq-ex-1-n-1-sampler fairmq-ex-1-n-1-processor fairmq-ex-1-n-1-sink)
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(EX_CONF_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-1-n-1.json ${CMAKE_CURRENT_BINARY_DIR}/ex-1-n-1.json)
# test
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh)
add_test(NAME Example.1-n-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh zeromq)
set_tests_properties(Example.1-n-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
add_test(NAME Example.1-n-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh shmem)
set_tests_properties(Example.1-n-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
# install
install(
TARGETS
fairmq-ex-1-n-1-sampler
fairmq-ex-1-n-1-processor
fairmq-ex-1-n-1-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
set(EX_CONF_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_DATADIR})
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-1-n-1.sh
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-1-n-1.json
DESTINATION ${PROJECT_INSTALL_DATADIR}
)

View File

@ -0,0 +1,53 @@
/********************************************************************************
* Copyright (C) 2014 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 "Processor.h"
#include <string>
using namespace std;
namespace example_1_n_1
{
Processor::Processor()
{
OnData("data1", &Processor::HandleData);
}
bool Processor::HandleData(FairMQMessagePtr& msg, int /*index*/)
{
LOG(info) << "Received data, processing...";
// Modify the received string
string* text = new std::string(static_cast<char*>(msg->GetData()), msg->GetSize());
*text += " (modified by " + fId + ")";
// create message object with a pointer to the data buffer,
// its size,
// custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer
FairMQMessagePtr msg2(NewMessage(const_cast<char*>(text->c_str()),
text->length(),
[](void* /*data*/, void* object) { delete static_cast<string*>(object); },
text));
// Send out the output message
if (Send(msg2, "data2") < 0)
{
return false;
}
return true;
}
Processor::~Processor()
{
}
} // namespace example_1_n_1

View File

@ -0,0 +1,29 @@
/********************************************************************************
* Copyright (C) 2014 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 FAIRMQEXAMPLE1N1PROCESSOR_H_
#define FAIRMQEXAMPLE1N1PROCESSOR_H_
#include "FairMQDevice.h"
namespace example_1_n_1
{
class Processor : public FairMQDevice
{
public:
Processor();
virtual ~Processor();
protected:
bool HandleData(FairMQMessagePtr&, int);
};
} // namespace example_1_n_1
#endif /* FAIRMQEXAMPLE1N1PROCESSOR_H_ */

View File

@ -0,0 +1,68 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sampler.cpp
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#include <thread> // this_thread::sleep_for
#include <chrono>
#include "Sampler.h"
using namespace std;
namespace example_1_n_1
{
Sampler::Sampler()
: fText()
, fMaxIterations(0)
, fNumIterations(0)
{
}
void Sampler::InitTask()
{
// Get the fText and fMaxIterations values from the command line options (via fConfig)
fText = fConfig->GetProperty<string>("text");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool Sampler::ConditionalRun()
{
// Initializing message with NewStaticMessage will avoid copy
// but won't delete the data after the sending is completed.
FairMQMessagePtr msg(NewStaticMessage(fText));
LOG(info) << "Sending \"" << fText << "\"";
// in case of error or transfer interruption, return false to go to IDLE state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
if (Send(msg, "data1") < 0)
{
return false;
}
else if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
{
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
this_thread::sleep_for(chrono::seconds(1));
return true;
}
Sampler::~Sampler()
{
}
} // namespace example_1_n_1

42
examples/1-n-1/Sampler.h Normal file
View File

@ -0,0 +1,42 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sampler.h
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#ifndef FAIRMQEXAMPLE1N1SAMPLER_H_
#define FAIRMQEXAMPLE1N1SAMPLER_H_
#include <string>
#include "FairMQDevice.h"
namespace example_1_n_1
{
class Sampler : public FairMQDevice
{
public:
Sampler();
virtual ~Sampler();
protected:
std::string fText;
uint64_t fMaxIterations;
uint64_t fNumIterations;
virtual void InitTask();
virtual bool ConditionalRun();
};
} // namespace example_1_n_1
#endif /* FAIRMQEXAMPLE1N1SAMPLER_H_ */

55
examples/1-n-1/Sink.cxx Normal file
View File

@ -0,0 +1,55 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sink.cxx
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#include "Sink.h"
using namespace std;
namespace example_1_n_1
{
Sink::Sink()
: fMaxIterations(0)
, fNumIterations(0)
{
// register a handler for data arriving on "data2" channel
OnData("data2", &Sink::HandleData);
}
void Sink::InitTask()
{
// Get the fMaxIterations value from the command line options (via fConfig)
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
// handler is called whenever a message arrives on "data2", with a reference to the message and a sub-channel index (here 0)
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
{
LOG(info) << "Received: \"" << string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
{
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
// return true if want to be called again (otherwise return false go to IDLE state)
return true;
}
Sink::~Sink()
{
}
} // namespace example_1_n_1

40
examples/1-n-1/Sink.h Normal file
View File

@ -0,0 +1,40 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sink.h
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#ifndef FAIRMQEXAMPLE1N1SINK_H
#define FAIRMQEXAMPLE1N1SINK_H
#include "FairMQDevice.h"
namespace example_1_n_1
{
class Sink : public FairMQDevice
{
public:
Sink();
virtual ~Sink();
protected:
virtual void InitTask();
bool HandleData(FairMQMessagePtr&, int);
private:
uint64_t fMaxIterations;
uint64_t fNumIterations;
};
} // namespace example_1_n_1
#endif /* FAIRMQEXAMPLE1N1SINK_H */

View File

@ -1,56 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <string>
namespace bpo = boost::program_options;
struct Processor : fair::mq::Device
{
Processor()
{
OnData("data1", &Processor::HandleData);
}
bool HandleData(fair::mq::MessagePtr& msg, int)
{
LOG(info) << "Received data, processing...";
// Modify the received string
std::string* text = new std::string(static_cast<char*>(msg->GetData()), msg->GetSize());
*text += " (modified by " + fId + ")";
// create message object with a pointer to the data buffer,
// its size,
// custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer
fair::mq::MessagePtr msg2(NewMessage(const_cast<char*>(text->c_str()),
text->length(),
[](void* /*data*/, void* object) { delete static_cast<std::string*>(object); },
text));
// Send out the output message
if (Send(msg2, "data2") < 0) {
return false;
}
return true;
}
};
void addCustomOptions(bpo::options_description& /*options*/)
{
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Processor>();
}

View File

@ -0,0 +1,21 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Processor.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& /*options*/)
{
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_1_n_1::Processor();
}

View File

@ -0,0 +1,24 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Sampler.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("text", bpo::value<std::string>()->default_value("Hello"), "Text to send out")
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_1_n_1::Sampler();
}

View File

@ -0,0 +1,23 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Sink.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_1_n_1::Sink();
}

View File

@ -1,65 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <string>
#include <thread> // this_thread::sleep_for
#include <chrono>
namespace bpo = boost::program_options;
struct Sampler : fair::mq::Device
{
void InitTask() override
{
// Get the fText and fMaxIterations values from the command line options (via fConfig)
fText = fConfig->GetProperty<std::string>("text");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool ConditionalRun() override
{
// Initializing message with NewStaticMessage will avoid copy
// but won't delete the data after the sending is completed.
fair::mq::MessagePtr msg(NewStaticMessage(fText));
LOG(info) << "Sending \"" << fText << "\"";
// in case of error or transfer interruption, return false to go to IDLE state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
if (Send(msg, "data1") < 0) {
return false;
} else if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
return true;
}
private:
std::string fText;
uint64_t fMaxIterations = 0;
uint64_t fNumIterations = 0;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("text", bpo::value<std::string>()->default_value("Hello"), "Text to send out")
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Sampler>();
}

View File

@ -1,57 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <string>
namespace bpo = boost::program_options;
struct Sink : fair::mq::Device
{
Sink()
{
// register a handler for data arriving on "data2" channel
OnData("data2", &Sink::HandleData);
}
void InitTask() override
{
// Get the fMaxIterations value from the command line options (via fConfig)
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool HandleData(fair::mq::MessagePtr& msg, int)
{
LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
// return true if want to be called again (otherwise return false go to IDLE state)
return true;
}
private:
uint64_t fMaxIterations = 0;
uint64_t fNumIterations = 0;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Sink>();
}

View File

@ -1,7 +1,5 @@
#!/bin/bash
set -e
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
transport="zeromq"
@ -10,26 +8,20 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1
fi
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan1="data1"
chan2="data2"
chan1Addr="/tmp/fmq_$session""_""$chan1""_""$transport"
chan2Addr="/tmp/fmq_$session""_""$chan2""_""$transport"
ex2config="@CMAKE_CURRENT_BINARY_DIR@/ex-1-n-1.json"
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
# setup a trap to kill everything if the test fails/timeouts
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $PROCESSOR1_PID; kill -TERM $PROCESSOR2_PID; wait $SAMPLER_PID; wait $SINK_PID; wait $PROCESSOR1_PID; wait $PROCESSOR2_PID; rm $chan1Addr; rm $chan2Addr; exit 0' TERM
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $PROCESSOR1_PID; kill -TERM $PROCESSOR2_PID; wait $SAMPLER_PID; wait $SINK_PID; wait $PROCESSOR1_PID; wait $PROCESSOR2_PID;' TERM
SAMPLER="fairmq-ex-1-n-1-sampler"
SAMPLER+=" --id sampler1"
SAMPLER+=" --transport $transport"
SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --session $session"
SAMPLER+=" --severity debug"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --shm-monitor true"
SAMPLER+=" --session $SESSION"
SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 2"
SAMPLER+=" --channel-config name=$chan1,type=push,method=bind,address=ipc://$chan1Addr,rateLogging=0"
SAMPLER+=" --mq-config $ex2config"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$!
@ -37,13 +29,10 @@ PROCESSOR1="fairmq-ex-1-n-1-processor"
PROCESSOR1+=" --id processor1"
PROCESSOR1+=" --transport $transport"
PROCESSOR1+=" --verbosity veryhigh"
PROCESSOR1+=" --session $session"
PROCESSOR1+=" --severity debug"
PROCESSOR1+=" --shm-segment-size 100000000"
PROCESSOR1+=" --shm-monitor true"
PROCESSOR1+=" --session $SESSION"
PROCESSOR1+=" --control static --color false"
PROCESSOR1+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr,rateLogging=0"
PROCESSOR1+=" name=$chan2,type=push,method=connect,address=ipc://$chan2Addr,rateLogging=0"
PROCESSOR1+=" --mq-config $ex2config"
PROCESSOR1+=" --config-key processor"
@CMAKE_CURRENT_BINARY_DIR@/$PROCESSOR1 &
PROCESSOR1_PID=$!
@ -51,13 +40,10 @@ PROCESSOR2="fairmq-ex-1-n-1-processor"
PROCESSOR2+=" --id processor2"
PROCESSOR2+=" --transport $transport"
PROCESSOR2+=" --verbosity veryhigh"
PROCESSOR2+=" --session $session"
PROCESSOR2+=" --severity debug"
PROCESSOR2+=" --shm-segment-size 100000000"
PROCESSOR2+=" --shm-monitor true"
PROCESSOR2+=" --session $SESSION"
PROCESSOR2+=" --control static --color false"
PROCESSOR2+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr,rateLogging=0"
PROCESSOR2+=" name=$chan2,type=push,method=connect,address=ipc://$chan2Addr,rateLogging=0"
PROCESSOR2+=" --mq-config $ex2config"
PROCESSOR2+=" --config-key processor"
@CMAKE_CURRENT_BINARY_DIR@/$PROCESSOR2 &
PROCESSOR2_PID=$!
@ -65,13 +51,10 @@ SINK="fairmq-ex-1-n-1-sink"
SINK+=" --id sink1"
SINK+=" --transport $transport"
SINK+=" --verbosity veryhigh"
SINK+=" --session $session"
SINK+=" --severity debug"
SINK+=" --shm-segment-size 100000000"
SINK+=" --shm-monitor true"
SINK+=" --session $SESSION"
SINK+=" --control static --color false"
SINK+=" --max-iterations 2"
SINK+=" --channel-config name=$chan2,type=pull,method=bind,address=ipc://$chan2Addr,rateLogging=0"
SINK+=" --mq-config $ex2config"
@CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$!
@ -86,7 +69,3 @@ kill -SIGINT $PROCESSOR2_PID
# wait for everything to finish
wait $PROCESSOR1_PID
wait $PROCESSOR2_PID
set +e
rm $chan1Addr; rm $chan2Addr
exit 0

View File

@ -1,145 +1,15 @@
################################################################################
# Copyright (C) 2018-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# 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" #
################################################################################
set(exe_prefix "fairmq-ex")
set(script_prefix "fairmq-start-ex")
set(test_script_prefix "test-ex")
set(testsuite "Example")
set(transports "zeromq" "shmem")
function(add_example)
cmake_parse_arguments(PARSE_ARGV 0 ARG
"CONFIG;NO_TRANSPORT;NO_TEST"
"NAME"
"DEVICE;VARIANT;TRANSPORT;SCRIPT"
)
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unexpected unparsed arguments: ${ARG_UNPARSED_ARGUMENTS}")
endif()
if(ARG_NAME)
set(name ${ARG_NAME})
else()
message(FATAL_ERROR "NAME arg is required")
endif()
if(ENABLE_SANITIZER_LEAK AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
get_filename_component(lsan_supps "${CMAKE_SOURCE_DIR}/test/leak_sanitizer_suppressions.txt" ABSOLUTE)
set(lsan_options "LSAN_OPTIONS=set:suppressions=${lsan_supps}")
endif()
if(ARG_DEVICE)
set(exe_targets)
foreach(device IN LISTS ARG_DEVICE)
set(exe "${exe_prefix}-${name}-${device}")
list(APPEND exe_targets ${exe})
add_executable(${exe} "${device}.cxx")
target_link_libraries(${exe} PRIVATE FairMQ)
endforeach()
endif()
if(ARG_TRANSPORT)
set(transports ${ARG_TRANSPORT})
endif()
if(ARG_SCRIPT)
set(scripts ${ARG_SCRIPT})
else()
set(scripts ${ARG_NAME})
endif()
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
if(ARG_CONFIG)
set(EX_CONF_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
foreach(script IN LISTS scripts)
set(script_file "${script_prefix}-${script}.sh")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${script_file}.in" "${CMAKE_CURRENT_BINARY_DIR}/${script_file}" @ONLY)
endforeach()
if(ARG_CONFIG)
set(config "ex-${name}.json")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${config}" "${CMAKE_CURRENT_BINARY_DIR}/${config}")
endif()
# test
if(NOT ARG_NO_TEST)
set(test_script "${test_script_prefix}-${name}.sh")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${test_script}.in" "${CMAKE_CURRENT_BINARY_DIR}/${test_script}")
if(ARG_NO_TRANSPORT)
set(test "${testsuite}.${name}.${transport}")
add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${test_script} ${transport})
set_tests_properties(${test} PROPERTIES TIMEOUT "30")
if(lsan_options)
set_tests_properties(${test} PROPERTIES ENVIRONMENT_MODIFICATION ${lsan_options})
endif()
else()
foreach(transport IN LISTS transports)
if(ARG_VARIANT)
foreach(variant IN LISTS ARG_VARIANT)
set(test "${testsuite}.${name}.${variant}.${transport}")
add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${test_script} ${transport} ${variant})
set_tests_properties(${test} PROPERTIES TIMEOUT "30")
if(lsan_options)
set_tests_properties(${test} PROPERTIES ENVIRONMENT_MODIFICATION ${lsan_options})
endif()
endforeach()
else()
set(test "${testsuite}.${name}.${transport}")
add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${test_script} ${transport})
set_tests_properties(${test} PROPERTIES TIMEOUT "30")
if(lsan_options)
set_tests_properties(${test} PROPERTIES ENVIRONMENT_MODIFICATION ${lsan_options})
endif()
endif()
endforeach()
endif()
endif()
# install
install(
TARGETS ${exe_targets}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
if(ARG_CONFIG)
set(EX_CONF_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_DATADIR})
endif()
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
foreach(script IN LISTS scripts)
set(script_file "${script_prefix}-${script}.sh")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${script_file}.in" "${CMAKE_CURRENT_BINARY_DIR}/${script_file}_install" @ONLY)
install(
PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${script_file}_install"
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME ${script_file}
)
endforeach()
if(ARG_CONFIG)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${config}
DESTINATION ${PROJECT_INSTALL_DATADIR}
)
endif()
endfunction()
add_subdirectory(1-1)
add_subdirectory(1-n-1)
add_subdirectory(builtin-devices)
add_subdirectory(copypush)
add_subdirectory(custom-controller)
add_subdirectory(dds)
add_subdirectory(multipart)
add_subdirectory(multiple-channels)

View File

@ -1,11 +1,40 @@
################################################################################
# Copyright (C) 2014-2023 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" #
################################################################################
################################################################################
# Copyright (C) 2014 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" #
################################################################################
add_example(NAME builtin-devices
VARIANT single_msg multipart
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh)
# test
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh)
add_test(NAME Example.BuiltinDevices.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq)
set_tests_properties(Example.BuiltinDevices.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
add_test(NAME Example.BuiltinDevices.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem)
set_tests_properties(Example.BuiltinDevices.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
add_test(NAME Example.BuiltinDevices.multipart.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq true 2)
set_tests_properties(Example.BuiltinDevices.multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
add_test(NAME Example.BuiltinDevices.multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem true 2)
set_tests_properties(Example.BuiltinDevices.multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
# install
# configure run script with different executable paths for build and for install directories
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-builtin-devices.sh
)

View File

@ -1,9 +1,9 @@
#!/bin/bash
set -e
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
transport="zeromq"
multipart="false"
numParts="1"
@ -12,27 +12,16 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1
fi
if [[ $2 =~ ^multipart$ ]]; then
multipart="true"
numParts=2
if [[ $2 =~ ^[a-z]+$ ]]; then
multipart=$2
fi
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan1="data1"
chan2="data2"
chan3="data3"
chan4="data4"
chan5="data5"
chan1Addr="/tmp/fmq_$session""_""$chan1""_""$transport"
chan2Addr1="/tmp/fmq_$session""_""$chan2""_1""_""$transport"
chan2Addr2="/tmp/fmq_$session""_""$chan2""_2""_""$transport"
chan3Addr1="/tmp/fmq_$session""_""$chan3""_1""_""$transport"
chan3Addr2="/tmp/fmq_$session""_""$chan3""_2""_""$transport"
chan4Addr="/tmp/fmq_$session""_""$chan4""_""$transport"
chan5Addr="/tmp/fmq_$session""_""$chan5""_""$transport"
if [[ $3 =~ ^[0-9]+$ ]]; then
numParts=$3
fi
# setup a trap to kill everything if the test fails/timeouts
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SPLITTER_PID; kill -TERM $PROXY1_PID; kill -TERM $PROXY2_PID; kill -TERM $MERGER_PID; kill -TERM $MULTIPLIER_PID; kill -TERM $SINK_PID; rm $chan1Addr; rm $chan2Addr1; rm $chan2Addr2; rm $chan3Addr1; rm $chan3Addr2; rm $chan4Addr; rm $chan5Addr; exit 0' TERM
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SPLITTER_PID; kill -TERM $PROXY1_PID; kill -TERM $PROXY2_PID; kill -TERM $MERGER_PID; kill -TERM $MULTIPLIER_PID; kill -TERM $SINK_PID;' TERM
SAMPLER="fairmq-bsampler"
SAMPLER+=" --id bsampler1"
@ -41,16 +30,14 @@ SAMPLER+=" --transport $transport"
SAMPLER+=" --color false"
SAMPLER+=" --control static"
SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --shm-monitor true"
SAMPLER+=" --severity debug"
SAMPLER+=" --msg-size 100000"
SAMPLER+=" --multipart $multipart"
SAMPLER+=" --num-parts $numParts"
SAMPLER+=" --msg-rate 1"
SAMPLER+=" --max-iterations 0"
SAMPLER+=" --out-channel $chan1"
SAMPLER+=" --channel-config name=$chan1,type=push,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan1Addr"
SAMPLER+=" --out-channel data1"
SAMPLER+=" --channel-config name=data1,type=push,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5555"
@FAIRMQ_BIN_DIR@/$SAMPLER &
SAMPLER_PID=$!
@ -61,13 +48,11 @@ SPLITTER+=" --transport $transport"
SPLITTER+=" --color false"
SPLITTER+=" --control static"
SPLITTER+=" --verbosity veryhigh"
SPLITTER+=" --shm-segment-size 100000000"
SPLITTER+=" --shm-monitor true"
SPLITTER+=" --multipart $multipart"
SPLITTER+=" --in-channel $chan1"
SPLITTER+=" --out-channel $chan2"
SPLITTER+=" --channel-config name=$chan1,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan1Addr"
SPLITTER+=" name=$chan2,type=push,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan2Addr1,address=ipc://$chan2Addr2"
SPLITTER+=" --in-channel data1"
SPLITTER+=" --out-channel data2"
SPLITTER+=" --channel-config name=data1,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5555"
SPLITTER+=" name=data2,type=push,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5556,address=tcp://localhost:5557"
@FAIRMQ_BIN_DIR@/$SPLITTER &
SPLITTER_PID=$!
@ -78,13 +63,11 @@ PROXY1+=" --transport $transport"
PROXY1+=" --color false"
PROXY1+=" --control static"
PROXY1+=" --verbosity veryhigh"
PROXY1+=" --shm-segment-size 100000000"
PROXY1+=" --shm-monitor true"
PROXY1+=" --multipart $multipart"
PROXY1+=" --in-channel $chan2"
PROXY1+=" --out-channel $chan3"
PROXY1+=" --channel-config name=$chan2,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan2Addr1"
PROXY1+=" name=$chan3,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan3Addr1"
PROXY1+=" --in-channel data2"
PROXY1+=" --out-channel data3"
PROXY1+=" --channel-config name=data2,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5556"
PROXY1+=" name=data3,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5558"
@FAIRMQ_BIN_DIR@/$PROXY1 &
PROXY1_PID=$!
@ -95,13 +78,11 @@ PROXY2+=" --transport $transport"
PROXY2+=" --color false"
PROXY2+=" --control static"
PROXY2+=" --verbosity veryhigh"
PROXY2+=" --shm-segment-size 100000000"
PROXY2+=" --shm-monitor true"
PROXY2+=" --multipart $multipart"
PROXY2+=" --in-channel $chan2"
PROXY2+=" --out-channel $chan3"
PROXY2+=" --channel-config name=$chan2,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan2Addr2"
PROXY2+=" name=$chan3,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan3Addr2"
PROXY2+=" --in-channel data2"
PROXY2+=" --out-channel data3"
PROXY2+=" --channel-config name=data2,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5557"
PROXY2+=" name=data3,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5559"
@FAIRMQ_BIN_DIR@/$PROXY2 &
PROXY2_PID=$!
@ -112,13 +93,11 @@ MERGER+=" --transport $transport"
MERGER+=" --color false"
MERGER+=" --control static"
MERGER+=" --verbosity veryhigh"
MERGER+=" --shm-segment-size 100000000"
MERGER+=" --shm-monitor true"
MERGER+=" --multipart $multipart"
MERGER+=" --in-channel $chan3"
MERGER+=" --out-channel $chan4"
MERGER+=" --channel-config name=$chan3,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan3Addr1,address=ipc://$chan3Addr2"
MERGER+=" name=$chan4,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan4Addr"
MERGER+=" --in-channel data3"
MERGER+=" --out-channel data4"
MERGER+=" --channel-config name=data3,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5558,address=tcp://localhost:5559"
MERGER+=" name=data4,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5560"
@FAIRMQ_BIN_DIR@/$MERGER &
MERGER_PID=$!
@ -129,13 +108,11 @@ MULTIPLIER+=" --transport $transport"
MULTIPLIER+=" --color false"
MULTIPLIER+=" --control static"
MULTIPLIER+=" --verbosity veryhigh"
MULTIPLIER+=" --shm-segment-size 100000000"
MULTIPLIER+=" --shm-monitor true"
MULTIPLIER+=" --multipart $multipart"
MULTIPLIER+=" --in-channel $chan4"
MULTIPLIER+=" --out-channel $chan5"
MULTIPLIER+=" --channel-config name=$chan4,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan4Addr"
MULTIPLIER+=" name=$chan5,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan5Addr,address=ipc://$chan5Addr"
MULTIPLIER+=" --in-channel data4"
MULTIPLIER+=" --out-channel data5"
MULTIPLIER+=" --channel-config name=data4,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5560"
MULTIPLIER+=" name=data5,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5561,address=tcp://localhost:5561"
@FAIRMQ_BIN_DIR@/$MULTIPLIER &
MULTIPLIER_PID=$!
@ -148,10 +125,9 @@ SINK+=" --control static"
SINK+=" --verbosity veryhigh"
SINK+=" --severity debug"
SINK+=" --multipart $multipart"
SINK+=" --shm-monitor true"
SINK+=" --max-iterations 2"
SINK+=" --in-channel $chan5"
SINK+=" --channel-config name=$chan5,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan5Addr"
SINK+=" --in-channel data5"
SINK+=" --channel-config name=data5,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5561"
@FAIRMQ_BIN_DIR@/$SINK &
SINK_PID=$!
@ -170,7 +146,3 @@ wait $PROXY1_PID
wait $PROXY2_PID
wait $MERGER_PID
wait $MULTIPLIER_PID
set +e
rm $chan1Addr; rm $chan2Addr1; rm $chan2Addr2; rm $chan3Addr1; rm $chan3Addr2; rm $chan4Addr; rm $chan5Addr
exit 0

View File

@ -1,11 +1,61 @@
################################################################################
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# Copyright (C) 2014 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" #
################################################################################
add_example(NAME copypush
DEVICE sampler sink
add_library(ExampleCopyPushLib STATIC
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(ExampleCopyPushLib PUBLIC FairMQ)
add_executable(fairmq-ex-copypush-sampler runSampler.cxx)
target_link_libraries(fairmq-ex-copypush-sampler PRIVATE ExampleCopyPushLib)
add_executable(fairmq-ex-copypush-sink runSink.cxx)
target_link_libraries(fairmq-ex-copypush-sink PRIVATE ExampleCopyPushLib)
add_custom_target(ExampleCopyPush DEPENDS fairmq-ex-copypush-sampler fairmq-ex-copypush-sink)
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh)
# test
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh)
add_test(NAME Example.CopyPush.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh zeromq)
set_tests_properties(Example.CopyPush.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
add_test(NAME Example.CopyPush.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh shmem)
set_tests_properties(Example.CopyPush.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
# install
install(
TARGETS
fairmq-ex-copypush-sampler
fairmq-ex-copypush-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-copypush.sh
)

View File

@ -0,0 +1,68 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sampler.cpp
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#include <thread> // this_thread::sleep_for
#include <chrono>
#include "Sampler.h"
using namespace std;
namespace example_copypush
{
Sampler::Sampler()
: fNumDataChannels(0)
, fCounter(0)
, fMaxIterations(0)
, fNumIterations(0)
{
}
void Sampler::InitTask()
{
fNumDataChannels = fChannels.at("data").size();
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool Sampler::ConditionalRun()
{
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy
FairMQMessagePtr msg(NewSimpleMessage(fCounter++));
for (int i = 0; i < fNumDataChannels - 1; ++i)
{
FairMQMessagePtr msgCopy(NewMessage());
msgCopy->Copy(*msg);
Send(msgCopy, "data", i);
}
Send(msg, "data", fNumDataChannels - 1);
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
{
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
this_thread::sleep_for(chrono::seconds(1));
return true;
}
Sampler::~Sampler()
{
}
} // namespace example_copypush

View File

@ -0,0 +1,43 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sampler.h
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#ifndef FAIRMQEXAMPLECOPYPUSHSAMPLER_H
#define FAIRMQEXAMPLECOPYPUSHSAMPLER_H
#include "FairMQDevice.h"
#include <stdint.h> // uint64_t
namespace example_copypush
{
class Sampler : public FairMQDevice
{
public:
Sampler();
virtual ~Sampler();
protected:
virtual void InitTask();
virtual bool ConditionalRun();
int fNumDataChannels;
uint64_t fCounter;
uint64_t fMaxIterations;
uint64_t fNumIterations;
};
} // namespace example_copypush
#endif /* FAIRMQEXAMPLECOPYPUSHSAMPLER_H */

View File

@ -0,0 +1,51 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sink.cxx
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#include "Sink.h"
namespace example_copypush
{
Sink::Sink()
: fMaxIterations(0)
, fNumIterations(0)
{
OnData("data", &Sink::HandleData);
}
void Sink::InitTask()
{
// Get the fMaxIterations value from the command line options (via fConfig)
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
{
LOG(info) << "Received message: \"" << *(static_cast<uint64_t*>(msg->GetData())) << "\"";
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
{
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
// return true if want to be called again (otherwise go to IDLE state)
return true;
}
Sink::~Sink()
{
}
} // namespace example_copypush

42
examples/copypush/Sink.h Normal file
View File

@ -0,0 +1,42 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sink.h
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#ifndef FAIRMQEXAMPLECOPYPUSHSINK_H
#define FAIRMQEXAMPLECOPYPUSHSINK_H
#include "FairMQDevice.h"
#include <stdint.h> // uint64_t
namespace example_copypush
{
class Sink : public FairMQDevice
{
public:
Sink();
virtual ~Sink();
protected:
virtual void InitTask();
bool HandleData(FairMQMessagePtr&, int);
private:
uint64_t fMaxIterations;
uint64_t fNumIterations;
};
} // namespace example_copypush
#endif /* FAIRMQEXAMPLECOPYPUSHSINK_H */

View File

@ -0,0 +1,23 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Sampler.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_copypush::Sampler();
}

View File

@ -0,0 +1,23 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Sink.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_copypush::Sink();
}

View File

@ -1,65 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <chrono>
#include <cstdint> // uint64_t
#include <thread> // this_thread::sleep_for
namespace bpo = boost::program_options;
struct Sampler : fair::mq::Device
{
void InitTask() override
{
fNumDataChannels = GetNumSubChannels("data");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool ConditionalRun() override
{
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy
fair::mq::MessagePtr msg(NewSimpleMessage(fCounter++));
for (int i = 0; i < fNumDataChannels - 1; ++i) {
fair::mq::MessagePtr msgCopy(NewMessage());
msgCopy->Copy(*msg);
Send(msgCopy, "data", i);
}
Send(msg, "data", fNumDataChannels - 1);
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
return true;
}
private:
int fNumDataChannels = 0;
uint64_t fCounter = 0;
uint64_t fMaxIterations = 0;
uint64_t fNumIterations = 0;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Sampler>();
}

View File

@ -1,57 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <cstdint> // uint64_t
namespace bpo = boost::program_options;
struct Sink : fair::mq::Device
{
Sink()
{
OnData("data", &Sink::HandleData);
}
protected:
void InitTask() override
{
// Get the fMaxIterations value from the command line options (via fConfig)
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
bool HandleData(fair::mq::MessagePtr& msg, int)
{
LOG(info) << "Received message: \"" << *(static_cast<uint64_t*>(msg->GetData())) << "\"";
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
// return true if want to be called again (otherwise go to IDLE state)
return true;
}
private:
uint64_t fMaxIterations = 0;
uint64_t fNumIterations = 0;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Sink>();
}

View File

@ -1,7 +1,5 @@
#!/bin/bash
set -e
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
transport="zeromq"
@ -10,25 +8,19 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1
fi
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan="data"
chanAddr1="/tmp/fmq_$session""_""$chan""_1""_""$transport"
chanAddr2="/tmp/fmq_$session""_""$chan""_2""_""$transport"
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
# setup a trap to kill everything if the test fails/timeouts
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK1_PID; kill -TERM $SINK2_PID; wait $SAMPLER_PID; wait $SINK1_PID; wait $SINK2_PID; rm $chanAddr1; rm $chanAddr2; exit 0' TERM
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK1_PID; kill -TERM $SINK2_PID; wait $SAMPLER_PID; wait $SINK1_PID; wait $SINK2_PID;' TERM
SAMPLER="fairmq-ex-copypush-sampler"
SAMPLER+=" --id sampler1"
SAMPLER+=" --transport $transport"
SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --severity debug"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --shm-monitor true"
SAMPLER+=" --session $session"
SAMPLER+=" --session $SESSION"
SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 1"
SAMPLER+=" --channel-config name=$chan,type=push,method=bind,rateLogging=0,address=ipc://$chanAddr1,address=ipc://$chanAddr2"
SAMPLER+=" --channel-config name=data,type=push,method=bind,rateLogging=0,address=tcp://*:5555,address=tcp://*:5556"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$!
@ -36,13 +28,10 @@ SINK1="fairmq-ex-copypush-sink"
SINK1+=" --id sink1"
SINK1+=" --transport $transport"
SINK1+=" --verbosity veryhigh"
SINK1+=" --severity debug"
SINK1+=" --shm-segment-size 100000000"
SINK1+=" --shm-monitor true"
SINK1+=" --session $session"
SINK1+=" --session $SESSION"
SINK1+=" --control static --color false"
SINK1+=" --max-iterations 1"
SINK1+=" --channel-config name=$chan,type=pull,method=connect,rateLogging=0,address=ipc://$chanAddr1"
SINK1+=" --channel-config name=data,type=pull,method=connect,rateLogging=0,address=tcp://localhost:5555"
@CMAKE_CURRENT_BINARY_DIR@/$SINK1 &
SINK1_PID=$!
@ -50,13 +39,10 @@ SINK2="fairmq-ex-copypush-sink"
SINK2+=" --id sink2"
SINK2+=" --transport $transport"
SINK2+=" --verbosity veryhigh"
SINK2+=" --severity debug"
SINK2+=" --shm-segment-size 100000000"
SINK2+=" --shm-monitor true"
SINK2+=" --session $session"
SINK2+=" --session $SESSION"
SINK2+=" --control static --color false"
SINK2+=" --max-iterations 1"
SINK2+=" --channel-config name=$chan,type=pull,method=connect,rateLogging=0,address=ipc://$chanAddr2"
SINK2+=" --channel-config name=data,type=pull,method=connect,rateLogging=0,address=tcp://localhost:5556"
@CMAKE_CURRENT_BINARY_DIR@/$SINK2 &
SINK2_PID=$!
@ -64,7 +50,3 @@ SINK2_PID=$!
wait $SAMPLER_PID
wait $SINK1_PID
wait $SINK2_PID
set +e
rm $chanAddr1; rm $chanAddr2
exit 0

View File

@ -1,20 +0,0 @@
################################################################################
# Copyright (C) 2022-2023 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" #
################################################################################
set(name "custom-controller")
set(exe "${exe_prefix}-${name}")
add_executable(${exe} main.cxx)
target_link_libraries(${exe} PRIVATE FairMQ)
set_target_properties(${exe} PROPERTIES ENABLE_EXPORTS ON)
set(test "${testsuite}.${name}")
add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${exe})
set_tests_properties(${test} PROPERTIES TIMEOUT 30)
if(lsan_options)
set_tests_properties(${test} PROPERTIES ENVIRONMENT_MODIFICATION ${lsan_options})
endif()

View File

@ -1,97 +0,0 @@
/********************************************************************************
* Copyright (C) 2022 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_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN
#define FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN
#include <fairmq/Plugin.h>
#include <utility> // for std::forward
namespace example {
struct MyController : fair::mq::Plugin // NOLINT
{
template<typename... Args>
MyController(Args&&... args)
: Plugin(std::forward<Args>(args)...)
{
TakeDeviceControl();
SubscribeToDeviceStateChange([this](auto state) {
auto shutdown = GetProperty<bool>("please-shut-me-down", false);
try {
switch (state) {
case DeviceState::Idle: {
ChangeDeviceState(shutdown ? DeviceStateTransition::End
: DeviceStateTransition::InitDevice);
break;
}
case DeviceState::InitializingDevice: {
ChangeDeviceState(DeviceStateTransition::CompleteInit);
break;
}
case DeviceState::Initialized: {
ChangeDeviceState(DeviceStateTransition::Bind);
break;
}
case DeviceState::Bound: {
ChangeDeviceState(DeviceStateTransition::Connect);
break;
}
case DeviceState::DeviceReady: {
ChangeDeviceState(shutdown ? DeviceStateTransition::ResetDevice
: DeviceStateTransition::InitTask);
break;
}
case DeviceState::Ready: {
ChangeDeviceState(shutdown ? DeviceStateTransition::ResetTask
: DeviceStateTransition::Run);
break;
}
case DeviceState::Running: {
ChangeDeviceState(DeviceStateTransition::Stop);
break;
}
case DeviceState::Exiting: {
ReleaseDeviceControl();
break;
}
default:
break;
}
} catch (fair::mq::PluginServices::DeviceControlError const&) {
// this means we do not have device control
}
});
}
~MyController() override { ReleaseDeviceControl(); }
};
// auto MyControllerProgramOptions() -> fair::mq::Plugin::ProgOptions
// {
// auto plugin_options = boost::program_options::options_description{"MyController Plugin"};
// plugin_options.add_options()
// ("custom-dummy-option", boost::program_options::value<std::string>(), "Cool custom option.")
// ("custom-dummy-option2", boost::program_options::value<std::string>(), "Another one.");
// return plugin_options;
// }
} // namespace example
REGISTER_FAIRMQ_PLUGIN(example::MyController, // Class name
mycontroller, // Plugin name (string, lower case chars only)
(fair::mq::Plugin::Version{0, 42, 0}), // Version
"Mr. Dummy <dummy@test.net>", // Maintainer
"https://git.test.net/mycontroller.git", // Homepage
// example::MyControllerProgramOptions // Free
// function which declares custom
// program options for the plugin
fair::mq::Plugin::NoProgramOptions)
#endif /* FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN */

View File

@ -1,46 +0,0 @@
/********************************************************************************
* Copyright (C) 2022 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 "MyController.h"
#include "MyDevice.h"
#include <chrono> // for std::chrono_literals
#include <fairlogger/Logger.h>
#include <fairmq/DeviceRunner.h>
#include <memory> // for std::make_unique
int main(int argc, char* argv[])
{
using namespace fair::mq;
using namespace std::chrono_literals;
DeviceRunner runner(argc, argv);
runner.AddHook<hooks::LoadPlugins>([](DeviceRunner& r) {
r.fPluginManager.LoadPlugin("s:mycontroller");
// 's:' stands for static because the plugin is compiled into the executable
// 'mycontroller' is the plugin name passed as second arg to REGISTER_FAIRMQ_PLUGIN
});
fair::Logger::SetConsoleSeverity(fair::Severity::debug);
runner.AddHook<hooks::InstantiateDevice>([](DeviceRunner& r) {
r.fConfig.SetProperty<int>("catch-signals", 0);
r.fConfig.SetProperty<bool>("please-shut-me-down", false);
r.fDevice = std::make_unique<example::MyDevice>(r.fConfig);
r.fDevice->SubscribeToStateChange("example", [&r](auto state) {
if (state == State::Running) {
r.fDevice->WaitFor(3s);
r.fConfig.SetProperty<bool>("please-shut-me-down", true);
}
});
});
return runner.RunWithExceptionHandlers();
}

View File

@ -6,14 +6,25 @@
# copied verbatim in the file "LICENSE" #
################################################################################
add_executable(fairmq-ex-dds-sampler sampler.cxx)
target_link_libraries(fairmq-ex-dds-sampler PRIVATE FairMQ)
add_library(ExampleDDSLib STATIC
"Sampler.cxx"
"Sampler.h"
"Processor.cxx"
"Processor.h"
"Sink.cxx"
"Sink.h"
)
add_executable(fairmq-ex-dds-processor processor.cxx)
target_link_libraries(fairmq-ex-dds-processor PRIVATE FairMQ)
target_link_libraries(ExampleDDSLib PUBLIC FairMQ)
add_executable(fairmq-ex-dds-sink sink.cxx)
target_link_libraries(fairmq-ex-dds-sink PRIVATE FairMQ)
add_executable(fairmq-ex-dds-sampler runSampler.cxx)
target_link_libraries(fairmq-ex-dds-sampler PRIVATE ExampleDDSLib)
add_executable(fairmq-ex-dds-processor runProcessor.cxx)
target_link_libraries(fairmq-ex-dds-processor PRIVATE ExampleDDSLib)
add_executable(fairmq-ex-dds-sink runSink.cxx)
target_link_libraries(fairmq-ex-dds-sink PRIVATE ExampleDDSLib)
add_custom_target(ExampleDDS DEPENDS fairmq-ex-dds-sampler fairmq-ex-dds-processor fairmq-ex-dds-sink)
@ -27,13 +38,14 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-dds-env.sh ${CMAKE_CURRENT_
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh @ONLY)
# test
# if(DDS_FOUND)
# add_test(NAME Example.DDS.localhost COMMAND ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh localhost)
# set_tests_properties(Example.DDS.localhost PROPERTIES
# TIMEOUT 15
# PASS_REGULAR_EXPRESSION "Example successful"
# )
# endif()
if(DDS_FOUND)
add_test(NAME Example.DDS.localhost COMMAND ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh localhost)
set_tests_properties(Example.DDS.localhost PROPERTIES
TIMEOUT 15
RUN_SERIAL true
PASS_REGULAR_EXPRESSION "Example successful"
)
endif()
# install

View File

@ -0,0 +1,52 @@
/********************************************************************************
* Copyright (C) 2014 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 "Processor.h"
#include "FairMQLogger.h"
using namespace std;
namespace example_dds
{
Processor::Processor()
{
OnData("data1", &Processor::HandleData);
}
bool Processor::HandleData(FairMQMessagePtr& msg, int /*index*/)
{
LOG(info) << "Received data, processing...";
// Modify the received string
string* text = new std::string(static_cast<char*>(msg->GetData()), msg->GetSize());
*text += " (modified by " + fId + ")";
// create message object with a pointer to the data buffer,
// its size,
// custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer
FairMQMessagePtr msg2(NewMessage(const_cast<char*>(text->c_str()),
text->length(),
[](void* /*data*/, void* object) { delete static_cast<string*>(object); },
text));
// Send out the output message
if (Send(msg2, "data2") < 0)
{
return false;
}
return true;
}
Processor::~Processor()
{
}
} // namespace example_dds

29
examples/dds/Processor.h Normal file
View File

@ -0,0 +1,29 @@
/********************************************************************************
* Copyright (C) 2014 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 FAIRMQEXAMPLEDDSPROCESSOR_H
#define FAIRMQEXAMPLEDDSPROCESSOR_H
#include "FairMQDevice.h"
namespace example_dds
{
class Processor : public FairMQDevice
{
public:
Processor();
virtual ~Processor();
protected:
bool HandleData(FairMQMessagePtr&, int);
};
}
#endif /* FAIRMQEXAMPLEDDSPROCESSOR_H */

64
examples/dds/Sampler.cxx Normal file
View File

@ -0,0 +1,64 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sampler.cpp
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#include <thread> // this_thread::sleep_for
#include <chrono>
#include "Sampler.h"
using namespace std;
namespace example_dds
{
Sampler::Sampler()
{
}
void Sampler::InitTask()
{
fIterations = fConfig->GetValue<uint64_t>("iterations");
fCounter = 0;
}
bool Sampler::ConditionalRun()
{
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy
FairMQMessagePtr msg(NewSimpleMessage("Data"));
LOG(info) << "Sending \"Data\"";
// in case of error or transfer interruption, return false to go to IDLE state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
if (Send(msg, "data1") < 0) {
return false;
}
if (fIterations > 0) {
++fCounter;
if (fCounter >= fIterations) {
LOG(info) << "Sent " << fCounter << " messages. Finished.";
return false;
}
}
return true;
}
Sampler::~Sampler()
{
}
}

40
examples/dds/Sampler.h Normal file
View File

@ -0,0 +1,40 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sampler.h
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#ifndef FAIRMQEXAMPLEDDSSAMPLER_H
#define FAIRMQEXAMPLEDDSSAMPLER_H
#include "FairMQDevice.h"
namespace example_dds
{
class Sampler : public FairMQDevice
{
public:
Sampler();
virtual ~Sampler();
void InitTask() override;
protected:
bool ConditionalRun() override;
private:
uint64_t fIterations;
uint64_t fCounter;
};
} // namespace example_dds
#endif /* FAIRMQEXAMPLEDDSSAMPLER_H */

54
examples/dds/Sink.cxx Normal file
View File

@ -0,0 +1,54 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sink.cxx
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#include "Sink.h"
using namespace std;
namespace example_dds
{
Sink::Sink()
{
// register a handler for data arriving on "data2" channel
OnData("data2", &Sink::HandleData);
}
void Sink::InitTask()
{
fIterations = fConfig->GetValue<uint64_t>("iterations");
fCounter = 0;
}
// handler is called whenever a message arrives on "data2", with a reference to the message and a sub-channel index (here 0)
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
{
LOG(info) << "Received: \"" << string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
if (fIterations > 0) {
++fCounter;
if (fCounter >= fIterations) {
LOG(info) << "Received " << fCounter << " messages. Finished.";
return false;
}
}
// return true if want to be called again (otherwise go to IDLE state)
return true;
}
Sink::~Sink()
{
}
} // namespace example_dds

40
examples/dds/Sink.h Normal file
View File

@ -0,0 +1,40 @@
/********************************************************************************
* Copyright (C) 2014 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" *
********************************************************************************/
/**
* Sink.h
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#ifndef FAIRMQEXAMPLEDDSSINK_H
#define FAIRMQEXAMPLEDDSSINK_H
#include "FairMQDevice.h"
namespace example_dds
{
class Sink : public FairMQDevice
{
public:
Sink();
virtual ~Sink();
void InitTask() override;
protected:
bool HandleData(FairMQMessagePtr&, int);
private:
uint64_t fIterations;
uint64_t fCounter;
};
} // namespace example_dds
#endif /* FAIRMQEXAMPLEDDSSINK_H */

View File

@ -8,7 +8,7 @@
<declrequirement name="SinkWorker" type="wnname" value="sink"/>
<decltask name="Sampler">
<exe>fairmq-ex-dds-sampler --color false --channel-config name=data1,type=push,method=bind --rate 100 --iterations 0 -P dds</exe>
<exe>fairmq-ex-dds-sampler --color false --channel-config name=data1,type=push,method=bind --rate 100 -P dds</exe>
<env reachable="false">fairmq-ex-dds-env.sh</env>
<requirements>
<name>SamplerWorker</name>

View File

@ -8,7 +8,7 @@
<declrequirement name="SinkWorker" type="wnname" value="sink"/>
<decltask name="Sampler">
<exe>fairmq-ex-dds-sampler --color false --channel-config name=data1,type=push,method=bind -P dds --iterations 10 --severity trace --verbosity veryhigh</exe>
<exe>fairmq-ex-dds-sampler --color false --channel-config name=data1,type=push,method=bind -P dds --iterations 10</exe>
<env reachable="false">fairmq-ex-dds-env.sh</env>
<requirements>
<name>SamplerWorker</name>
@ -19,7 +19,7 @@
</decltask>
<decltask name="Processor">
<exe>fairmq-ex-dds-processor --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect -P dds --severity trace --verbosity veryhigh</exe>
<exe>fairmq-ex-dds-processor --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect -P dds</exe>
<env reachable="false">fairmq-ex-dds-env.sh</env>
<requirements>
<name>ProcessorWorker</name>
@ -31,7 +31,7 @@
</decltask>
<decltask name="Sink">
<exe>fairmq-ex-dds-sink --color false --channel-config name=data2,type=pull,method=bind -P dds --iterations 10 --severity trace --verbosity veryhigh</exe>
<exe>fairmq-ex-dds-sink --color false --channel-config name=data2,type=pull,method=bind -P dds --iterations 10</exe>
<env reachable="false">fairmq-ex-dds-env.sh</env>
<requirements>
<name>SinkWorker</name>

View File

@ -1,7 +1,7 @@
#!/bin/bash
################################################################################
# Copyright (C) 2019-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# #
# This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, #
@ -18,6 +18,7 @@ cleanup() {
echo "CLEANUP PERFORMED"
}
source @DDS_INSTALL_PREFIX@/DDS_env.sh
export PATH=@BIN_DIR@:$PATH
plugin=${1:-localhost}
@ -50,6 +51,7 @@ dds-info --executing-count --wait ${requiredNofSlots}
echo "------------------------"
echo "...waiting for Topology to finish..."
# TODO Retrieve number of devices from DDS topology API instead of having the user pass it explicitely
fairmq-dds-command-ui -w "IDLE"
fairmq-dds-command-ui -c i
fairmq-dds-command-ui -c k
@ -72,13 +74,12 @@ dds-info --active-topology
dds-topology --stop
dds-info --active-topology
# TODO Simplify, see https://github.com/FairRootGroup/DDS/issues/369
if dds-agent-cmd getlog -a; then
logDir=$(eval "echo $(dds-user-defaults --key server.sandbox_dir)/log/agents")
echo "AGENT LOG FILES IN: ${logDir}"
fi
dds-agent-cmd getlog -a
logDir="${wrkDir}/logs"
for file in $(find "${logDir}" -name "*.tar.gz"); do tar -xf ${file} -C "${logDir}" ; done
echo "AGENT LOG FILES IN: ${logDir}"
# This string is used by ctest to detect success
echo "Example successful"
echo "Example successful :)"
# Cleanup function is called by EXIT trap

View File

@ -1,56 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <string>
namespace bpo = boost::program_options;
struct Processor : fair::mq::Device
{
Processor()
{
OnData("data1", &Processor::HandleData);
}
bool HandleData(fair::mq::MessagePtr& msg, int)
{
LOG(info) << "Received data, processing...";
// Modify the received string
std::string* text = new std::string(static_cast<char*>(msg->GetData()), msg->GetSize());
*text += " (modified by " + fId + ")";
// create message object with a pointer to the data buffer,
// its size,
// custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer
fair::mq::MessagePtr msg2(NewMessage(const_cast<char*>(text->c_str()),
text->length(),
[](void* /*data*/, void* object) { delete static_cast<std::string*>(object); },
text));
// Send out the output message
if (Send(msg2, "data2") < 0) {
return false;
}
return true;
}
};
void addCustomOptions(bpo::options_description& /*options*/)
{
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Processor>();
}

View File

@ -0,0 +1,21 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Processor.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& /*options*/)
{
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_dds::Processor();
}

View File

@ -0,0 +1,25 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Sampler.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()(
"iterations,i",
bpo::value<uint64_t>()->default_value(1000),
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_dds::Sampler();
}

25
examples/dds/runSink.cxx Normal file
View File

@ -0,0 +1,25 @@
/********************************************************************************
* Copyright (C) 2014 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 "runFairMQDevice.h"
#include "Sink.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()(
"iterations,i",
bpo::value<uint64_t>()->default_value(1000),
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
{
return new example_dds::Sink();
}

View File

@ -1,64 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <cstdint> // uint64_t
namespace bpo = boost::program_options;
struct Sampler : fair::mq::Device
{
void InitTask() override
{
fIterations = fConfig->GetValue<uint64_t>("iterations");
}
bool ConditionalRun() override
{
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy
fair::mq::MessagePtr msg(NewSimpleMessage("Data"));
LOG(info) << "Sending \"Data\"";
// in case of error or transfer interruption, return false to go to IDLE state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
if (Send(msg, "data1") < 0) {
return false;
}
if (fIterations > 0) {
++fCounter;
if (fCounter >= fIterations) {
LOG(info) << "Sent " << fCounter << " messages. Finished.";
return false;
}
}
return true;
}
private:
uint64_t fIterations = 0;
uint64_t fCounter = 0;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()(
"iterations,i",
bpo::value<uint64_t>()->default_value(1000),
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Sampler>();
}

View File

@ -1,58 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 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 <fairmq/Device.h>
#include <fairmq/runDevice.h>
#include <string>
namespace bpo = boost::program_options;
struct Sink : fair::mq::Device
{
Sink()
{
OnData("data2", &Sink::HandleData);
}
void InitTask() override
{
fIterations = fConfig->GetValue<uint64_t>("iterations");
}
bool HandleData(fair::mq::MessagePtr& msg, int)
{
LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
if (fIterations > 0) {
++fCounter;
if (fCounter >= fIterations) {
LOG(info) << "Received " << fCounter << " messages. Finished.";
return false;
}
}
// return true if want to be called again (otherwise go to IDLE state)
return true;
}
private:
uint64_t fIterations = 0;
uint64_t fCounter = 0;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()(
"iterations,i",
bpo::value<uint64_t>()->default_value(1000),
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
{
return std::make_unique<Sink>();
}

Some files were not shown because too many files have changed in this diff Show More