Unverified Commit 7bce1d66 authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #1087

Modernize CMake setup
parents 8f025383 60e87a05
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(caf CXX)
# -- project options -----------------------------------------------------------
option(BUILD_SHARED_LIBS "Build all modules as shared library" ON)
cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
project(CAF CXX)
# -- includes ------------------------------------------------------------------
include(CMakeDependentOption) # Conditional default values
include(CMakePackageConfigHelpers) # For creating .cmake files
include(GNUInstallDirs) # Sets default install paths
include(GenerateExportHeader) # Auto-generates dllexport macros
# -- general options -----------------------------------------------------------
option(BUILD_SHARED_LIBS "Build shared library targets" ON)
option(CMAKE_EXPORT_COMPILE_COMMANDS "Write JSON compile commands database" ON)
option(THREADS_PREFER_PTHREAD_FLAG "Prefer -pthread flag if available " ON)
# -- CAF options that are off by default ----------------------------------------
option(CAF_ENABLE_CURL_EXAMPLES "Build examples with libcurl" OFF)
option(CAF_ENABLE_PROTOBUF_EXAMPLES "Build examples with Google Protobuf" OFF)
option(CAF_ENABLE_QT5_EXAMPLES "Build examples with the Qt5 framework" OFF)
option(CAF_ENABLE_RUNTIME_CHECKS "Build CAF with extra runtime assertions" OFF)
option(CAF_ENABLE_UTILITY_TARGETS "Include targets like consistency-check" OFF)
option(CAF_ENABLE_ACTOR_PROFILER "Enable experimental profiler API" OFF)
# -- CAF options that are on by default ----------------------------------------
option(CAF_ENABLE_EXAMPLES "Build small programs showcasing CAF features" ON)
option(CAF_ENABLE_IO_MODULE "Build networking I/O module" ON)
option(CAF_ENABLE_TESTING "Build unit test suites" ON)
option(CAF_ENABLE_TOOLS "Build utility programs such as caf-run" ON)
option(CAF_ENABLE_EXCEPTIONS "Build CAF with support for exceptions" ON)
# -- CAF options that depend on others -----------------------------------------
cmake_dependent_option(CAF_ENABLE_OPENSSL_MODULE "Build OpenSSL module" ON
"CAF_ENABLE_IO_MODULE" OFF)
# -- CAF options with non-boolean values ---------------------------------------
set(CAF_LOG_LEVEL "QUIET" CACHE STRING "Set log verbosity of CAF components")
set(CAF_SANITIZERS "" CACHE STRING
"Comma separated sanitizers, e.g., 'address,undefined'")
set(CAF_INSTALL_CMAKEDIR
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/CAF" CACHE STRING
"Path for installing CMake files, enables 'find_package(CAF)'")
# -- macOS-specific options ----------------------------------------------------
if(APPLE)
option(CMAKE_MACOSX_RPATH "Use rpaths on macOS and iOS" ON)
endif()
# -- project-specific CMake settings -------------------------------------------
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# -- check whether we are running as CMake subdirectory ------------------------
# -- sanity checking -----------------------------------------------------------
get_directory_property(_parent PARENT_DIRECTORY)
if(_parent)
set(caf_is_subproject ON)
else()
set(caf_is_subproject OFF)
if(CAF_ENABLE_OPENSSL_MODULE AND NOT CAF_ENABLE_IO_MODULE)
message(FATAL_ERROR "Invalid options: cannot build OpenSSL without I/O")
endif()
unset(_parent)
# enable tests if not disabled
if(NOT CAF_NO_UNIT_TESTS)
set(CAF_VALID_LOG_LEVELS QUIET ERROR WARNING INFO DEBUG TRACE)
if(NOT CAF_LOG_LEVEL IN_LIST CAF_VALID_LOG_LEVELS)
message(FATAL_ERROR "Invalid log level: \"${CAF_LOG_LEVEL}\"")
endif()
# -- compiler setup ------------------------------------------------------------
if(MSVC)
# Disable 4275 and 4251 (warnings regarding C++ classes at ABI boundaries).
add_compile_options(/wd4275 /wd4251)
if(CAF_SANITIZERS)
message(FATAL_ERROR "Sanitizer builds are currently not supported on MSVC")
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang"
OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
# Flags for both compilers.
add_compile_options(-ftemplate-depth=512 -ftemplate-backtrace-limit=0
-Wall -Wextra -pedantic)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Flags for Clang only.
add_compile_options(-Wdocumentation)
else()
# Flags for GCC only.
add_compile_options(-Wno-missing-field-initializers)
endif()
endif()
if(CAF_SANITIZERS)
add_compile_options(-fsanitize=${CAF_SANITIZERS} -fno-omit-frame-pointer)
endif()
# -- unit testing setup / caf_add_test_suites function ------------------------
if(CAF_ENABLE_TESTING)
enable_testing()
function(add_test_suites executable dir)
# enumerate all test suites.
set(suites "")
foreach(cpp_file ${ARGN})
file(STRINGS "${dir}/${cpp_file}" contents)
foreach(line ${contents})
if ("${line}" MATCHES "SUITE (.+)")
string(REGEX REPLACE ".*SUITE (.+)" "\\1" suite ${line})
list(APPEND suites "${suite}")
endif()
endforeach()
function(caf_add_test_suites target)
foreach(suiteName ${ARGN})
string(REPLACE "." "/" suitePath ${suiteName})
target_sources(${target} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/test/${suitePath}.cpp")
add_test(NAME ${suiteName}
COMMAND ${target} -r300 -n -v5 -s"^${suiteName}$")
endforeach()
list(REMOVE_DUPLICATES suites)
list(LENGTH suites num_suites)
message(STATUS "Found ${num_suites} test suite for ${executable}")
# creates one CMake test per test suite.
macro (make_test suite)
string(REPLACE " " "_" test_name ${suite})
add_test(NAME ${test_name} COMMAND ${executable} -r300 -n -v5 -s"^${suite}$")
endmacro ()
list(LENGTH suites num_suites)
foreach(suite ${suites})
make_test("${suite}")
endforeach ()
endfunction()
endif()
# -- make sure we have at least C++17 available --------------------------------
# TODO: simply set CXX_STANDARD when switching to CMake ≥ 3.9.6
if(NOT CMAKE_CROSSCOMPILING)
# Check whether the user already provided flags that enable C++ >= 17.
try_compile(caf_has_cxx_17
"${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/check-compiler-features.cpp")
# Try enabling C++17 mode if user-provided flags aren't sufficient.
if(NOT caf_has_cxx_17)
if(MSVC)
set(cxx_flag "/std:c++17")
......@@ -81,7 +132,7 @@ if(NOT CMAKE_CROSSCOMPILING)
COMPILE_DEFINITIONS "${cxx_flag}"
OUTPUT_VARIABLE cxx_check_output)
if(NOT caf_has_cxx_17)
MESSAGE(FATAL_ERROR "\nFatal error: unable activate C++17 mode!\
message(FATAL_ERROR "\nFatal error: unable activate C++17 mode!\
\nPlease see README.md for supported compilers.\
\n\ntry_compile output:\n${cxx_check_output}")
endif()
......@@ -89,181 +140,70 @@ if(NOT CMAKE_CROSSCOMPILING)
endif()
endif()
set(CMAKE_INSTALL_CMAKEBASEDIR "${CMAKE_INSTALL_LIBDIR}/cmake" CACHE PATH
"Base directory for installing cmake specific artifacts")
set(INSTALL_CAF_CMAKEDIR "${CMAKE_INSTALL_CMAKEBASEDIR}/caf")
# -- set default visibility to hidden when building shared libs ----------------
if(BUILD_SHARED_LIBS)
set(LINK_TYPE "shared")
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN yes)
if(POLICY CMP0063)
cmake_policy(SET CMP0063 NEW)
endif()
else()
set(CAF_STATIC_BUILD yes)
set(LINK_TYPE "static")
endif()
# Be nice to VIM users and Clang tools.
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
# Silence policy CMP0042 warning by enabling RPATH explicitly.
if(APPLE AND NOT DEFINED CMAKE_MACOSX_RPATH)
set(CMAKE_MACOSX_RPATH true)
endif()
if(CAF_BUILD_STATIC_RUNTIME)
set(flags_configs
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_MINSIZEREL
)
foreach(flags ${flags_configs})
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(NOT ${flags} MATCHES "-static-libstdc\\+\\+")
set(${flags} "${${flags}} -static-libstdc++")
endif()
if(NOT ${flags} MATCHES "-static-libgcc")
set(${flags} "${${flags}} -static-libgcc")
endif()
elseif(MSVC)
if(${flags} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flags} "${${flags}}")
endif()
endif()
endforeach()
else()
set(CAF_BUILD_STATIC_RUNTIME no)
endif()
# add helper target that simplifies re-running configure
if(NOT caf_is_subproject)
add_custom_target(configure COMMAND ${CMAKE_CURRENT_BINARY_DIR}/config.status)
endif()
# Silence annoying MSVC warning.
if(MSVC)
add_compile_options(/wd4275 /wd4251)
endif()
################################################################################
# utility functions #
################################################################################
# Appends `str` to the variable named `var` with a whitespace as separator.
# Suppresses a leading whitespace if the variable is empty and does nothing if
# `str` is empty.
function(build_string var str)
if(NOT str STREQUAL "")
if("${${var}}" STREQUAL "")
set("${var}" "${str}" PARENT_SCOPE)
else()
set("${var}" "${${var}} ${str}" PARENT_SCOPE)
endif()
endif()
endfunction(build_string)
# Forces `var` to 'no' if the content of the variables evaluates to false.
function(pretty_no var)
if(NOT "${${var}}")
set("${var}" no PARENT_SCOPE)
endif()
endfunction(pretty_no)
# Forces `var` to 'yes' if the content of the variables evaluates to false.
function(pretty_yes var)
if("${${var}}")
set("${var}" yes PARENT_SCOPE)
endif()
endfunction(pretty_yes)
add_executable(caf-generate-enum-strings
EXCLUDE_FROM_ALL
cmake/caf-generate-enum-strings.cpp)
add_custom_target(consistency-check)
add_custom_target(update-enum-strings)
# adds a consistency check that verifies that `cpp_file` is still valid by
# re-generating the file and comparing it to the existing file
function(add_enum_consistency_check hpp_file cpp_file)
set(input "${CMAKE_CURRENT_SOURCE_DIR}/${hpp_file}")
set(file_under_test "${CMAKE_CURRENT_SOURCE_DIR}/${cpp_file}")
set(output "${CMAKE_CURRENT_BINARY_DIR}/check/${cpp_file}")
get_filename_component(output_dir "${output}" DIRECTORY)
file(MAKE_DIRECTORY "${output_dir}")
add_custom_command(OUTPUT "${output}"
COMMAND caf-generate-enum-strings "${input}" "${output}"
DEPENDS caf-generate-enum-strings "${input}")
get_filename_component(target_name "${input}" NAME_WE)
add_custom_target("${target_name}"
COMMAND
"${CMAKE_COMMAND}"
"-Dfile_under_test=${file_under_test}"
"-Dgenerated_file=${output}"
-P "${PROJECT_SOURCE_DIR}/cmake/check-consistency.cmake"
DEPENDS "${output}")
add_dependencies(consistency-check "${target_name}")
add_custom_target("${target_name}-update"
COMMAND
caf-generate-enum-strings
"${input}"
"${file_under_test}"
DEPENDS caf-generate-enum-strings "${input}")
add_dependencies(update-enum-strings "${target_name}-update")
endfunction()
################################################################################
# set prefix paths if available #
################################################################################
build_string("CMAKE_PREFIX_PATH" "${CAF_QT_PREFIX_PATH}")
################################################################################
# make sure config parameters are printed with yes or no in summary #
################################################################################
pretty_yes("CAF_FORCE_NO_EXCEPTIONS")
pretty_no("CAF_ENABLE_RUNTIME_CHECKS")
pretty_no("CAF_NO_MEM_MANAGEMENT")
pretty_no("CAF_NO_EXCEPTIONS")
pretty_no("CAF_NO_OPENSSL")
pretty_no("CAF_NO_TOOLS")
pretty_no("CAF_NO_SUMMARY")
if(NOT CAF_NO_IO)
set(CAF_NO_IO no)
# -- utility targets -----------------------------------------------------------
if(CAF_ENABLE_UTILITY_TARGETS)
add_executable(caf-generate-enum-strings
EXCLUDE_FROM_ALL
cmake/caf-generate-enum-strings.cpp)
add_custom_target(consistency-check)
add_custom_target(update-enum-strings)
# adds a consistency check that verifies that `cpp_file` is still valid by
# re-generating the file and comparing it to the existing file
function(add_enum_consistency_check hpp_file cpp_file)
set(input "${CMAKE_CURRENT_SOURCE_DIR}/${hpp_file}")
set(file_under_test "${CMAKE_CURRENT_SOURCE_DIR}/${cpp_file}")
set(output "${CMAKE_CURRENT_BINARY_DIR}/check/${cpp_file}")
get_filename_component(output_dir "${output}" DIRECTORY)
file(MAKE_DIRECTORY "${output_dir}")
add_custom_command(OUTPUT "${output}"
COMMAND caf-generate-enum-strings "${input}" "${output}"
DEPENDS caf-generate-enum-strings "${input}")
get_filename_component(target_name "${input}" NAME_WE)
add_custom_target("${target_name}"
COMMAND
"${CMAKE_COMMAND}"
"-Dfile_under_test=${file_under_test}"
"-Dgenerated_file=${output}"
-P "${PROJECT_SOURCE_DIR}/cmake/check-consistency.cmake"
DEPENDS "${output}")
add_dependencies(consistency-check "${target_name}")
add_custom_target("${target_name}-update"
COMMAND
caf-generate-enum-strings
"${input}"
"${file_under_test}"
DEPENDS caf-generate-enum-strings "${input}")
add_dependencies(update-enum-strings "${target_name}-update")
endfunction()
else()
set(CAF_NO_TOOLS yes)
function(add_enum_consistency_check hpp_file cpp_file)
# nop
endfunction()
endif()
################################################################################
# get version of CAF #
################################################################################
# -- get CAF version -----------------------------------------------------------
# read content of config.hpp
file(READ "libcaf_core/caf/config.hpp" CONFIG_HPP)
# get line containing the version
string(REGEX MATCH "#define CAF_VERSION [0-9]+" VERSION_LINE "${CONFIG_HPP}")
# extract version number from line
string(REGEX MATCH "[0-9]+" VERSION_INT "${VERSION_LINE}")
# get line containing the version from config.hpp and extract version number
file(READ "libcaf_core/caf/config.hpp" CAF_CONFIG_HPP)
string(REGEX MATCH "#define CAF_VERSION [0-9]+" CAF_VERSION_LINE "${CAF_CONFIG_HPP}")
string(REGEX MATCH "[0-9]+" CAF_VERSION_INT "${CAF_VERSION_LINE}")
# calculate major, minor, and patch version
math(EXPR CAF_VERSION_MAJOR "${VERSION_INT} / 10000")
math(EXPR CAF_VERSION_MINOR "( ${VERSION_INT} / 100) % 100")
math(EXPR CAF_VERSION_PATCH "${VERSION_INT} % 100")
math(EXPR CAF_VERSION_MAJOR "${CAF_VERSION_INT} / 10000")
math(EXPR CAF_VERSION_MINOR "( ${CAF_VERSION_INT} / 100) % 100")
math(EXPR CAF_VERSION_PATCH "${CAF_VERSION_INT} % 100")
# create full version string
set(CAF_VERSION
"${CAF_VERSION_MAJOR}.${CAF_VERSION_MINOR}.${CAF_VERSION_PATCH}")
set(CAF_VERSION "${CAF_VERSION_MAJOR}.${CAF_VERSION_MINOR}.${CAF_VERSION_PATCH}")
# set the library version for our shared library targets
if(CMAKE_HOST_SYSTEM_NAME MATCHES "OpenBSD")
set(CAF_LIB_VERSION "${CAF_VERSION_MAJOR}.${CAF_VERSION_MINOR}")
......@@ -271,241 +211,69 @@ else()
set(CAF_LIB_VERSION "${CAF_VERSION}")
endif()
################################################################################
# set output paths for binaries and libraries if not provided by the user #
################################################################################
# -- generate build config header ----------------------------------------------
# prohibit in-source builds
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
message(FATAL_ERROR "In-source builds are not allowed. Please use "
"./configure to choose a build directory and "
"initialize the build configuration.")
endif()
if(NOT XCODE)
# set binary output path if not defined by user
if(NOT EXECUTABLE_OUTPUT_PATH)
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/bin")
endif()
# set library output path if not defined by user
if(NOT LIBRARY_OUTPUT_PATH)
set(LIBRARY_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/lib")
endif()
endif()
################################################################################
# compiler setup #
################################################################################
# set optional build flags
# increase max. template depth on GCC and Clang
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang"
OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options("-ftemplate-depth=512"
"-ftemplate-backtrace-limit=0")
endif()
# enable useful warnings by default
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wdocumentation)
endif()
# explicitly disable obnoxious GCC warnings
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options(-Wno-missing-field-initializers)
endif()
# set -fno-exception if requested
if(CAF_FORCE_NO_EXCEPTIONS)
add_compile_options(-fno-exceptions)
endif()
# allow enabling IPO on gcc/clang
if(POLICY CMP0069)
cmake_policy(SET CMP0069 NEW)
else()
if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-flto)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options(-flto -fno-fat-lto-objects)
endif()
endif()
endif()
# enable address sanitizer if requested by the user
if(CAF_SANITIZERS)
add_compile_options("-fsanitize=${CAF_SANITIZERS}"
"-fno-omit-frame-pointer")
list(APPEND CAF_EXTRA_LDFLAGS "-fsanitize=${CAF_SANITIZERS}")
endif()
# -pthread is ignored on MacOSX but required on other platforms
if(NOT APPLE AND NOT WIN32)
add_compile_options(-pthread)
list(APPEND CAF_EXTRA_LDFLAGS "-pthread")
endif()
# -fPIC generates warnings on MinGW and Cygwin plus extra setup steps needed on MinGW
if(MINGW)
add_definitions(-D_WIN32_WINNT=0x0600 -DWIN32)
list(APPEND CAF_EXTRA_LDFLAGS -lws2_32 -liphlpapi -lpsapi)
# build static to avoid runtime dependencies to GCC libraries
add_compile_options(-static)
elseif(CYGWIN)
add_compile_options(-U__STRICT_ANSI__)
endif()
if (WIN32)
list(APPEND CAF_EXTRA_LDFLAGS ws2_32 iphlpapi)
endif()
configure_file("${PROJECT_SOURCE_DIR}/cmake/build_config.hpp.in"
"${CMAKE_BINARY_DIR}/caf/detail/build_config.hpp"
@ONLY)
# iOS support
if(CAF_OSX_SYSROOT)
set(CMAKE_OSX_SYSROOT "${CAF_OSX_SYSROOT}")
endif()
if(CAF_IOS_DEPLOYMENT_TARGET)
if(CAF_OSX_SYSROOT STREQUAL "iphonesimulator")
add_compile_options("-mios-simulator-version-min=${CAF_IOS_DEPLOYMENT_TARGET}")
else()
add_compile_options("-miphoneos-version-min=${CAF_IOS_DEPLOYMENT_TARGET}")
endif()
endif()
# -- install testing DSL headers -----------------------------------------------
################################################################################
# setup logging #
################################################################################
# install includes from test
install(DIRECTORY libcaf_test/caf/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/caf
FILES_MATCHING PATTERN "*.hpp")
# make sure log level is defined and all-uppercase
if(NOT CAF_LOG_LEVEL)
set(CAF_LOG_LEVEL "QUIET")
else()
string(TOUPPER "${CAF_LOG_LEVEL}" CAF_LOG_LEVEL)
endif()
add_library(libcaf_test INTERFACE)
set(validLogLevels QUIET ERROR WARNING INFO DEBUG TRACE)
list(FIND validLogLevels "${CAF_LOG_LEVEL}" logLevelIndex)
if(logLevelIndex LESS 0)
MESSAGE(FATAL_ERROR "Invalid log level: \"${CAF_LOG_LEVEL}\"")
endif()
target_include_directories(libcaf_test INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/libcaf_test>)
################################################################################
# setup for install target #
################################################################################
add_library(CAF::test ALIAS libcaf_test)
# install includes from test
install(DIRECTORY libcaf_test/caf/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/caf
FILES_MATCHING PATTERN "*.hpp")
# -- provide an uinstall target ------------------------------------------------
# process cmake_uninstall.cmake.in
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
# add uninstall target if it does not exist yet
if(NOT TARGET uninstall)
add_custom_target(uninstall)
endif()
add_custom_command(TARGET uninstall
PRE_BUILD
COMMAND "${CMAKE_COMMAND}" -P
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
# -- set include paths for subprojects -----------------------------------------
# -- build all components the user asked for -----------------------------------
configure_file("${PROJECT_SOURCE_DIR}/cmake/build_config.hpp.in"
"${CMAKE_BINARY_DIR}/caf/detail/build_config.hpp"
@ONLY)
# -- set include paths for all subprojects -------------------------------------
include_directories("${CMAKE_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/libcaf_core"
"${CMAKE_CURRENT_SOURCE_DIR}/libcaf_io"
"${CMAKE_CURRENT_SOURCE_DIR}/libcaf_test"
"${CMAKE_CURRENT_SOURCE_DIR}/libcaf_openssl")
add_subdirectory(libcaf_core)
################################################################################
# add targets #
################################################################################
if(CAF_ENABLE_IO_MODULE)
add_subdirectory(libcaf_io)
endif()
macro(add_optional_caf_lib name)
string(TOUPPER ${name} upper_name)
set(flag_varname CAF_NO_${upper_name})
if(NOT ${flag_varname}
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_${name}/CMakeLists.txt")
add_subdirectory("libcaf_${name}")
else()
set(${flag_varname} yes)
endif()
endmacro()
macro(add_optional_caf_binaries name)
string(TOUPPER ${name} upper_name)
set(dependency_failed no)
# check all additional dependency flags
foreach(flag_name ${ARGN})
if(${flag_name})
set(dependency_failed yes)
endif()
endforeach()
if(NOT dependency_failed)
if(NOT CAF_NO_${upper_name}
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${name}/CMakeLists.txt")
add_subdirectory(${name})
else()
# make sure variable is set for nicer build log
set(CAF_NO_${upper_name} yes)
endif()
else()
message(STATUS
"Disable ${name}, one of the following flags was set: ${ARGN}")
# make sure variable is set for nicer build log
set(CAF_NO_${upper_name} yes)
endif()
endmacro()
if(CAF_ENABLE_OPENSSL_MODULE)
add_subdirectory(libcaf_openssl)
endif()
# build core and I/O library
add_subdirectory(libcaf_core)
add_optional_caf_lib(io)
# build SSL module if OpenSSL library is available
if(NOT CAF_NO_OPENSSL)
find_package(OpenSSL)
if(OPENSSL_FOUND)
# Check OpenSSL version >= 1.0.1
if (OPENSSL_VERSION VERSION_LESS 1.0.1)
message(STATUS
"Disable OpenSSL. Required >= 1.0.1 due to TLSv1.2 support.")
set(CAF_NO_OPENSSL yes)
else()
if(NOT CMAKE_CROSSCOMPILING)
# Check if openssl headers and library versions match
try_run(sslRunResult sslCompileResult
"${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/openssl-check.cpp"
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${OPENSSL_INCLUDE_DIR}"
LINK_LIBRARIES ${OPENSSL_LIBRARIES}
OUTPUT_VARIABLE sslOutput)
if (NOT sslCompileResult)
message(FATAL_ERROR "failed to compile/link against OpenSSL")
endif()
if(NOT sslRunResult EQUAL 0)
message(FATAL_ERROR
"OpenSSL version does not match headers: ${sslOutput}")
endif()
endif()
include_directories(BEFORE ${OPENSSL_INCLUDE_DIR})
add_optional_caf_lib(openssl)
endif()
else(OPENSSL_FOUND)
set(CAF_NO_OPENSSL yes)
endif(OPENSSL_FOUND)
if(CAF_ENABLE_EXAMPLES)
add_subdirectory(examples)
endif()
# build examples if not being told otherwise
add_optional_caf_binaries(examples)
if(CAF_ENABLE_TOOLS)
add_subdirectory(tools)
endif()
# build tools if not being told otherwise
add_optional_caf_binaries(tools)
# -- generate and install .cmake files -----------------------------------------
export(EXPORT CAFTargets FILE CAFTargets.cmake NAMESPACE caf::)
export(EXPORT CAFTargets FILE CAFTargets.cmake NAMESPACE CAF::)
install(EXPORT CAFTargets
DESTINATION "${INSTALL_CAF_CMAKEDIR}"
NAMESPACE caf::)
DESTINATION "${CAF_INSTALL_CMAKEDIR}"
NAMESPACE CAF::)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/CAFConfigVersion.cmake"
......@@ -514,74 +282,12 @@ write_basic_package_version_file(
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/CAFConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/CAFConfig.cmake" INSTALL_DESTINATION
"${INSTALL_CAF_CMAKEDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CAFConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/CAFConfigVersion.cmake"
DESTINATION "${INSTALL_CAF_CMAKEDIR}")
################################################################################
# Add additional project files to GUI #
################################################################################
file(GLOB_RECURSE script_files "scripts/*")
add_custom_target(gui_dummy SOURCES configure ${script_files})
################################################################################
# print summary #
################################################################################
# little helper macro to invert a boolean
macro(invertYesNo in out)
if(${in})
set(${out} no)
else()
set(${out} yes)
endif()
endmacro()
# invert CAF_NO_* variables for nicer output
invertYesNo(CAF_NO_IO CAF_BUILD_IO)
invertYesNo(CAF_NO_EXAMPLES CAF_BUILD_EXAMPLES)
invertYesNo(CAF_NO_TOOLS CAF_BUILD_TOOLS)
invertYesNo(CAF_NO_UNIT_TESTS CAF_BUILD_UNIT_TESTS)
invertYesNo(CAF_NO_EXCEPTIONS CAF_BUILD_WITH_EXCEPTIONS)
invertYesNo(CAF_NO_MEM_MANAGEMENT CAF_BUILD_MEM_MANAGEMENT)
invertYesNo(CAF_NO_OPENSSL CAF_BUILD_OPENSSL)
if(GENERATOR_IS_MULTI_CONFIG)
set(summary_build_type "Multi-Config")
else()
set(summary_build_type "${CMAKE_BUILD_TYPE}")
endif()
# done
if(NOT CAF_NO_SUMMARY)
message(STATUS
"\n====================| Build Summary |===================="
"\n"
"\nCAF version: ${CAF_VERSION}"
"\n"
"\nCXX: ${CMAKE_CXX_COMPILER}"
"\nBuild type: ${summary_build_type}"
"\nLink type: ${LINK_TYPE}"
"\nBuild static runtime: ${CAF_BUILD_STATIC_RUNTIME}"
"\nRuntime checks: ${CAF_ENABLE_RUNTIME_CHECKS}"
"\nLog level: ${CAF_LOG_LEVEL}"
"\nWith mem. mgmt.: ${CAF_BUILD_MEM_MANAGEMENT}"
"\nWith exceptions: ${CAF_BUILD_WITH_EXCEPTIONS}"
"\n"
"\nBuild I/O module: ${CAF_BUILD_IO}"
"\nBuild OpenSSL module: ${CAF_BUILD_OPENSSL}"
"\nBuild tools: ${CAF_BUILD_TOOLS}"
"\nBuild examples: ${CAF_BUILD_EXAMPLES}"
"\nBuild unit tests: ${CAF_BUILD_UNIT_TESTS}"
"\n"
"\n"
"\nSource directory: ${CMAKE_CURRENT_SOURCE_DIR}"
"\nBuild directory: ${CMAKE_CURRENT_BINARY_DIR}"
"\nExecutable path: ${EXECUTABLE_OUTPUT_PATH}"
"\nLibrary path: ${LIBRARY_OUTPUT_PATH}"
"\nInstall prefix: ${CMAKE_INSTALL_PREFIX}"
"\nGenerator: ${CMAKE_GENERATOR}"
"\n"
"\n===========================================================\n")
endif()
"${CMAKE_CURRENT_BINARY_DIR}/CAFConfig.cmake"
INSTALL_DESTINATION "${CAF_INSTALL_CMAKEDIR}")
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/CAFConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/CAFConfigVersion.cmake"
DESTINATION
"${CAF_INSTALL_CMAKEDIR}")
......@@ -4,14 +4,14 @@
// Default CMake flags for release builds.
defaultReleaseBuildFlags = [
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=yes',
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=ON',
]
// Default CMake flags for debug builds.
defaultDebugBuildFlags = defaultReleaseBuildFlags + [
'CAF_SANITIZERS:STRING=address,undefined',
'CAF_LOG_LEVEL:STRING=TRACE',
'CAF_ENABLE_ACTOR_PROFILER:BOOL=yes',
'CAF_ENABLE_ACTOR_PROFILER:BOOL=ON',
]
// Configures the behavior of our stages.
......@@ -28,10 +28,6 @@ config = [
// Our build matrix. Keys are the operating system labels and values are build configurations.
buildMatrix: [
// Various Linux builds for debug and release.
['debian-8', [
builds: ['debug', 'release'],
tools: ['clang-4'],
]],
['centos-6', [
builds: ['debug', 'release'],
tools: ['gcc-7'],
......@@ -97,12 +93,20 @@ config = [
'OPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include',
],
],
Windows: [
debug: defaultDebugBuildFlags + [
'CAF_ENABLE_OPENSSL_MODULE:BOOL=OFF',
],
release: defaultReleaseBuildFlags + [
'CAF_ENABLE_OPENSSL_MODULE:BOOL=OFF',
],
],
],
// Configures what binary the coverage report uses and what paths to exclude.
coverage: [
binaries: [
'build/bin/caf-core-test',
'build/bin/caf-io-test',
'build/libcaf_core/caf-core-test',
'build/libcaf_io/caf-io-test',
],
relativeExcludePaths: [
'examples',
......@@ -151,6 +155,8 @@ pipeline {
buildDir: 'build',
installation: 'cmake in search path',
sourceDir: '.',
cmakeArgs: '-DCAF_ENABLE_IO_MODULE:BOOL=OFF ' +
'-DCAF_ENABLE_UTILITY_TARGETS:BOOL=ON',
steps: [[
args: '--target consistency-check',
withCmake: true,
......
......@@ -25,10 +25,8 @@
#define CAF_LOG_LEVEL CAF_LOG_LEVEL_@CAF_LOG_LEVEL@
#cmakedefine CAF_NO_MEM_MANAGEMENT
#cmakedefine CAF_ENABLE_RUNTIME_CHECKS
#cmakedefine CAF_NO_EXCEPTIONS
#cmakedefine CAF_ENABLE_EXCEPTIONS
#cmakedefine CAF_ENABLE_ACTOR_PROFILER
#!/bin/sh
# Convenience wrapper for easily viewing/setting options that
# the project's CMake scripts will recognize.
set -e
command="$0 $*"
dirname_0=`dirname $0`
sourcedir=`cd $dirname_0 && pwd`
# Convenience wrapper for easily setting options that the project's CMake
# scripts will recognize.
usage="\
Usage: $0 [OPTION]... [VAR=VALUE]...
Build Options:
--cmake=PATH set a custom path to the CMake binary
--generator=GENERATOR set CMake generator (see cmake --help)
--build-type=TYPE set CMake build type [RelWithDebInfo]:
- Debug: debugging flags enabled
- MinSizeRel: minimal output size
- Release: optimizations on, debugging off
- RelWithDebInfo: release flags plus debugging
--extra-flags=STRING additional compiler flags (sets CMAKE_CXX_FLAGS)
--build-dir=DIR place build files in directory [build]
--bin-dir=DIR executable directory [build/bin]
--lib-dir=DIR library directory [build/lib]
--with-clang=FILE path to clang++ executable
--with-gcc=FILE path to g++ executable
--with-qt-prefix=PATH prefix path for Qt5 cmake modules
--with-openssl=PATH path to OpenSSL library and headers
--dual-build build using both gcc and clang
--build-static build as static library
--static-runtime build with static C++ runtime
--no-compiler-check disable compiler version check
--no-auto-libc++ do not automatically enable libc++ for Clang
--no-exceptions do not catch exceptions in CAF
--force-no-exceptions build CAF with '-fno-exceptions'
--warnings-as-errors build with '-Werror'
Optional Targets:
--with-qt-examples build Qt example(s)
--with-protobuf-examples build Google Protobuf example(s)
Installation Directories:
--prefix=PREFIX installation directory [/usr/local]
Remove Standard Features (even if all dependencies are available):
--no-memory-management build without memory management
--no-examples build without examples
--no-curl-examples build without libcurl examples
--no-unit-tests build without unit tests
--no-openssl build without OpenSSL module
--no-tools build without CAF tools such as caf-run
--no-io build without I/O module
--no-summary do not print configuration before building
--libs-only sets no-examples, no-tools and no-unit-tests
--core-only same as libs-only but also adds sets
no-openssl, and no-io
Debugging:
--with-runtime-checks build with requirement checks at runtime
--with-log-level=LVL build with debugging output, possible values:
- ERROR
- WARNING
- INFO
- DEBUG
- TRACE
--with-sanitizers=LIST build with this list of sanitizers enabled
--with-actor-profiler enables the (experimental) actor_profiler API
Convenience options:
--dev-mode sets --build-type=debug, --no-examples,
--no-tools, --with-runtime-checks,
--log-level=trace, and
--with-sanitizers=address,undefined
Influential Environment Variables (only on first invocation):
CXX C++ compiler command
CXXFLAGS C++ compiler flags (overrides defaults)
LDFLAGS Additional linker flags
CMAKE_GENERATOR Selects a custom generator
Command="$0 $*"
CommandDirname=`dirname $0`
SourceDir=`cd $CommandDirname && pwd`
iOS Build Options (should be used with XCode generator):
--sysroot=DIR set system root for Clang
- iphoneos: for iOS device
- iphonesimulator: for iOS simulator
--ios-min-ver=VERSION set the ios deployment target version
usage="\
Usage:
$0 [--<variable>=<value>...]
General CMake options:
--cmake=PATH set a custom path to the CMake binary
--build-dir=PATH set build directory [build]
--build-type=STRING set build type of single-configuration generators
--generator=STRING set CMake generator (see cmake --help)
--cxx-flags=STRING set CMAKE_CXX_FLAGS when running CMake
--prefix=PATH set installation directory
Locating packages in non-standard locations:
--openssl-root-dir=PATH set root directory of an OpenSSL installation
Debugging options:
--log-level=STRING build with debugging output, possible values:
- ERROR
- WARNING
- INFO
- DEBUG
- TRACE
--sanitizers=STRING build with this list of sanitizers enabled
Convenience options:
--dev-mode shortcut for passing:
--build-type=Debug
--log-level=TRACE
--sanitizers=address,undefined
--disable-examples
--disable-tools
--enable-utility-targets
--enable-runtime-checks
Flags (use --enable-<name> to activate and --disable-<name> to deactivate):
shared-libs build shared library targets [ON]
export-compile-commands write JSON compile commands database [ON]
prefer-pthread-flag prefer -pthread flag if available [ON]
curl-examples build examples with libcurl [OFF]
protobuf-examples build examples with Google Protobuf [OFF]
qt5-examples build examples with the Qt5 framework [OFF]
runtime-checks build CAF with extra runtime assertions [OFF]
utility-targets include targets like consistency-check [OFF]
actor-profiler enable experimental proiler API [OFF]
examples build small programs showcasing CAF features [ON]
io-module build networking I/O module [ON]
openssl-module build OpenSSL module [ON]
testing build unit test suites [ON]
tools build utility programs such as caf-run [ON]
with-exceptions build CAF with support for exceptions [ON]
Influential Environment Variables (only on first invocation):
CXX C++ compiler command
CXXFLAGS Additional C++ compiler flags
LDFLAGS Additional linker flags
CMAKE_GENERATOR Selects a custom generator
"
# Appends a CMake cache entry definition to the CMakeCacheEntries variable.
# $1 is the cache entry variable name
# $2 is the cache entry variable type
# $3 is the cache entry variable value
append_cache_entry ()
{
case "$3" in
*\ * )
# string contains whitespace
CMakeCacheEntries="$CMakeCacheEntries -D \"$1:$2=$3\""
;;
*)
# string contains whitespace
CMakeCacheEntries="$CMakeCacheEntries -D $1:$2=$3"
;;
esac
# $1: variable name
# $2: CMake type
# $3: value
append_cache_entry() {
case "$3" in
*\ * )
# string contains whitespace
CMakeCacheEntries="$CMakeCacheEntries -D \"$1:$2=$3\""
;;
*)
# string contains no whitespace
CMakeCacheEntries="$CMakeCacheEntries -D $1:$2=$3"
;;
esac
}
# Creates a build directory via CMake.
# $1 is the path to a compiler executable.
# $2 is the suffix of the build directory.
# $3 is the executable output path.
# $4 is the library output path.
# $5 is the CMake generator.
configure ()
{
CMakeCacheEntries=$CMakeDefaultCache
if [ -n "$1" ]; then
append_cache_entry CMAKE_CXX_COMPILER FILEPATH $1
fi
case "$builddir" in
/*)
#absolute path given
absolute_builddir="$builddir"
;;
*)
# relative path given; convert to absolute path
absolute_builddir="$PWD/$builddir"
;;
esac
if [ -n "$2" ]; then
workdir="$absolute_builddir-$2"
else
workdir="$absolute_builddir"
fi
workdirs="$workdirs $workdir"
if [ -n "$3" ]; then
append_cache_entry EXECUTABLE_OUTPUT_PATH PATH "$3"
else
append_cache_entry EXECUTABLE_OUTPUT_PATH PATH "$workdir/bin"
fi
if [ -n "$4" ]; then
append_cache_entry LIBRARY_OUTPUT_PATH PATH "$4"
else
append_cache_entry LIBRARY_OUTPUT_PATH PATH "$workdir/lib"
fi
if [ -d "$workdir" ]; then
# If a build directory exists, check if it has a CMake cache.
if [ -f "$workdir/CMakeCache.txt" ]; then
# If the CMake cache exists, delete it so that this configuration
# is not tainted by a previous one.
rm -f "$workdir/CMakeCache.txt"
fi
else
mkdir -p "$workdir"
fi
cd "$workdir"
if [ -n "$5" ]; then
"$CMakeCommand" -G "$5" $CMakeCacheEntries "$sourcedir"
else
"$CMakeCommand" $CMakeCacheEntries "$sourcedir"
fi
printf "#!/bin/sh\n\n" > config.status
printf "# Switch to the source of this build directory.\n" >> config.status
printf "cd \"$sourcedir\"\n\n" >> config.status
printf "# Invoke the command to configure this build.\n" >> config.status
if [ -n "$CC" ]; then
printf "CC=\"%s\"\n" "$CC" >> config.status
fi
if [ -n "$CXX" ]; then
printf "CXX=\"%s\"\n" "$CXX" >> config.status
fi
if [ -n "$CXXFLAGS" ]; then
printf "CXXFLAGS=\"%s\"\n" "$CXXFLAGS" >> config.status
fi
if [ -n "$LDFLAGS" ]; then
printf "LDFLAGS=\"%s\"\n" "$LDFLAGS" >> config.status
fi
echo $command >> config.status
chmod u+x config.status
# Appends a BOOL cache entry to the CMakeCacheEntries variable.
# $1: flag name
# $2: value (ON or OFF)
set_build_flag() {
FlagName=''
case "$1" in
shared-libs) FlagName='BUILD_SHARED_LIBS' ;;
export-compile-commands) FlagName='CMAKE_EXPORT_COMPILE_COMMANDS' ;;
prefer-pthread-flag) FlagName='THREADS_PREFER_PTHREAD_FLAG' ;;
curl-examples) FlagName='CAF_ENABLE_CURL_EXAMPLES' ;;
protobuf-examples) FlagName='CAF_ENABLE_PROTOBUF_EXAMPLES' ;;
qt5-examples) FlagName='CAF_ENABLE_QT5_EXAMPLES' ;;
runtime-checks) FlagName='CAF_ENABLE_RUNTIME_CHECKS' ;;
utility-targets) FlagName='CAF_ENABLE_UTILITY_TARGETS' ;;
actor-profiler) FlagName='CAF_ENABLE_ACTOR_PROFILER' ;;
examples) FlagName='CAF_ENABLE_EXAMPLES' ;;
io-module) FlagName='CAF_ENABLE_IO_MODULE' ;;
openssl-module) FlagName='CAF_ENABLE_OPENSSL_MODULE' ;;
testing) FlagName='CAF_ENABLE_TESTING' ;;
tools) FlagName='CAF_ENABLE_TOOLS' ;;
exceptions) FlagName='CAF_ENABLE_EXCEPTIONS' ;;
*)
echo "Invalid flag '$1'. Try $0 --help to see available options."
exit 1
;;
esac
append_cache_entry $FlagName BOOL $2
}
# Set defaults.
builddir="$sourcedir/build"
CMakeBuildDir="$SourceDir/build"
CMakeCacheEntries=""
append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local
append_cache_entry CAF_ENABLE_RUNTIME_CHECKS BOOL false
# parse custom environment variable to initialize CMakeGenerator
if [ -n "$CMAKE_GENERATOR" ]; then
CMakeGenerator="$CMAKE_GENERATOR"
fi
# Parse arguments.
# Parse user input.
while [ $# -ne 0 ]; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) optarg= ;;
esac
case "$1" in
--help|-h)
echo "${usage}" 1>&2
exit 1
;;
--cmake=*)
CMakeCommand="$optarg"
;;
--generator=*)
CMakeGenerator="$optarg"
;;
--prefix=*)
append_cache_entry CMAKE_INSTALL_PREFIX PATH "$optarg"
;;
--with-runtime-checks)
append_cache_entry CAF_ENABLE_RUNTIME_CHECKS BOOL yes
;;
--with-sanitizers=*)
append_cache_entry CAF_SANITIZERS STRING "$optarg"
;;
--with-actor-profiler)
append_cache_entry CAF_ENABLE_ACTOR_PROFILER BOOL yes
;;
--no-memory-management)
append_cache_entry CAF_NO_MEM_MANAGEMENT BOOL yes
;;
--no-compiler-check)
append_cache_entry CAF_NO_COMPILER_CHECK BOOL yes
;;
--no-auto-libc++)
append_cache_entry CAF_NO_AUTO_LIBCPP BOOL yes
;;
--no-exceptions)
append_cache_entry CAF_NO_EXCEPTIONS BOOL yes
;;
--force-no-exceptions)
append_cache_entry CAF_NO_EXCEPTIONS BOOL yes
append_cache_entry CAF_FORCE_NO_EXCEPTIONS BOOL yes
;;
--sysroot=*)
append_cache_entry CAF_OSX_SYSROOT PATH "$optarg"
;;
--ios-min-ver=*)
append_cache_entry CMAKE_OSX_ARCHITECTURES STRING "\$(ARCHS_STANDARD_32_64_BIT)"
append_cache_entry CAF_IOS_DEPLOYMENT_TARGET STRING "$optarg"
;;
--with-log-level=*)
append_cache_entry CAF_LOG_LEVEL STRING "$optarg"
;;
--with-clang=*)
clang="$optarg"
;;
--with-gcc=*)
gcc="$optarg"
;;
--with-qt-prefix=*)
append_cache_entry CAF_QT_PREFIX_PATH STRING "$optarg"
;;
--with-openssl=*)
append_cache_entry OPENSSL_ROOT_DIR PATH "$optarg"
;;
--build-type=*)
append_cache_entry CMAKE_BUILD_TYPE STRING "$optarg"
;;
--extra-flags=*)
append_cache_entry CMAKE_CXX_FLAGS STRING "$optarg"
;;
--build-dir=*)
builddir="$optarg"
;;
--bin-dir=*)
bindir="$optarg"
;;
--lib-dir=*)
libdir="$optarg"
;;
--dual-build)
dualbuild=1
;;
--no-examples)
append_cache_entry CAF_NO_EXAMPLES BOOL yes
;;
--with-qt-examples)
append_cache_entry CAF_BUILD_QT_EXAMPLES BOOL yes
;;
--with-protobuf-examples)
append_cache_entry CAF_BUILD_PROTOBUF_EXAMPLES BOOL yes
;;
--no-curl-examples)
append_cache_entry CAF_NO_CURL_EXAMPLES BOOL yes
;;
--no-unit-tests)
append_cache_entry CAF_NO_UNIT_TESTS BOOL yes
;;
--no-openssl)
append_cache_entry CAF_NO_OPENSSL BOOL yes
;;
--build-static)
append_cache_entry BUILD_SHARED_LIBS BOOL no
;;
--static-runtime)
append_cache_entry CAF_BUILD_STATIC_RUNTIME BOOL yes
;;
--no-tools)
append_cache_entry CAF_NO_TOOLS BOOL yes
;;
--no-io)
append_cache_entry CAF_NO_IO BOOL yes
;;
--no-summary)
append_cache_entry CAF_NO_SUMMARY BOOL yes
;;
--libs-only)
for var in CAF_NO_TOOLS CAF_NO_EXAMPLES CAF_NO_UNIT_TESTS; do
append_cache_entry $var BOOL yes
done
;;
--core-only)
for var in CAF_NO_TOOLS CAF_NO_EXAMPLES CAF_NO_UNIT_TESTS CAF_NO_IO CAF_NO_OPENSSL ; do
append_cache_entry $var BOOL yes
done
;;
--dev-mode)
for var in CAF_NO_TOOLS CAF_NO_EXAMPLES CAF_ENABLE_RUNTIME_CHECKS ; do
append_cache_entry $var BOOL yes
done
append_cache_entry CMAKE_BUILD_TYPE STRING Debug
append_cache_entry CAF_LOG_LEVEL STRING TRACE
append_cache_entry CAF_SANITIZERS STRING address,undefined
;;
*)
echo "Invalid option '$1'. Try $0 --help to see available options."
exit 1
;;
esac
shift
# Fetch the option argument.
case "$1" in
--*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
--enable-*) optarg=`echo "$1" | sed 's/--enable-//'` ;;
--disable-*) optarg=`echo "$1" | sed 's/--disable-//'` ;;
*) ;;
esac
# Consume current input.
case "$1" in
--help|-h)
echo "${usage}" 1>&2
exit 1
;;
--cmake=*)
CMakeCommand="$optarg"
;;
--build-dir=*)
CMakeBuildDir="$optarg"
;;
--generator=*)
CMakeGenerator="$optarg"
;;
--build-type=*)
CMakeBuildType="$optarg"
;;
--cxx-flags=*)
append_cache_entry CMAKE_CXX_FLAGS STRING "$optarg"
;;
--prefix=*)
append_cache_entry CMAKE_INSTALL_PREFIX PATH "$optarg"
;;
--log-level=*)
append_cache_entry CAF_LOG_LEVEL STRING "$optarg"
;;
--sanitizers=*)
append_cache_entry CAF_SANITIZERS STRING "$optarg"
;;
--dev-mode)
append_cache_entry CAF_LOG_LEVEL STRING "$optarg"
CMakeBuildType='Debug'
append_cache_entry CAF_LOG_LEVEL STRING 'TRACE'
append_cache_entry CAF_SANITIZERS STRING 'address,undefined'
set_build_flag examples OFF
set_build_flag tools OFF
set_build_flag utility-targets ON
set_build_flag runtime-checks ON
;;
--enable-*)
set_build_flag $optarg ON
;;
--disable-*)
set_build_flag $optarg OFF
;;
--openssl-root-dir=*)
append_cache_entry OPENSSL_ROOT_DIR PATH "$optarg"
;;
*)
echo "Invalid option '$1'. Try $0 --help to see available options."
exit 1
;;
esac
# Get next input.
shift
done
# Check for `cmake` command.
if [ -z "$CMakeCommand" ]; then
# prefer cmake3 over "regular" cmake (cmake == cmake2 on RHEL)
if command -v cmake3 >/dev/null 2>&1 ; then
CMakeCommand="cmake3"
elif command -v cmake >/dev/null 2>&1 ; then
CMakeCommand="cmake"
else
echo "This package requires CMake, please install it first."
echo "Then you may use this script to configure the CMake build."
echo "Note: pass --cmake=PATH to use cmake in non-standard locations."
exit 1;
fi
# Prefer cmake3 over "regular" cmake (cmake == cmake2 on RHEL).
if command -v cmake3 >/dev/null 2>&1 ; then
CMakeCommand="cmake3"
elif command -v cmake >/dev/null 2>&1 ; then
CMakeCommand="cmake"
else
echo "This package requires CMake, please install it first."
echo "Then you may use this script to configure the CMake build."
echo "Note: pass --cmake=PATH to use cmake in non-standard locations."
exit 1
fi
fi
# At this point we save the global CMake variables so that configure() can
# later use them.
CMakeDefaultCache=$CMakeCacheEntries
if [ -n "$dualbuild" ]; then
# Use what we got in $PATH if --with-clang or --with-gcc is not specified.
if [ -z "$clang" ]; then
clang=clang++
fi
if [ -z "$gcc" ]; then
gcc=g++
fi
# Make sure the build directory is an absolute path.
case "$CMakeBuildDir" in
/*)
CMakeAbsoluteBuildDir="$CMakeBuildDir"
;;
*)
CMakeAbsoluteBuildDir="$PWD/$CMakeBuildDir"
;;
esac
# If a build directory exists, delete any existing cache to have a clean build.
if [ -d "$CMakeAbsoluteBuildDir" ]; then
if [ -f "$CMakeAbsoluteBuildDir/CMakeCache.txt" ]; then
rm -f "$CMakeAbsoluteBuildDir/CMakeCache.txt"
fi
else
mkdir -p "$CMakeAbsoluteBuildDir"
fi
for i in gcc clang; do
eval "compiler=\$$i"
configure $compiler $i "" "" $CMakeGenerator
done
# Run CMake.
cd "$CMakeAbsoluteBuildDir"
if [ -n "$CMakeGenerator" ]; then
"$CMakeCommand" -G "$CMakeGenerator" $CMakeCacheEntries "$SourceDir"
else
# Prefer Clang to GCC.
if [ -n "$clang" ]; then
compiler=$clang
elif [ -n "$gcc" ]; then
compiler=$gcc
fi
"$CMakeCommand" $CMakeCacheEntries "$SourceDir"
fi
configure "$compiler" "" "$bindir" "$libdir" "$CMakeGenerator"
# Generate a config.status file that allows re-running a clean build.
printf "#!/bin/sh\n\n" > config.status
printf "# Switch to the source of this build directory.\n" >> config.status
printf "cd \"%s\"\n\n" "$CMakeAbsoluteBuildDir" >> config.status
printf "# Invoke the command to configure this build.\n" >> config.status
if [ -n "$CXX" ]; then
printf "CXX=\"%s\"\n" "$CXX" >> config.status
fi
if [ -n "$CXXFLAGS" ]; then
printf "CXXFLAGS=\"%s\"\n" "$CXXFLAGS" >> config.status
fi
if [ -n "$LDFLAGS" ]; then
printf "LDFLAGS=\"%s\"\n" "$LDFLAGS" >> config.status
fi
echo $Command >> config.status
chmod u+x config.status
add_custom_target(all_examples)
include_directories(${LIBCAF_INCLUDE_DIRS})
macro(add folder name)
function(add_example folder name)
add_executable(${name} ${folder}/${name}.cpp ${ARGN})
target_link_libraries(${name}
${CAF_EXTRA_LDFLAGS}
${CAF_LIBRARIES}
${PTHREAD_LIBRARIES})
install(FILES ${folder}/${name}.cpp DESTINATION ${CMAKE_INSTALL_DATADIR}/caf/examples/${folder})
add_dependencies(${name} all_examples)
endmacro()
endfunction()
function(add_core_example folder name)
add_example(${folder} ${name} ${ARGN})
target_link_libraries(${name} CAF::core)
endfunction()
# -- examples for CAF::core ----------------------------------------------------
# introductionary applications
add(. aout)
add(. hello_world)
add_core_example(. aout)
add_core_example(. hello_world)
# basic message passing primitives
add(message_passing calculator)
add(message_passing cell)
add(message_passing dancing_kirby)
add(message_passing delegating)
add(message_passing divider)
add(message_passing fan_out_request)
add(message_passing fixed_stack)
add(message_passing promises)
add(message_passing request)
add(message_passing typed_calculator)
add_core_example(message_passing calculator)
add_core_example(message_passing cell)
add_core_example(message_passing dancing_kirby)
add_core_example(message_passing delegating)
add_core_example(message_passing divider)
add_core_example(message_passing fan_out_request)
add_core_example(message_passing fixed_stack)
add_core_example(message_passing promises)
add_core_example(message_passing request)
add_core_example(message_passing typed_calculator)
# streaming API
add(streaming integer_stream)
add_core_example(streaming integer_stream)
# dynamic behavior changes using 'become'
add(dynamic_behavior skip_messages)
add(dynamic_behavior dining_philosophers)
add_core_example(dynamic_behavior skip_messages)
add_core_example(dynamic_behavior dining_philosophers)
# adding custom message types
add(custom_type custom_types_1)
add(custom_type custom_types_2)
add(custom_type custom_types_3)
add_core_example(custom_type custom_types_1)
add_core_example(custom_type custom_types_2)
add_core_example(custom_type custom_types_3)
# basic remoting
add(remoting group_chat)
add(remoting group_server)
add(remoting remote_spawn)
add(remoting distributed_calculator)
# testing DSL
add_example(testing ping_pong)
target_link_libraries(ping_pong CAF::core CAF::test)
# basic I/O with brokers
add(broker simple_broker)
add(broker simple_http_broker)
# testing DSL
add(testing ping_pong)
if(CAF_BUILD_PROTOBUF_EXAMPLES)
find_package(Protobuf)
if(PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE)
PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders "${CMAKE_CURRENT_SOURCE_DIR}/remoting/pingpong.proto")
include_directories(${PROTOBUF_INCLUDE_DIR})
# add binary dir as include path as generated headers will be located there
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(protobuf_broker broker/protobuf_broker.cpp ${ProtoSources})
target_link_libraries(protobuf_broker ${CMAKE_DL_LIBS} ${CAF_LIBRARIES} ${PTHREAD_LIBRARIES} ${PROTOBUF_LIBRARIES})
add_dependencies(protobuf_broker all_examples)
endif(PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE)
# -- examples for CAF::io ------------------------------------------------------
if(TARGET CAF::io)
function(add_io_example folder name)
add_example(${folder} ${name} ${ARGN})
target_link_libraries(${name} CAF::io CAF::core)
endfunction()
# basic remoting
add_io_example(remoting group_chat)
add_io_example(remoting group_server)
add_io_example(remoting remote_spawn)
add_io_example(remoting distributed_calculator)
# basic I/O with brokers
add_io_example(broker simple_broker)
add_io_example(broker simple_http_broker)
endif()
if(CAF_BUILD_QT_EXAMPLES)
find_package(Qt5 COMPONENTS Core Gui Widgets QUIET)
if(Qt5_FOUND)
message(STATUS "Found Qt5")
#include(${QT_USE_FILE})
QT5_ADD_RESOURCES(GROUP_CHAT_RCS )
QT5_WRAP_UI(GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui)
QT5_WRAP_CPP(GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp)
# generated headers will be in cmake build directory
#include_directories(. qtsupport ${CMAKE_CURRENT_BINARY_DIR} ${CPPA_INCLUDE})
include_directories(qtsupport
${CMAKE_CURRENT_BINARY_DIR}
${Qt5Core_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS})
set(GROUP_CHAT_SRC qtsupport/qt_group_chat.cpp qtsupport/chatwidget.cpp)
add_executable(qt_group_chat
${GROUP_CHAT_SRC}
${GROUP_CHAT_MOC_SRC}
${GROUP_CHAT_UI_HDR})
target_link_libraries(qt_group_chat
${CMAKE_DL_LIBS}
${CAF_LIBRARIES}
Qt5::Core
Qt5::Gui
Qt5::Widgets)
add_dependencies(qt_group_chat all_examples)
else()
find_package(Qt4)
if(QT4_FOUND)
message(STATUS "Found Qt4")
include(${QT_USE_FILE})
QT4_ADD_RESOURCES(GROUP_CHAT_RCS )
QT4_WRAP_UI(GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui)
QT4_WRAP_CPP(GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp)
# generated headers will be in cmake build directory
#include_directories(. qtsupport ${CMAKE_CURRENT_BINARY_DIR} ${CPPA_INCLUDE})
include_directories(qtsupport ${CMAKE_CURRENT_BINARY_DIR})
set(GROUP_CHAT_SRCS qtsupport/qt_group_chat.cpp qtsupport/chatwidget.cpp)
add_executable(qt_group_chat
${GROUP_CHAT_SRCS}
${GROUP_CHAT_MOC_SRC}
${GROUP_CHAT_UI_HDR})
target_link_libraries(qt_group_chat
${CMAKE_DL_LIBS}
${CAF_LIBRARIES}
${QT_LIBRARIES})
add_dependencies(qt_group_chat all_examples)
endif()
if(CAF_ENABLE_PROTOBUF_EXAMPLES)
find_package(Protobuf REQUIRED)
if(NOT PROTOBUF_PROTOC_EXECUTABLE)
message(FATAL_ERROR "CMake was unable to set PROTOBUF_PROTOC_EXECUTABLE")
endif()
protobuf_generate_cpp(ProtoSources ProtoHeaders "${CMAKE_CURRENT_SOURCE_DIR}/remoting/pingpong.proto")
include_directories(${PROTOBUF_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(protobuf_broker broker/protobuf_broker.cpp ${ProtoSources})
target_link_libraries(protobuf_broker ${PROTOBUF_LIBRARIES} CAF::core CAF::io)
add_dependencies(protobuf_broker all_examples)
endif()
if(CAF_ENABLE_QT5_EXAMPLES)
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
message(STATUS "Found Qt5")
#include(${QT_USE_FILE})
QT5_ADD_RESOURCES(GROUP_CHAT_RCS )
QT5_WRAP_UI(GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui)
QT5_WRAP_CPP(GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp)
# generated headers will be in cmake build directory
include_directories(qtsupport
${CMAKE_CURRENT_BINARY_DIR}
${Qt5Core_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS})
set(GROUP_CHAT_SRC qtsupport/qt_group_chat.cpp qtsupport/chatwidget.cpp)
add_executable(qt_group_chat
${GROUP_CHAT_SRC}
${GROUP_CHAT_MOC_SRC}
${GROUP_CHAT_UI_HDR})
target_link_libraries(qt_group_chat
Qt5::Core
Qt5::Gui
Qt5::Widgets
CAF::core
CAF::io)
add_dependencies(qt_group_chat all_examples)
endif()
if(NOT CAF_NO_CURL_EXAMPLES)
find_package(CURL)
if(CURL_FOUND)
add_executable(curl_fuse curl/curl_fuse.cpp)
include_directories(${CURL_INCLUDE_DIRS})
target_link_libraries(curl_fuse ${CMAKE_DL_LIBS} ${CAF_LIBRARIES} ${PTHREAD_LIBRARIES} ${CURL_LIBRARY})
add_dependencies(curl_fuse all_examples)
endif(CURL_FOUND)
if(CAF_ENABLE_CURL_EXAMPLES)
find_package(CURL REQUIRED)
add_executable(curl_fuse curl/curl_fuse.cpp)
include_directories(${CURL_INCLUDE_DIRS})
target_link_libraries(curl_fuse ${CURL_LIBRARY} CAF::core CAF::io)
add_dependencies(curl_fuse all_examples)
endif()
......@@ -4,7 +4,6 @@
#include <iostream>
#include "caf/all.hpp"
#include "caf/io/all.hpp"
using namespace caf;
using std::endl;
......
......@@ -19,9 +19,9 @@ add_enum_consistency_check("caf/intrusive/inbox_result.hpp"
add_enum_consistency_check("caf/intrusive/task_result.hpp"
"src/intrusive/task_result_strings.cpp")
# -- list cpp files for libcaf_core --------------------------------------------
# -- add library target --------------------------------------------------------
set(CAF_CORE_SOURCES
add_library(libcaf_core_obj OBJECT ${CAF_CORE_HEADERS}
src/abstract_actor.cpp
src/abstract_channel.cpp
src/abstract_group.cpp
......@@ -154,140 +154,42 @@ set(CAF_CORE_SOURCES
src/uuid.cpp
)
# -- list cpp files for caf-core-test ------------------------------------------
set(CAF_CORE_TEST_SOURCES
test/actor_clock.cpp
test/actor_factory.cpp
test/actor_lifetime.cpp
test/actor_pool.cpp
test/actor_profiler.cpp
test/actor_registry.cpp
test/actor_system_config.cpp
test/actor_termination.cpp
test/aout.cpp
test/behavior.cpp
test/binary_deserializer.cpp
test/binary_serializer.cpp
test/blocking_actor.cpp
test/broadcast_downstream_manager.cpp
test/byte.cpp
test/composition.cpp
test/config_option.cpp
test/config_option_set.cpp
test/config_value.cpp
test/config_value_adaptor.cpp
test/const_typed_message_view.cpp
test/constructor_attach.cpp
test/continuous_streaming.cpp
test/cow_tuple.cpp
test/custom_exception_handler.cpp
test/decorator/sequencer.cpp
test/deep_to_string.cpp
test/detached_actors.cpp
test/detail/bounds_checker.cpp
test/detail/ini_consumer.cpp
test/detail/limited_vector.cpp
test/detail/meta_object.cpp
test/detail/parse.cpp
test/detail/parser/read_bool.cpp
test/detail/parser/read_floating_point.cpp
test/detail/parser/read_ini.cpp
test/detail/parser/read_number.cpp
test/detail/parser/read_number_or_timespan.cpp
test/detail/parser/read_signed_integer.cpp
test/detail/parser/read_string.cpp
test/detail/parser/read_timespan.cpp
test/detail/parser/read_unsigned_integer.cpp
test/detail/ringbuffer.cpp
test/detail/ripemd_160.cpp
test/detail/serialized_size.cpp
test/detail/tick_emitter.cpp
test/detail/type_id_list_builder.cpp
test/detail/unique_function.cpp
test/detail/unordered_flat_map.cpp
test/dictionary.cpp
test/dynamic_spawn.cpp
test/error.cpp
test/expected.cpp
test/function_view.cpp
test/fused_downstream_manager.cpp
test/handles.cpp
test/hash/fnv.cpp
test/inspector.cpp
test/intrusive/drr_cached_queue.cpp
test/intrusive/drr_queue.cpp
test/intrusive/fifo_inbox.cpp
test/intrusive/lifo_inbox.cpp
test/intrusive/task_queue.cpp
test/intrusive/wdrr_dynamic_multiplexed_queue.cpp
test/intrusive/wdrr_fixed_multiplexed_queue.cpp
test/intrusive_ptr.cpp
test/ipv4_address.cpp
test/ipv4_endpoint.cpp
test/ipv4_subnet.cpp
test/ipv6_address.cpp
test/ipv6_endpoint.cpp
test/ipv6_subnet.cpp
test/local_group.cpp
test/logger.cpp
test/mailbox_element.cpp
test/make_config_value_field.cpp
test/message.cpp
test/message_id.cpp
test/message_lifetime.cpp
test/metaprogramming.cpp
test/mixin/requester.cpp
test/mixin/sender.cpp
test/mock_streaming_classes.cpp
test/native_streaming_classes.cpp
test/node_id.cpp
test/optional.cpp
test/or_else.cpp
test/pipeline_streaming.cpp
test/policy/categorized.cpp
test/policy/select_all.cpp
test/policy/select_any.cpp
test/request_timeout.cpp
test/result.cpp
test/selective_streaming.cpp
test/serialization.cpp
test/settings.cpp
test/simple_timeout.cpp
test/span.cpp
test/stateful_actor.cpp
test/string_algorithms.cpp
test/string_view.cpp
test/sum_type.cpp
test/thread_hook.cpp
test/tracing_data.cpp
test/type_id_list.cpp
test/typed_behavior.cpp
test/typed_message_view.cpp
test/typed_response_promise.cpp
test/typed_spawn.cpp
test/unit.cpp
test/uri.cpp
test/uuid.cpp
test/variant.cpp
)
target_include_directories(libcaf_core_obj PRIVATE
"${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
# -- add library target --------------------------------------------------------
add_library(libcaf_core "${PROJECT_SOURCE_DIR}/cmake/dummy.cpp"
$<TARGET_OBJECTS:libcaf_core_obj>)
add_library(libcaf_core_obj OBJECT ${CAF_CORE_SOURCES} ${CAF_CORE_HEADERS})
target_include_directories(libcaf_core INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
add_library(libcaf_core
"${PROJECT_SOURCE_DIR}/cmake/dummy.cpp"
$<TARGET_OBJECTS:libcaf_core_obj>)
target_include_directories(libcaf_core INTERFACE
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>)
add_library(caf::core ALIAS libcaf_core)
add_library(CAF::core ALIAS libcaf_core)
# -- dependencies and compiler flags -------------------------------------------
if(BUILD_SHARED_LIBS AND NOT WIN32)
target_compile_options(libcaf_core PRIVATE -fPIC)
target_compile_options(libcaf_core_obj PRIVATE -fPIC)
endif()
target_link_libraries(libcaf_core PUBLIC ${CAF_EXTRA_LDFLAGS})
if(NOT TARGET Threads::Threads)
find_package(Threads REQUIRED)
endif()
target_link_libraries(libcaf_core PUBLIC Threads::Threads)
if(MSVC)
target_link_libraries(libcaf_core PUBLIC iphlpapi)
endif()
if(CAF_SANITIZERS)
target_link_libraries(libcaf_core PUBLIC -fsanitize=${CAF_SANITIZERS})
endif()
# -- API exports ---------------------------------------------------------------
generate_export_header(libcaf_core
EXPORT_MACRO_NAME CAF_CORE_EXPORT
......@@ -321,21 +223,142 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/caf"
# -- build unit tests ----------------------------------------------------------
if(NOT CAF_NO_UNIT_TESTS)
add_executable(caf-core-test
test/core-test.cpp
${CAF_CORE_TEST_SOURCES}
$<TARGET_OBJECTS:libcaf_core_obj>)
target_include_directories(caf-core-test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/test")
target_compile_definitions(caf-core-test PRIVATE libcaf_core_EXPORTS)
target_link_libraries(caf-core-test ${CAF_EXTRA_LDFLAGS})
add_test_suites(caf-core-test
"${CMAKE_CURRENT_SOURCE_DIR}"
${CAF_CORE_TEST_SOURCES})
if(NOT CAF_ENABLE_TESTING)
return()
endif()
# -- add this library to the global CAF_LIBRARIES ------------------------------
add_executable(caf-core-test
test/core-test.cpp
$<TARGET_OBJECTS:libcaf_core_obj>)
target_include_directories(caf-core-test PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/test")
target_compile_definitions(caf-core-test PRIVATE libcaf_core_EXPORTS)
list(APPEND CAF_LIBRARIES libcaf_core)
target_link_libraries(caf-core-test PUBLIC CAF::test)
set(CAF_LIBRARIES ${CAF_LIBRARIES} PARENT_SCOPE)
target_link_libraries(caf-core-test PRIVATE
$<TARGET_PROPERTY:libcaf_core,INTERFACE_LINK_LIBRARIES>)
target_include_directories(caf-core-test PRIVATE
"${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
caf_add_test_suites(caf-core-test
actor_clock
actor_factory
actor_lifetime
actor_pool
actor_profiler
actor_registry
actor_system_config
actor_termination
aout
behavior
binary_deserializer
binary_serializer
blocking_actor
broadcast_downstream_manager
byte
composition
config_option
config_option_set
config_value
config_value_adaptor
const_typed_message_view
constructor_attach
continuous_streaming
cow_tuple
decorator.sequencer
deep_to_string
detached_actors
detail.bounds_checker
detail.ini_consumer
detail.limited_vector
detail.meta_object
detail.parse
detail.parser.read_bool
detail.parser.read_floating_point
detail.parser.read_ini
detail.parser.read_number
detail.parser.read_number_or_timespan
detail.parser.read_signed_integer
detail.parser.read_string
detail.parser.read_timespan
detail.parser.read_unsigned_integer
detail.ringbuffer
detail.ripemd_160
detail.serialized_size
detail.tick_emitter
detail.type_id_list_builder
detail.unique_function
detail.unordered_flat_map
dictionary
dynamic_spawn
error
expected
function_view
fused_downstream_manager
handles
hash.fnv
inspector
intrusive.drr_cached_queue
intrusive.drr_queue
intrusive.fifo_inbox
intrusive.lifo_inbox
intrusive.task_queue
intrusive.wdrr_dynamic_multiplexed_queue
intrusive.wdrr_fixed_multiplexed_queue
intrusive_ptr
ipv4_address
ipv4_endpoint
ipv4_subnet
ipv6_address
ipv6_endpoint
ipv6_subnet
local_group
logger
mailbox_element
make_config_value_field
message
message_id
message_lifetime
metaprogramming
mixin.requester
mixin.sender
mock_streaming_classes
native_streaming_classes
node_id
optional
or_else
pipeline_streaming
policy.categorized
policy.select_all
policy.select_any
request_timeout
result
selective_streaming
serialization
settings
simple_timeout
span
stateful_actor
string_algorithms
string_view
sum_type
thread_hook
tracing_data
type_id_list
typed_behavior
typed_message_view
typed_response_promise
typed_spawn
unit
uri
uuid
variant
)
if(CAF_ENABLE_EXCEPTIONS)
caf_add_test_suites(caf-core-test custom_exception_handler)
endif()
......@@ -20,7 +20,7 @@
#include "caf/config.hpp"
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
# include <stdexcept>
#endif
......@@ -33,32 +33,32 @@ CAF_CORE_EXPORT void log_cstring_error(const char* cstring);
} // namespace caf::detail
#ifdef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
# define CAF_RAISE_ERROR_IMPL_1(msg) \
# define CAF_RAISE_ERROR_IMPL_2(exception_type, msg) \
do { \
::caf::detail::log_cstring_error(msg); \
CAF_CRITICAL(msg); \
throw exception_type(msg); \
} while (false)
# define CAF_RAISE_ERROR_IMPL_2(unused, msg) CAF_RAISE_ERROR_IMPL_1(msg)
# define CAF_RAISE_ERROR_IMPL_1(msg) \
CAF_RAISE_ERROR_IMPL_2(std::runtime_error, msg)
#else // CAF_NO_EXCEPTIONS
#else // CAF_ENABLE_EXCEPTIONS
# define CAF_RAISE_ERROR_IMPL_2(exception_type, msg) \
# define CAF_RAISE_ERROR_IMPL_1(msg) \
do { \
::caf::detail::log_cstring_error(msg); \
throw exception_type(msg); \
CAF_CRITICAL(msg); \
} while (false)
# define CAF_RAISE_ERROR_IMPL_1(msg) \
CAF_RAISE_ERROR_IMPL_2(std::runtime_error, msg)
# define CAF_RAISE_ERROR_IMPL_2(unused, msg) CAF_RAISE_ERROR_IMPL_1(msg)
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
#ifdef CAF_MSVC
/// Throws an exception if `CAF_NO_EXCEPTIONS` is undefined, otherwise calls
/// Throws an exception if `CAF_ENABLE_EXCEPTIONS` is defined, otherwise calls
/// abort() after printing a given message.
# define CAF_RAISE_ERROR(...) \
CAF_PP_CAT(CAF_PP_OVERLOAD(CAF_RAISE_ERROR_IMPL_, \
......@@ -67,7 +67,7 @@ CAF_CORE_EXPORT void log_cstring_error(const char* cstring);
#else // CAF_MSVC
/// Throws an exception if `CAF_NO_EXCEPTIONS` is undefined, otherwise calls
/// Throws an exception if `CAF_ENABLE_EXCEPTIONS` is defined, otherwise calls
/// abort() after printing a given message.
# define CAF_RAISE_ERROR(...) \
CAF_PP_OVERLOAD(CAF_RAISE_ERROR_IMPL_, __VA_ARGS__)(__VA_ARGS__)
......
......@@ -20,9 +20,9 @@
#include "caf/config.hpp"
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
# include <exception>
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
#include <forward_list>
#include <map>
......@@ -190,10 +190,10 @@ public:
/// Function object for handling exit messages.
using exit_handler = std::function<void(pointer, exit_msg&)>;
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
/// Function object for handling exit messages.
using exception_handler = std::function<error(pointer, std::exception_ptr&)>;
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
/// Consumes messages from the mailbox.
struct mailbox_visitor {
......@@ -232,9 +232,9 @@ public:
static void default_exit_handler(pointer ptr, exit_msg& x);
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
static error default_exception_handler(pointer ptr, std::exception_ptr& x);
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
// -- constructors and destructors -------------------------------------------
......@@ -389,7 +389,7 @@ public:
set_exit_handler([fun](scheduled_actor*, exit_msg& x) { fun(x); });
}
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
/// Sets a custom exception handler for this actor. If multiple handlers are
/// defined, only the functor that was added *last* is being executed.
inline void set_exception_handler(exception_handler fun) {
......@@ -408,7 +408,7 @@ public:
set_exception_handler(
[f](scheduled_actor*, std::exception_ptr& x) { return f(x); });
}
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
/// @cond PRIVATE
......@@ -703,10 +703,10 @@ protected:
/// Pointer to a private thread object associated with a detached actor.
detail::private_thread* private_thread_;
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
/// Customization point for setting a default exception callback.
exception_handler exception_handler_;
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
/// @endcond
};
......
......@@ -174,7 +174,7 @@ public:
self_->set_exit_handler(std::forward<Fun>(fun));
}
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
/// @copydoc scheduled_actor::set_exception_handler
template <class Fun>
......@@ -182,7 +182,7 @@ public:
self_->set_exception_handler(std::forward<Fun>(fun));
}
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
// -- linking and monitoring -------------------------------------------------
......
......@@ -107,7 +107,7 @@ void blocking_actor::launch(execution_unit*, bool, bool hide) {
CAF_PUSH_AID_FROM_PTR(self);
self->initialize();
error rsn;
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
try {
self->act();
rsn = self->fail_state_;
......
......@@ -97,7 +97,7 @@ void scheduled_actor::default_exit_handler(scheduled_actor* ptr, exit_msg& x) {
default_error_handler(ptr, x.reason);
}
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
error scheduled_actor::default_exception_handler(pointer ptr,
std::exception_ptr& x) {
CAF_ASSERT(x != nullptr);
......@@ -115,7 +115,7 @@ error scheduled_actor::default_exception_handler(pointer ptr,
}
return sec::runtime_error;
}
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
// -- constructors and destructors ---------------------------------------------
......@@ -129,10 +129,10 @@ scheduled_actor::scheduled_actor(actor_config& cfg)
node_down_handler_(default_node_down_handler),
exit_handler_(default_exit_handler),
private_thread_(nullptr)
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
,
exception_handler_(default_exception_handler)
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
{
auto& sys_cfg = home_system().config();
auto interval = sys_cfg.stream_tick_duration();
......@@ -743,9 +743,9 @@ bool scheduled_actor::activate(execution_unit* ctx) {
CAF_LOG_ERROR("activate called on a terminated actor");
return false;
}
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
try {
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
if (!getf(is_initialized_flag)) {
initialize();
if (finalize()) {
......@@ -754,7 +754,7 @@ bool scheduled_actor::activate(execution_unit* ctx) {
}
CAF_LOG_DEBUG("initialized actor:" << CAF_ARG(name()));
}
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
} catch (...) {
CAF_LOG_ERROR("actor died during initialization");
auto eptr = std::current_exception();
......@@ -762,7 +762,7 @@ bool scheduled_actor::activate(execution_unit* ctx) {
finalize();
return false;
}
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
return true;
}
......@@ -779,7 +779,7 @@ auto scheduled_actor::activate(execution_unit* ctx, mailbox_element& x)
auto scheduled_actor::reactivate(mailbox_element& x) -> activation_result {
CAF_LOG_TRACE(CAF_ARG(x));
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
auto handle_exception = [&](std::exception_ptr eptr) {
auto err = call_handler(exception_handler_, this, eptr);
if (x.mid.is_request()) {
......@@ -789,7 +789,7 @@ auto scheduled_actor::reactivate(mailbox_element& x) -> activation_result {
quit(std::move(err));
};
try {
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
switch (consume(x)) {
case invoke_message_result::dropped:
return activation_result::dropped;
......@@ -803,7 +803,7 @@ auto scheduled_actor::reactivate(mailbox_element& x) -> activation_result {
case invoke_message_result::skipped:
return activation_result::skipped;
}
#ifndef CAF_NO_EXCEPTIONS
#ifdef CAF_ENABLE_EXCEPTIONS
} catch (std::exception& e) {
CAF_LOG_INFO("actor died because of an exception, what: " << e.what());
static_cast<void>(e); // keep compiler happy when not logging
......@@ -814,7 +814,7 @@ auto scheduled_actor::reactivate(mailbox_element& x) -> activation_result {
}
finalize();
return activation_result::terminated;
#endif // CAF_NO_EXCEPTIONS
#endif // CAF_ENABLE_EXCEPTIONS
}
// -- behavior management ----------------------------------------------------
......
......@@ -24,7 +24,9 @@
using namespace caf;
#ifndef CAF_NO_EXCEPTIONS
#ifndef CAF_ENABLE_EXCEPTIONS
# error "building unit test for exception handlers in no-exceptions build"
#endif
class exception_testee : public event_based_actor {
public:
......@@ -77,11 +79,3 @@ CAF_TEST(test_custom_exception_handler) {
// receive all down messages
self->wait_for(testee1, testee2, testee3);
}
#else // CAF_NO_EXCEPTIONS
CAF_TEST(no_exceptions_dummy) {
CAF_CHECK_EQUAL(true, true);
}
#endif // CAF_NO_EXCEPTIONS
......@@ -10,9 +10,9 @@ add_enum_consistency_check("caf/io/basp/message_type.hpp"
add_enum_consistency_check("caf/io/network/operation.hpp"
"src/io/network/operation_strings.cpp")
# -- list cpp files ------------------------------------------------------------
# -- add library target --------------------------------------------------------
set(CAF_IO_SOURCES
add_library(libcaf_io_obj OBJECT ${CAF_IO_HEADERS}
src/detail/socket_guard.cpp
src/io/abstract_broker.cpp
src/io/basp/header.cpp
......@@ -55,38 +55,31 @@ set(CAF_IO_SOURCES
src/policy/udp.cpp
)
set(CAF_IO_TEST_SOURCES
test/io/basp/message_queue.cpp
test/io/basp_broker.cpp
test/io/broker.cpp
test/io/http_broker.cpp
test/io/monitor.cpp
test/io/network/default_multiplexer.cpp
test/io/network/ip_endpoint.cpp
test/io/receive_buffer.cpp
test/io/remote_actor.cpp
test/io/remote_group.cpp
test/io/remote_spawn.cpp
test/io/unpublish.cpp
test/io/worker.cpp
)
# -- add library target --------------------------------------------------------
add_library(libcaf_io_obj OBJECT ${CAF_IO_SOURCES} ${CAF_IO_HEADERS})
target_include_directories(libcaf_io_obj PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}")
add_library(libcaf_io
"${PROJECT_SOURCE_DIR}/cmake/dummy.cpp"
$<TARGET_OBJECTS:libcaf_io_obj>)
add_library(caf::io ALIAS libcaf_io)
target_include_directories(libcaf_io INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
add_library(CAF::io ALIAS libcaf_io)
if(BUILD_SHARED_LIBS AND NOT WIN32)
target_compile_options(libcaf_io PRIVATE -fPIC)
target_compile_options(libcaf_io_obj PRIVATE -fPIC)
endif()
target_link_libraries(libcaf_io PUBLIC caf::core ${CAF_EXTRA_LDFLAGS})
target_include_directories(libcaf_io_obj PRIVATE
$<TARGET_PROPERTY:libcaf_core,INTERFACE_INCLUDE_DIRECTORIES>)
target_link_libraries(libcaf_io PUBLIC CAF::core)
if(MSVC)
target_link_libraries(libcaf_io PUBLIC ws2_32 iphlpapi)
endif()
generate_export_header(libcaf_io
EXPORT_MACRO_NAME CAF_IO_EXPORT
......@@ -119,21 +112,37 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/caf"
# -- build unit tests ----------------------------------------------------------
if(NOT CAF_NO_UNIT_TESTS)
add_executable(caf-io-test
test/io-test.cpp
${CAF_IO_TEST_SOURCES}
$<TARGET_OBJECTS:libcaf_io_obj>)
target_include_directories(caf-io-test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/test")
target_compile_definitions(caf-io-test PRIVATE libcaf_io_EXPORTS)
target_link_libraries(caf-io-test caf::core ${CAF_EXTRA_LDFLAGS})
add_test_suites(caf-io-test
"${CMAKE_CURRENT_SOURCE_DIR}"
${CAF_IO_TEST_SOURCES})
if(NOT CAF_ENABLE_TESTING)
return()
endif()
# -- add this library to the global CAF_LIBRARIES ------------------------------
add_executable(caf-io-test
test/io-test.cpp
$<TARGET_OBJECTS:libcaf_io_obj>)
target_include_directories(caf-io-test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/test")
target_compile_definitions(caf-io-test PRIVATE libcaf_io_EXPORTS)
list(APPEND CAF_LIBRARIES libcaf_io)
target_link_libraries(caf-io-test PRIVATE CAF::core CAF::test)
set(CAF_LIBRARIES ${CAF_LIBRARIES} PARENT_SCOPE)
target_link_libraries(caf-io-test PRIVATE
$<TARGET_PROPERTY:libcaf_io,INTERFACE_LINK_LIBRARIES>)
target_include_directories(caf-io-test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
caf_add_test_suites(caf-io-test
io.basp.message_queue
io.basp_broker
io.broker
io.http_broker
io.monitor
io.network.default_multiplexer
io.network.ip_endpoint
io.receive_buffer
io.remote_actor
io.remote_group
io.remote_spawn
io.unpublish
io.worker
)
......@@ -2,9 +2,9 @@
file(GLOB_RECURSE CAF_OPENSSL_HEADERS "caf/*.hpp")
# -- list cpp files ------------------------------------------------------------
# -- add library target --------------------------------------------------------
set(CAF_OPENSSL_SOURCES
add_library(libcaf_openssl_obj OBJECT ${CAF_OPENSSL_HEADERS}
src/openssl/manager.cpp
src/openssl/middleman_actor.cpp
src/openssl/publish.cpp
......@@ -12,33 +12,36 @@ set(CAF_OPENSSL_SOURCES
src/openssl/session.cpp
)
set(CAF_OPENSSL_TEST_SOURCES
test/openssl/authentication.cpp
test/openssl/remote_actor.cpp
)
# -- add library target --------------------------------------------------------
add_library(libcaf_openssl_obj OBJECT ${CAF_OPENSSL_SOURCES} ${CAF_OPENSSL_HEADERS})
target_include_directories(libcaf_openssl_obj PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}")
add_library(libcaf_openssl
"${PROJECT_SOURCE_DIR}/cmake/dummy.cpp"
$<TARGET_OBJECTS:libcaf_openssl_obj>)
add_library(caf::openssl ALIAS libcaf_openssl)
target_include_directories(libcaf_openssl INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
add_library(CAF::openssl ALIAS libcaf_openssl)
if(BUILD_SHARED_LIBS AND NOT WIN32)
target_compile_options(libcaf_openssl PRIVATE -fPIC)
target_compile_options(libcaf_openssl_obj PRIVATE -fPIC)
endif()
target_link_libraries(libcaf_openssl PUBLIC
caf::core caf::io ${OPENSSL_LIBRARIES})
if(NOT APPLE AND NOT WIN32)
target_link_libraries(libcaf_openssl PUBLIC "-pthread")
if(NOT TARGET OpenSSL::SSL OR NOT TARGET OpenSSL::Crypto)
find_package(OpenSSL REQUIRED)
endif()
target_include_directories(libcaf_openssl_obj PRIVATE
$<TARGET_PROPERTY:libcaf_core,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:libcaf_io,INTERFACE_INCLUDE_DIRECTORIES>
${OPENSSL_INCLUDE_DIR})
target_link_libraries(libcaf_openssl PUBLIC
CAF::core CAF::io
OpenSSL::SSL OpenSSL::Crypto)
generate_export_header(libcaf_openssl
EXPORT_MACRO_NAME CAF_OPENSSL_EXPORT
EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/caf/detail/openssl_export.hpp"
......@@ -75,22 +78,26 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/caf"
# -- build unit tests ----------------------------------------------------------
if(NOT CAF_NO_UNIT_TESTS)
add_executable(caf-openssl-test
test/openssl-test.cpp
${CAF_OPENSSL_TEST_SOURCES}
$<TARGET_OBJECTS:libcaf_openssl_obj>)
target_include_directories(caf-openssl-test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/test")
target_compile_definitions(caf-openssl-test PRIVATE libcaf_openssl_EXPORTS)
target_link_libraries(caf-openssl-test caf::core caf::io
${OPENSSL_LIBRARIES} ${CAF_EXTRA_LDFLAGS})
add_test_suites(caf-openssl-test
"${CMAKE_CURRENT_SOURCE_DIR}"
${CAF_OPENSSL_TEST_SOURCES})
if(NOT CAF_ENABLE_TESTING)
return()
endif()
# -- add this library to the global CAF_LIBRARIES ------------------------------
add_executable(caf-openssl-test
test/openssl-test.cpp
${CAF_OPENSSL_TEST_SOURCES}
$<TARGET_OBJECTS:libcaf_openssl_obj>)
target_include_directories(caf-openssl-test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/test")
list(APPEND CAF_LIBRARIES libcaf_openssl)
target_compile_definitions(caf-openssl-test PRIVATE libcaf_openssl_EXPORTS)
set(CAF_LIBRARIES ${CAF_LIBRARIES} PARENT_SCOPE)
target_link_libraries(caf-openssl-test PRIVATE
CAF::io CAF::core CAF::test OpenSSL::SSL OpenSSL::Crypto)
target_include_directories(caf-openssl-test PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}")
caf_add_test_suites(caf-openssl-test
openssl.authentication
openssl.remote_actor
)
add_custom_target(all_tools)
include_directories(${LIBCAF_INCLUDE_DIRS})
macro(add name)
add_executable(${name} ${name}.cpp ${ARGN})
target_link_libraries(${name}
${CAF_EXTRA_LDFLAGS}
${CAF_LIBRARIES}
${PTHREAD_LIBRARIES})
install(FILES ${name}.cpp DESTINATION ${CMAKE_INSTALL_DATADIR}/caf/tools/${folder})
install(FILES ${name}.cpp DESTINATION ${CMAKE_INSTALL_DATADIR}/caf/tools)
add_dependencies(${name} all_tools)
endmacro()
if(WIN32)
message(STATUS "skip caf-run (not supported on Windows)")
else()
add(caf-run)
endif()
add(caf-vec)
target_link_libraries(caf-vec PRIVATE CAF::core)
if(TARGET CAF::io)
if(WIN32)
message(STATUS "skip caf-run (not supported on Windows)")
else()
add(caf-run)
target_link_libraries(caf-run PRIVATE CAF::io CAF::core)
endif()
endif()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment