Unverified Commit 5106b9f9 authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #49

Update CMake scaffold
parents 0bc32b58 47b07613
......@@ -3,12 +3,59 @@
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(caf_incubator C CXX)
# -- CMake includes for C/C++ features -----------------------------------------
# -- project options -----------------------------------------------------------
include(CheckCSourceCompiles)
include(CheckCSourceRuns)
option(BUILD_SHARED_LIBS "Build all modules as shared library" ON)
# -- set useful CMake options --------------------------------------------------
# -- includes ------------------------------------------------------------------
include(CMakePackageConfigHelpers) # For creating .cmake files
include(CheckCSourceCompiles) # Check whether compiler works
include(CheckCSourceRuns) # Check whether compiler produces binaries
include(GNUInstallDirs) # Sets default install paths
include(GenerateExportHeader) # Auto-generates dllexport macros
# -- check whether we are running as CMake subdirectory ------------------------
get_directory_property(_parent PARENT_DIRECTORY)
if(_parent)
set(caf_is_subproject ON)
else()
set(caf_is_subproject OFF)
endif()
unset(_parent)
# enable tests if not disabled
if(NOT CAF_NO_UNIT_TESTS)
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()
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 --------------------------------
if(NOT CMAKE_CROSSCOMPILING)
# Check whether the user already provided flags that enable C++ >= 17.
......@@ -42,6 +89,22 @@ 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")
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)
......@@ -57,12 +120,6 @@ add_custom_target(configure COMMAND ${CMAKE_CURRENT_BINARY_DIR}/config.status)
# -- check for static builds ---------------------------------------------------
# Shared libs are currently not supported on Windows.
if(WIN32 AND NOT CAF_BUILD_STATIC_ONLY)
message(STATUS "CAF currently only supports static-only builds on Windows")
set(CAF_BUILD_STATIC_ONLY yes)
endif()
if(CAF_BUILD_STATIC_RUNTIME)
set(flags_configs
CMAKE_CXX_FLAGS
......@@ -94,7 +151,14 @@ else()
set(CAF_BUILD_STATIC_RUNTIME no)
endif()
# -- utility functions ---------------------------------------------------------
# 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
......@@ -127,7 +191,7 @@ add_executable(caf-generate-enum-strings cmake/caf-generate-enum-strings.cpp)
function(enum_to_string relative_input_file relative_output_file)
set(input "${CMAKE_CURRENT_SOURCE_DIR}/${relative_input_file}")
set(output "${CMAKE_CURRENT_BINARY_DIR}/${relative_output_file}")
set(output "${CMAKE_BINARY_DIR}/${relative_output_file}")
add_custom_command(OUTPUT "${output}"
COMMAND caf-generate-enum-strings "${input}" "${output}"
DEPENDS caf-generate-enum-strings "${input}")
......@@ -223,10 +287,10 @@ if(CAF_MORE_WARNINGS)
endif()
# Enable ASAN if requested by the user.
if(CAF_ENABLE_ADDRESS_SANITIZER AND NOT WIN32)
add_compile_options("-fsanitize=address"
if(CAF_SANITIZERS)
add_compile_options("-fsanitize=${CAF_SANITIZERS}"
"-fno-omit-frame-pointer")
list(APPEND CAF_EXTRA_LDFLAGS "-fsanitize=address")
list(APPEND CAF_EXTRA_LDFLAGS "-fsanitize=${CAF_SANITIZERS}")
endif()
# -pthread is ignored on MacOSX but required on other platforms
......@@ -238,14 +302,11 @@ endif()
if(MINGW)
add_definitions(-D_WIN32_WINNT=0x0600)
add_definitions(-DWIN32)
include(GenerateExportHeader)
list(APPEND CAF_EXTRA_LDFLAGS -lws2_32 -liphlpapi -lpsapi)
# build static to avoid runtime dependencies to GCC libraries
build_string("EXTRA_FLAGS" "-static")
elseif(CYGWIN)
build_string("EXTRA_FLAGS" "-U__STRICT_ANSI__")
else()
build_string("EXTRA_FLAGS" "-fPIC")
endif()
# Add Windows-specific linker flags.
......@@ -312,92 +373,38 @@ add_custom_target(uninstall
COMMAND "${CMAKE_COMMAND}" -P
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
# -- utility macro for adding unit tests ---------------------------------------
# -- set include paths for all subprojects -------------------------------------
if(NOT CAF_NO_UNIT_TESTS)
enable_testing()
macro(add_unit_tests globstr)
file(GLOB_RECURSE tests "${globstr}")
set(CAF_ALL_UNIT_TESTS ${CAF_ALL_UNIT_TESTS} ${tests})
endmacro()
else()
macro(add_unit_tests globstr)
# do nothing (unit tests disabled)
endmacro()
endif()
include_directories("${CMAKE_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/libcaf_net"
"${CAF_INCLUDE_DIRS}")
# -- add targets ---------------------------------------------------------------
################################################################################
# add targets #
################################################################################
include_directories("${CAF_INCLUDE_DIRS}")
add_subdirectory(libcaf_net)
add_subdirectory(libcaf_bb)
macro(add_caf_lib name header_only)
string(TOUPPER ${name} upper_name)
set(full_name "libcaf_${name}")
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${full_name}")
message(STATUS "skip ${full_name} (not found)")
else()
add_subdirectory(${full_name})
if(NOT ${header_only})
set(shared_target ${full_name}_shared)
set(static_target ${full_name}_static)
set(lib_varname CAF_LIBRARY_${upper_name})
set(lib_varname_static ${lib_varname}_STATIC)
if(NOT CAF_BUILD_STATIC_ONLY)
set(${lib_varname} ${shared_target})
set(CAF_LIBRARIES ${CAF_LIBRARIES} ${shared_target})
else()
set(${lib_varname} ${static_target})
set(CAF_LIBRARIES ${CAF_LIBRARIES} ${static_target})
endif()
if(CAF_BUILD_STATIC_ONLY OR CAF_BUILD_STATIC)
set(${lib_varname_static} ${static_target})
endif()
endif()
add_unit_tests("${full_name}/test/*.cpp")
# add headers to include directories so other subprojects can use them
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/libcaf_${name}")
endif()
endmacro()
export(EXPORT CAFTargets FILE CAFTargets.cmake NAMESPACE caf::)
add_caf_lib(bb yes)
add_caf_lib(net no)
install(EXPORT CAFTargets
DESTINATION "${INSTALL_CAF_CMAKEDIR}"
NAMESPACE caf::)
# -- unit tests setup ----------------------------------------------------------
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/CAFConfigVersion.cmake"
VERSION ${CAF_VERSION}
COMPATIBILITY ExactVersion)
if(NOT CAF_NO_UNIT_TESTS)
# setup unit test binary
add_executable(incubator-test
"cmake/incubator-test.cpp"
${CAF_ALL_UNIT_TESTS})
target_link_libraries(incubator-test
${CAF_EXTRA_LDFLAGS}
${CAF_LIBRARIES}
${PTHREAD_LIBRARIES})
add_custom_target(all_unit_tests)
add_dependencies(incubator-test all_unit_tests)
# enumerate all test suites.
foreach(test ${CAF_ALL_UNIT_TESTS})
file(STRINGS ${test} contents)
foreach(line ${contents})
if ("${line}" MATCHES "CAF_SUITE (.*)")
string(REGEX REPLACE ".* CAF_SUITE (.*)" "\\1" suite ${line})
list(APPEND suites ${suite})
endif()
endforeach()
endforeach()
list(REMOVE_DUPLICATES suites)
# creates one CMake test per test suite.
macro (make_test suite)
string(REPLACE " " "_" test_name ${suite})
set(caf_test ${EXECUTABLE_OUTPUT_PATH}/incubator-test)
add_test(${test_name} ${caf_test} -r 300 -n -v 5 -s "^${suite}$" ${ARGN})
endmacro ()
list(LENGTH suites num_suites)
message(STATUS "Found ${num_suites} test suites")
foreach(suite ${suites})
make_test("${suite}")
endforeach ()
endif()
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}")
# -- print summary -------------------------------------------------------------
......@@ -425,8 +432,7 @@ if(NOT CAF_NO_SUMMARY)
"\n====================| Build Summary |===================="
"\n"
"\nBuild type: ${CMAKE_BUILD_TYPE}"
"\nBuild static: ${CAF_BUILD_STATIC}"
"\nBuild static only: ${CAF_BUILD_STATIC_ONLY}"
"\nLink type: ${LINK_TYPE}"
"\nBuild static runtime: ${CAF_BUILD_STATIC_RUNTIME}"
"\n"
"\nCXX: ${CMAKE_CXX_COMPILER}"
......
......@@ -9,7 +9,7 @@ defaultReleaseBuildFlags = [
// Default CMake flags for debug builds.
defaultDebugBuildFlags = defaultReleaseBuildFlags + [
'CAF_ENABLE_ADDRESS_SANITIZER:BOOL=yes',
'CAF_SANITIZERS:STRING=address,undefined',
'CAF_LOG_LEVEL:STRING=TRACE',
]
......@@ -61,6 +61,7 @@ config = [
builds: ['debug'],
tools: ['gcc-8'],
extraSteps: ['coverageReport'],
extraFlags: ['BUILD_SHARED_LIBS:BOOL=OFF'],
]],
['fedora-28', [
builds: ['release'],
......@@ -94,19 +95,13 @@ config = [
],
// CMake flags by OS and build type to override defaults for individual builds.
buildFlags: [
Windows: [
debug: defaultDebugBuildFlags + [
'CAF_BUILD_STATIC_ONLY:BOOL=yes',
],
release: defaultReleaseBuildFlags + [
'CAF_BUILD_STATIC_ONLY:BOOL=yes',
],
],
nop: [],
],
// Configures what binary the coverage report uses and what paths to exclude.
coverage: [
binary: 'build/incubator-test',
binary: 'build/libcaf_net/caf-net-test',
relativeExcludePaths: [
'libcaf_net/test'
],
],
]
......
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_dependency(Threads)
include("${CMAKE_CURRENT_LIST_DIR}/CAFTargets.cmake")
......@@ -2,7 +2,7 @@
#
# Use this module as follows:
#
# find_package(CAF [COMPONENTS <core|io|opencl|...>*] [REQUIRED])
# find_package(CAF [COMPONENTS <core|io|openssl|...>*] [REQUIRED])
#
# Variables used by this module (they can change the default behaviour and need
# to be set before calling find_package):
......@@ -61,12 +61,13 @@ foreach (comp ${CAF_FIND_COMPONENTS})
NAMES
caf/detail/build_config.hpp
HINTS
${CAF_ROOT_DIR}
${header_hints}
/usr/include
/usr/local/include
/opt/local/include
/sw/include
${CMAKE_INSTALL_PREFIX}/include)
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
if ("${caf_build_header_path}" STREQUAL "caf_build_header_path-NOTFOUND")
message(WARNING "Found all.hpp for CAF core, but not build_config.hpp")
set(CAF_${comp}_FOUND false)
......@@ -84,14 +85,14 @@ foreach (comp ${CAF_FIND_COMPONENTS})
find_library(CAF_LIBRARY_${UPPERCOMP}
NAMES
"caf_${comp}"
"caf_${comp}_static"
HINTS
${library_hints}
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
${CMAKE_INSTALL_PREFIX}/lib)
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_BUILD_TYPE})
mark_as_advanced(CAF_LIBRARY_${UPPERCOMP})
if ("${CAF_LIBRARY_${UPPERCOMP}}"
STREQUAL "CAF_LIBRARY_${UPPERCOMP}-NOTFOUND")
......@@ -119,3 +120,36 @@ mark_as_advanced(CAF_ROOT_DIR
CAF_LIBRARIES
CAF_INCLUDE_DIRS)
if (CAF_core_FOUND AND NOT TARGET caf::core)
add_library(caf::core UNKNOWN IMPORTED)
set_target_properties(caf::core PROPERTIES
IMPORTED_LOCATION "${CAF_LIBRARY_CORE}"
INTERFACE_INCLUDE_DIRECTORIES "${CAF_INCLUDE_DIR_CORE}")
endif ()
if (CAF_io_FOUND AND NOT TARGET caf::io)
add_library(caf::io UNKNOWN IMPORTED)
set_target_properties(caf::io PROPERTIES
IMPORTED_LOCATION "${CAF_LIBRARY_IO}"
INTERFACE_INCLUDE_DIRECTORIES "${CAF_INCLUDE_DIR_IO}"
INTERFACE_LINK_LIBRARIES "caf::core")
endif ()
if (CAF_openssl_FOUND AND NOT TARGET caf::openssl)
add_library(caf::openssl UNKNOWN IMPORTED)
set_target_properties(caf::openssl PROPERTIES
IMPORTED_LOCATION "${CAF_LIBRARY_OPENSSL}"
INTERFACE_INCLUDE_DIRECTORIES "${CAF_INCLUDE_DIR_OPENSSL}"
INTERFACE_LINK_LIBRARIES "caf::core;caf::io")
if (NOT BUILD_SHARED_LIBS)
include(CMakeFindDependencyMacro)
set(OPENSSL_USE_STATIC_LIBS TRUE)
find_dependency(OpenSSL)
set_property(TARGET caf::openssl APPEND PROPERTY
INTERFACE_LINK_LIBRARIES "OpenSSL::SSL")
endif ()
endif ()
if (CAF_test_FOUND AND NOT TARGET caf::test)
add_library(caf::test INTERFACE IMPORTED)
set_target_properties(caf::test PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${CAF_INCLUDE_DIR_TEST}"
INTERFACE_LINK_LIBRARIES "caf::core")
endif ()
......@@ -99,20 +99,22 @@ int main(int argc, char** argv) {
cerr << "unable to open output file: " << argv[1] << '\n';
return EXIT_FAILURE;
}
std::string namespace_str;
for (size_t i = 0; i < namespaces.size() - 1; ++i)
namespace_str += namespaces[i] + "::";
namespace_str += namespaces[namespaces.size() - 1];
// Print file header.
out << "#include \"" << namespaces[0];
for (size_t i = 1; i < namespaces.size(); ++i)
out << '/' << namespaces[i];
out << '/' << enum_name << ".hpp\"\n\n"
<< "#include <string>\n\n"
<< "namespace " << namespaces[0] << " {\n";
for (size_t i = 1; i < namespaces.size(); ++i)
out << "namespace " << namespaces[i] << " {\n";
<< "namespace ";
out << namespace_str << " {\n";
out << "\nstd::string to_string(" << enum_name << " x) {\n"
<< " switch(x) {\n"
<< " switch (x) {\n"
<< " default:\n"
<< " return \"???\";\n";
// Read until hitting the closing '}'.
std::string case_label_prefix;
if (is_enum_class)
......@@ -136,6 +138,5 @@ int main(int argc, char** argv) {
// Done. Print file footer and exit.
out << " };\n"
<< "}\n\n";
for (auto i = namespaces.rbegin(); i != namespaces.rend(); ++i)
out << "} // namespace " << *i << '\n';
out << "} // namespace " << namespace_str << '\n';
}
......@@ -43,10 +43,11 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--prefix=PREFIX installation directory [/usr/local]
Debugging:
--enable-asan build with address sanitizer
--with-sanitizers=LIST build with this list of sanitizers enabled
Convenience options:
--dev-mode sets --build-type=debug and --enable-asan
--dev-mode sets --build-type=debug and
--sanitizers=address,undefined
Influential Environment Variables (only on first invocation):
CXX C++ compiler command
......@@ -116,8 +117,8 @@ while [ $# -ne 0 ]; do
--prefix=*)
append_cache_entry CMAKE_INSTALL_PREFIX PATH "$optarg"
;;
--enable-asan)
append_cache_entry CAF_ENABLE_ADDRESS_SANITIZER BOOL yes
--with-sanitizers=*)
append_cache_entry CAF_SANITIZERS STRING "$optarg"
;;
--more-warnings)
append_cache_entry CAF_MORE_WARNINGS BOOL yes
......@@ -159,9 +160,6 @@ while [ $# -ne 0 ]; do
--no-unit-tests)
append_cache_entry CAF_NO_UNIT_TESTS BOOL yes
;;
--no-opencl)
append_cache_entry CAF_NO_OPENCL BOOL yes
;;
--no-openssl)
append_cache_entry CAF_NO_OPENSSL BOOL yes
;;
......@@ -176,7 +174,7 @@ while [ $# -ne 0 ]; do
;;
--dev-mode)
append_cache_entry CMAKE_BUILD_TYPE STRING Debug
append_cache_entry CAF_ENABLE_ADDRESS_SANITIZER BOOL yes
append_cache_entry CAF_SANITIZERS STRING address,undefined
;;
*)
echo "Invalid option '$1'. Try $0 --help to see available options."
......
cmake_minimum_required(VERSION 2.8.12)
project(caf_bb C CXX)
# -- get header files for creating "proper" XCode projects ---------------------
# get header files; only needed by CMake generators,
# e.g., for creating proper Xcode projects
file(GLOB_RECURSE LIBCAF_BB_HDRS "caf/*.hpp")
file(GLOB_RECURSE CAF_BB_HEADERS "caf/*.hpp")
# -- list cpp files for caf::bb ------------------------------------------------
set(CAF_BB_SOURCES
# nop
)
# -- list cpp files for caf-bb-test --------------------------------------------
set(CAF_BB_TEST_SOURCES
test/container_source.cpp
test/stream_reader.cpp
test/tokenized_integer_reader.cpp
)
# -- add library target --------------------------------------------------------
# --> Uncomment this block when adding the first .cpp file
#
# # list cpp files excluding platform-dependent files
# set(LIBCAF_BB_SRCS
# )
#
# add_custom_target(libcaf_bb)
#
# # build shared library if not compiling static only
# if (NOT CAF_BUILD_STATIC_ONLY)
# add_library(libcaf_bb_shared SHARED ${LIBCAF_BB_SRCS} ${LIBCAF_BB_HDRS})
# target_link_libraries(libcaf_bb_shared ${CAF_EXTRA_LDFLAGS})
# target_include_directories(libcaf_bb_shared PUBLIC
# $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
# $<INSTALL_INTERFACE:include>
# )
# set_target_properties(libcaf_bb_shared
# PROPERTIES
# add_library(libcaf_bb_obj OBJECT ${CAF_BB_SOURCES} ${CAF_BB_HEADERS})
#
# add_library(libcaf_bb $<TARGET_OBJECTS:libcaf_bb_obj>)
#
# add_library(caf::bb ALIAS libcaf_bb)
#
# if(BUILD_SHARED_LIBS AND NOT WIN32)
# target_compile_options(libcaf_bb PRIVATE -fPIC)
# target_compile_options(libcaf_bb_obj PRIVATE -fPIC)
# endif()
#
# target_link_libraries(libcaf_bb PUBLIC ${CAF_EXTRA_LDFLAGS} ${CAF_LIBRARIES})
#
# generate_export_header(libcaf_bb
# EXPORT_MACRO_NAME CAF_BB_EXPORT
# EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/caf/detail/bb_export.hpp"
# STATIC_DEFINE CAF_STATIC_BUILD)
#
# target_compile_definitions(libcaf_bb_obj PRIVATE libcaf_bb_EXPORTS)
#
# set_target_properties(libcaf_bb PROPERTIES
# EXPORT_NAME bb
# SOVERSION ${CAF_VERSION}
# VERSION ${CAF_VERSION}
# OUTPUT_NAME caf_bb
# )
# install(TARGETS libcaf_bb_shared
# RUNTIME DESTINATION bin
# LIBRARY DESTINATION lib
# )
# add_dependencies(libcaf_bb_shared libcaf_bb)
# endif ()
#
# # build static library only if --build-static or --build-static-only was set
# if (CAF_BUILD_STATIC_ONLY OR CAF_BUILD_STATIC)
# add_library(libcaf_bb_static STATIC ${LIBCAF_BB_HDRS} ${LIBCAF_BB_SRCS})
# target_link_libraries(libcaf_bb_static ${CAF_EXTRA_LDFLAGS})
# target_include_directories(libcaf_bb_static PUBLIC
# $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
# $<INSTALL_INTERFACE:include>
# )
# set_target_properties(libcaf_bb_static PROPERTIES OUTPUT_NAME caf_bb_static)
# install(TARGETS libcaf_bb_static ARCHIVE DESTINATION lib)
# add_dependencies(libcaf_bb_static libcaf_bb)
# endif ()
# VERSION ${CAF_LIB_VERSION}
# OUTPUT_NAME caf_bb)
#
# -- install library and header files ------------------------------------------
#
# install(FILES "${CMAKE_BINARY_DIR}/caf/detail/bb_export.hpp"
# DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/caf/detail")
#
# install(TARGETS libcaf_bb
# EXPORT CAFTargets
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT bb
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bb
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT bb)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/caf"
DESTINATION include
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT bb
FILES_MATCHING PATTERN "*.hpp")
# -- build unit tests ----------------------------------------------------------
if(NOT CAF_NO_UNIT_TESTS)
message(STATUS "${CMAKE_CURRENT_SOURCE_DIR}")
add_executable(caf-bb-test
"${PROJECT_SOURCE_DIR}/cmake/incubator-test.cpp"
"${CAF_INCLUDE_DIR_TEST}/caf/test/unit_test.hpp"
"${CAF_INCLUDE_DIR_TEST}/caf/test/unit_test_impl.hpp"
${CAF_BB_TEST_SOURCES})
# --> Remove this when adding the first cpp
target_include_directories(caf-bb-test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
# $<TARGET_OBJECTS:libcaf_bb_obj>)
# target_compile_definitions(caf-bb-test PRIVATE libcaf_bb_EXPORTS)
target_link_libraries(caf-bb-test ${CAF_EXTRA_LDFLAGS} ${CAF_LIBRARIES})
add_test_suites(caf-bb-test
"${CMAKE_CURRENT_SOURCE_DIR}"
${CAF_BB_TEST_SOURCES})
endif()
# -- add this library to the global CAF_LIBRARIES ------------------------------
list(APPEND CAF_LIBRARIES libcaf_bb)
set(CAF_LIBRARIES ${CAF_LIBRARIES} PARENT_SCOPE)
# get header files; only needed by CMake generators,
# e.g., for creating proper Xcode projects
file(GLOB_RECURSE LIBCAF_NET_HDRS "caf/*.hpp")
# -- get header files for creating "proper" XCode projects ---------------------
file(GLOB_RECURSE CAF_NET_HEADERS "caf/*.hpp")
# -- auto generate to_string for enum types ------------------------------------
enum_to_string("caf/net/basp/connection_state.hpp" "basp_conn_strings.cpp")
enum_to_string("caf/net/basp/ec.hpp" "basp_ec_strings.cpp")
enum_to_string("caf/net/basp/message_type.hpp" "basp_message_type_strings.cpp")
enum_to_string("caf/net/operation.hpp" "operation_strings.cpp")
# list cpp files excluding platform-dependent files
set(LIBCAF_NET_SRCS
"${CMAKE_CURRENT_BINARY_DIR}/basp_conn_strings.cpp"
"${CMAKE_CURRENT_BINARY_DIR}/basp_ec_strings.cpp"
"${CMAKE_CURRENT_BINARY_DIR}/basp_message_type_strings.cpp"
"${CMAKE_CURRENT_BINARY_DIR}/operation_strings.cpp"
# -- list cpp files for caf::net -----------------------------------------------
set(CAF_NET_SOURCES
"${CMAKE_BINARY_DIR}/basp_conn_strings.cpp"
"${CMAKE_BINARY_DIR}/basp_ec_strings.cpp"
"${CMAKE_BINARY_DIR}/basp_message_type_strings.cpp"
"${CMAKE_BINARY_DIR}/operation_strings.cpp"
src/actor_proxy_impl.cpp
src/application.cpp
src/convert_ip_endpoint.cpp
......@@ -43,44 +46,98 @@ set(LIBCAF_NET_SRCS
src/worker.cpp
)
add_custom_target(libcaf_net)
# build shared library if not compiling static only
if (NOT CAF_BUILD_STATIC_ONLY)
add_library(libcaf_net_shared SHARED ${LIBCAF_NET_SRCS} ${LIBCAF_NET_HDRS})
target_link_libraries(libcaf_net_shared ${CAF_EXTRA_LDFLAGS} ${CAF_LIBRARY_CORE})
target_include_directories(libcaf_net_shared PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
set_target_properties(libcaf_net_shared
PROPERTIES
# -- list cpp files for caf-net-test ------------------------------------------
set(CAF_NET_TEST_SOURCES
test/net/basp/message_queue.cpp
test/net/basp/ping_pong.cpp
test/net/basp/worker.cpp
test/accept_socket.cpp
test/pipe_socket.cpp
test/application.cpp
test/socket.cpp
test/convert_ip_endpoint.cpp
test/socket_guard.cpp
test/datagram_socket.cpp
test/stream_application.cpp
test/datagram_transport.cpp
test/stream_socket.cpp
test/doorman.cpp
test/stream_transport.cpp
test/endpoint_manager.cpp
test/string_application.cpp
test/header.cpp
test/tcp_sockets.cpp
test/ip.cpp
test/transport_worker.cpp
test/multiplexer.cpp
test/transport_worker_dispatcher.cpp
test/udp_datagram_socket.cpp
test/network_socket.cpp
)
# -- add library target --------------------------------------------------------
add_library(libcaf_net_obj OBJECT ${CAF_NET_SOURCES} ${CAF_NET_HEADERS})
add_library(libcaf_net $<TARGET_OBJECTS:libcaf_net_obj>)
add_library(caf::net ALIAS libcaf_net)
if(BUILD_SHARED_LIBS AND NOT WIN32)
target_compile_options(libcaf_net PRIVATE -fPIC)
target_compile_options(libcaf_net_obj PRIVATE -fPIC)
endif()
target_link_libraries(libcaf_net PUBLIC ${CAF_EXTRA_LDFLAGS} ${CAF_LIBRARIES})
generate_export_header(libcaf_net
EXPORT_MACRO_NAME CAF_NET_EXPORT
EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/caf/detail/net_export.hpp"
STATIC_DEFINE CAF_STATIC_BUILD)
target_compile_definitions(libcaf_net_obj PRIVATE libcaf_net_EXPORTS)
set_target_properties(libcaf_net PROPERTIES
EXPORT_NAME net
SOVERSION ${CAF_VERSION}
VERSION ${CAF_LIB_VERSION}
OUTPUT_NAME caf_net
)
install(TARGETS libcaf_net_shared
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)
add_dependencies(libcaf_net_shared libcaf_net)
endif ()
# build static library only if --build-static or --build-static-only was set
if (CAF_BUILD_STATIC_ONLY OR CAF_BUILD_STATIC)
add_library(libcaf_net_static STATIC ${LIBCAF_NET_HDRS} ${LIBCAF_NET_SRCS})
target_link_libraries(libcaf_net_static ${CAF_EXTRA_LDFLAGS} ${CAF_LIBRARY_CORE_STATIC})
target_include_directories(libcaf_net_static PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
set_target_properties(libcaf_net_static PROPERTIES OUTPUT_NAME caf_net_static)
install(TARGETS libcaf_net_static ARCHIVE DESTINATION lib)
add_dependencies(libcaf_net_static libcaf_net)
endif ()
OUTPUT_NAME caf_net)
# -- install library and header files ------------------------------------------
install(FILES "${CMAKE_BINARY_DIR}/caf/detail/net_export.hpp"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/caf/detail")
install(TARGETS libcaf_net
EXPORT CAFTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT net
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT net
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT net)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/caf"
DESTINATION include
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT net
FILES_MATCHING PATTERN "*.hpp")
# -- build unit tests ----------------------------------------------------------
if(NOT CAF_NO_UNIT_TESTS)
add_executable(caf-net-test
"${PROJECT_SOURCE_DIR}/cmake/incubator-test.cpp"
"${CAF_INCLUDE_DIR_TEST}/caf/test/unit_test.hpp"
"${CAF_INCLUDE_DIR_TEST}/caf/test/unit_test_impl.hpp"
${CAF_NET_TEST_SOURCES}
$<TARGET_OBJECTS:libcaf_net_obj>)
target_compile_definitions(caf-net-test PRIVATE libcaf_net_EXPORTS)
target_link_libraries(caf-net-test ${CAF_EXTRA_LDFLAGS} ${CAF_LIBRARIES})
add_test_suites(caf-net-test
"${CMAKE_CURRENT_SOURCE_DIR}"
${CAF_NET_TEST_SOURCES})
endif()
# -- add this library to the global CAF_LIBRARIES ------------------------------
list(APPEND CAF_LIBRARIES libcaf_net)
set(CAF_LIBRARIES ${CAF_LIBRARIES} PARENT_SCOPE)
......@@ -20,6 +20,7 @@
#include <map>
#include "caf/detail/net_export.hpp"
#include "caf/net/endpoint_manager.hpp"
#include "caf/net/fwd.hpp"
#include "caf/net/middleman_backend.hpp"
......@@ -30,7 +31,7 @@ namespace caf::net::backend {
/// Minimal backend for unit testing.
/// @warning this backend is *not* thread safe.
class test : public middleman_backend {
class CAF_NET_EXPORT test : public middleman_backend {
public:
// -- member types -----------------------------------------------------------
......
......@@ -18,13 +18,14 @@
#pragma once
#include "caf/detail/net_export.hpp"
#include "caf/net/network_socket.hpp"
#include "caf/variant.hpp"
namespace caf::net {
/// A datagram-oriented network communication endpoint.
struct datagram_socket : network_socket {
struct CAF_NET_EXPORT datagram_socket : network_socket {
using super = network_socket;
using super::super;
......@@ -32,12 +33,12 @@ struct datagram_socket : network_socket {
/// Enables or disables `SIO_UDP_CONNRESET` error on `x`.
/// @relates datagram_socket
error allow_connreset(datagram_socket x, bool new_value);
error CAF_NET_EXPORT allow_connreset(datagram_socket x, bool new_value);
/// Converts the result from I/O operation on a ::datagram_socket to either an
/// error code or a integer greater or equal to zero.
/// @relates datagram_socket
variant<size_t, sec>
variant<size_t, sec> CAF_NET_EXPORT
check_datagram_socket_io_res(std::make_signed<size_t>::type res);
} // namespace caf::net
......@@ -25,6 +25,7 @@
#include "caf/actor.hpp"
#include "caf/actor_clock.hpp"
#include "caf/byte.hpp"
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include "caf/intrusive/drr_queue.hpp"
#include "caf/intrusive/fifo_inbox.hpp"
......@@ -37,7 +38,7 @@
namespace caf::net {
/// Manages a communication endpoint.
class endpoint_manager : public socket_manager {
class CAF_NET_EXPORT endpoint_manager : public socket_manager {
public:
// -- member types -----------------------------------------------------------
......
......@@ -18,11 +18,12 @@
#pragma once
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
namespace caf::net {
struct this_host {
struct CAF_NET_EXPORT this_host {
/// Initializes the network subsystem.
static error startup();
......
......@@ -21,24 +21,25 @@
#include <string>
#include <vector>
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
namespace caf::net::ip {
/// Returns all IP addresses of `host` (if any).
std::vector<ip_address> resolve(string_view host);
std::vector<ip_address> CAF_NET_EXPORT resolve(string_view host);
/// Returns all IP addresses of `host` (if any).
std::vector<ip_address> resolve(ip_address host);
std::vector<ip_address> CAF_NET_EXPORT resolve(ip_address host);
/// Returns the IP addresses for a local endpoint, which is either an address,
/// an interface name, or the string "localhost".
std::vector<ip_address> local_addresses(string_view host);
std::vector<ip_address> CAF_NET_EXPORT local_addresses(string_view host);
/// Returns the IP addresses for a local endpoint address.
std::vector<ip_address> local_addresses(ip_address host);
std::vector<ip_address> CAF_NET_EXPORT local_addresses(ip_address host);
/// Returns the hostname of this device.
std::string hostname();
std::string CAF_NET_EXPORT hostname();
} // namespace caf::net::ip
......@@ -18,6 +18,7 @@
#pragma once
#include "caf/detail/net_export.hpp"
#include "caf/make_counted.hpp"
#include "caf/net/endpoint_manager.hpp"
#include "caf/net/endpoint_manager_impl.hpp"
......@@ -25,8 +26,8 @@
namespace caf::net {
template <class Transport>
endpoint_manager_ptr make_endpoint_manager(const multiplexer_ptr& mpx,
actor_system& sys, Transport trans) {
endpoint_manager_ptr CAF_NET_EXPORT make_endpoint_manager(
const multiplexer_ptr& mpx, actor_system& sys, Transport trans) {
using impl = endpoint_manager_impl<Transport>;
return make_counted<impl>(mpx, sys, std::move(trans));
}
......
......@@ -21,13 +21,14 @@
#include <thread>
#include "caf/actor_system.hpp"
#include "caf/detail/net_export.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/fwd.hpp"
#include "caf/net/fwd.hpp"
namespace caf::net {
class middleman : public actor_system::module {
class CAF_NET_EXPORT middleman : public actor_system::module {
public:
// -- member types -----------------------------------------------------------
......
......@@ -24,6 +24,7 @@
#include <type_traits>
#include "caf/config.hpp"
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include "caf/net/socket.hpp"
#include "caf/net/socket_id.hpp"
......@@ -31,7 +32,7 @@
namespace caf::net {
/// A bidirectional network communication endpoint.
struct network_socket : socket {
struct CAF_NET_EXPORT network_socket : socket {
using super = socket;
using super::super;
......@@ -39,47 +40,47 @@ struct network_socket : socket {
/// Enables or disables `SIGPIPE` events from `x`.
/// @relates network_socket
error allow_sigpipe(network_socket x, bool new_value);
error CAF_NET_EXPORT allow_sigpipe(network_socket x, bool new_value);
/// Enables or disables `SIO_UDP_CONNRESET`error on `x`.
/// @relates network_socket
error allow_udp_connreset(network_socket x, bool new_value);
error CAF_NET_EXPORT allow_udp_connreset(network_socket x, bool new_value);
/// Get the socket buffer size for `x`.
/// @pre `x != invalid_socket`
/// @relates network_socket
expected<size_t> send_buffer_size(network_socket x);
expected<size_t> CAF_NET_EXPORT send_buffer_size(network_socket x);
/// Set the socket buffer size for `x`.
/// @relates network_socket
error send_buffer_size(network_socket x, size_t capacity);
error CAF_NET_EXPORT send_buffer_size(network_socket x, size_t capacity);
/// Returns the locally assigned port of `x`.
/// @relates network_socket
expected<uint16_t> local_port(network_socket x);
expected<uint16_t> CAF_NET_EXPORT local_port(network_socket x);
/// Returns the locally assigned address of `x`.
/// @relates network_socket
expected<std::string> local_addr(network_socket x);
expected<std::string> CAF_NET_EXPORT local_addr(network_socket x);
/// Returns the port used by the remote host of `x`.
/// @relates network_socket
expected<uint16_t> remote_port(network_socket x);
expected<uint16_t> CAF_NET_EXPORT remote_port(network_socket x);
/// Returns the remote host address of `x`.
/// @relates network_socket
expected<std::string> remote_addr(network_socket x);
expected<std::string> CAF_NET_EXPORT remote_addr(network_socket x);
/// Closes the read channel for a socket.
/// @relates network_socket
void shutdown_read(network_socket x);
void CAF_NET_EXPORT shutdown_read(network_socket x);
/// Closes the write channel for a socket.
/// @relates network_socket
void shutdown_write(network_socket x);
void CAF_NET_EXPORT shutdown_write(network_socket x);
/// Closes the both read and write channel for a socket.
/// @relates network_socket
void shutdown(network_socket x);
void CAF_NET_EXPORT shutdown(network_socket x);
} // namespace caf::net
......@@ -21,13 +21,14 @@
#include <vector>
#include "caf/byte.hpp"
#include "caf/detail/net_export.hpp"
#include "caf/net/fwd.hpp"
#include "caf/span.hpp"
namespace caf::net {
/// Implements an interface for packet writing in application-layers.
class packet_writer {
class CAF_NET_EXPORT packet_writer {
public:
using buffer_type = std::vector<byte>;
......
......@@ -22,6 +22,7 @@
#include <system_error>
#include <utility>
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include "caf/net/socket.hpp"
#include "caf/net/socket_id.hpp"
......@@ -29,7 +30,7 @@
namespace caf::net {
/// A unidirectional communication endpoint for inter-process communication.
struct pipe_socket : socket {
struct CAF_NET_EXPORT pipe_socket : socket {
using super = socket;
using super::super;
......@@ -38,7 +39,7 @@ struct pipe_socket : socket {
/// Creates two connected sockets. The first socket is the read handle and the
/// second socket is the write handle.
/// @relates pipe_socket
expected<std::pair<pipe_socket, pipe_socket>> make_pipe();
expected<std::pair<pipe_socket, pipe_socket>> CAF_NET_EXPORT make_pipe();
/// Transmits data from `x` to its peer.
/// @param x Connected endpoint.
......@@ -46,7 +47,7 @@ expected<std::pair<pipe_socket, pipe_socket>> make_pipe();
/// @param buf_size Specifies the size of the buffer in bytes.
/// @returns The number of written bytes on success, otherwise an error code.
/// @relates pipe_socket
variant<size_t, sec> write(pipe_socket x, span<const byte> buf);
variant<size_t, sec> CAF_NET_EXPORT write(pipe_socket x, span<const byte> buf);
/// Receives data from `x`.
/// @param x Connected endpoint.
......@@ -54,12 +55,12 @@ variant<size_t, sec> write(pipe_socket x, span<const byte> buf);
/// @param buf_size Specifies the maximum size of the buffer in bytes.
/// @returns The number of received bytes on success, otherwise an error code.
/// @relates pipe_socket
variant<size_t, sec> read(pipe_socket x, span<byte>);
variant<size_t, sec> CAF_NET_EXPORT read(pipe_socket x, span<byte>);
/// Converts the result from I/O operation on a ::pipe_socket to either an
/// error code or a non-zero positive integer.
/// @relates pipe_socket
variant<size_t, sec>
check_pipe_socket_io_res(std::make_signed<size_t>::type res);
CAF_NET_EXPORT check_pipe_socket_io_res(std::make_signed<size_t>::type res);
} // namespace caf::net
......@@ -26,7 +26,11 @@
namespace caf::net {
enum class receive_policy_flag : unsigned { at_least, at_most, exactly };
enum class CAF_NET_EXPORT receive_policy_flag : unsigned {
at_least,
at_most,
exactly
};
inline std::string to_string(receive_policy_flag x) {
return x == receive_policy_flag::at_least
......@@ -34,7 +38,7 @@ inline std::string to_string(receive_policy_flag x) {
: (x == receive_policy_flag::at_most ? "at_most" : "exactly");
}
class receive_policy {
class CAF_NET_EXPORT receive_policy {
public:
receive_policy() = delete;
......
......@@ -24,6 +24,7 @@
#include "caf/config.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include "caf/net/socket_id.hpp"
......@@ -31,7 +32,7 @@ namespace caf::net {
/// An internal endpoint for sending or receiving data. Can be either a
/// ::network_socket, ::pipe_socket, ::stream_socket, or ::datagram_socket.
struct socket : detail::comparable<socket> {
struct CAF_NET_EXPORT socket : detail::comparable<socket> {
socket_id id;
constexpr socket() noexcept : id(invalid_socket_id) {
......@@ -54,7 +55,8 @@ struct socket : detail::comparable<socket> {
/// @relates socket
template <class Inspector>
typename Inspector::result_type inspect(Inspector& f, socket& x) {
typename Inspector::result_type CAF_NET_EXPORT inspect(Inspector& f,
socket& x) {
return f(x.id);
}
......@@ -63,29 +65,29 @@ constexpr auto invalid_socket = socket{invalid_socket_id};
/// Converts between different socket types.
template <class To, class From>
To socket_cast(From x) {
To CAF_NET_EXPORT socket_cast(From x) {
return To{x.id};
}
/// Close socket `x`.
/// @relates socket
void close(socket x);
void CAF_NET_EXPORT close(socket x);
/// Returns the last socket error in this thread as an integer.
/// @relates socket
std::errc last_socket_error();
std::errc CAF_NET_EXPORT last_socket_error();
/// Returns the last socket error as human-readable string.
/// @relates socket
std::string last_socket_error_as_string();
std::string CAF_NET_EXPORT last_socket_error_as_string();
/// Sets x to be inherited by child processes if `new_value == true`
/// or not if `new_value == false`. Not implemented on Windows.
/// @relates socket
error child_process_inherit(socket x, bool new_value);
error CAF_NET_EXPORT child_process_inherit(socket x, bool new_value);
/// Enables or disables nonblocking I/O on `x`.
/// @relates socket
error nonblocking(socket x, bool new_value);
error CAF_NET_EXPORT nonblocking(socket x, bool new_value);
} // namespace caf::net
......@@ -18,6 +18,7 @@
#pragma once
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include "caf/net/network_socket.hpp"
......@@ -25,7 +26,7 @@ namespace caf::net {
/// A connection-oriented network communication endpoint for bidirectional byte
/// streams.
struct stream_socket : network_socket {
struct CAF_NET_EXPORT stream_socket : network_socket {
using super = network_socket;
using super::super;
......@@ -34,15 +35,16 @@ struct stream_socket : network_socket {
/// Creates two connected sockets to mimic network communication (usually for
/// testing purposes).
/// @relates stream_socket
expected<std::pair<stream_socket, stream_socket>> make_stream_socket_pair();
expected<std::pair<stream_socket, stream_socket>>
CAF_NET_EXPORT make_stream_socket_pair();
/// Enables or disables keepalive on `x`.
/// @relates network_socket
error keepalive(stream_socket x, bool new_value);
error CAF_NET_EXPORT keepalive(stream_socket x, bool new_value);
/// Enables or disables Nagle's algorithm on `x`.
/// @relates stream_socket
error nodelay(stream_socket x, bool new_value);
error CAF_NET_EXPORT nodelay(stream_socket x, bool new_value);
/// Receives data from `x`.
/// @param x Connected endpoint.
......@@ -50,7 +52,7 @@ error nodelay(stream_socket x, bool new_value);
/// @returns The number of received bytes on success, an error code otherwise.
/// @relates stream_socket
/// @post either the result is a `sec` or a positive (non-zero) integer
variant<size_t, sec> read(stream_socket x, span<byte> buf);
variant<size_t, sec> CAF_NET_EXPORT read(stream_socket x, span<byte> buf);
/// Transmits data from `x` to its peer.
/// @param x Connected endpoint.
......@@ -58,7 +60,8 @@ variant<size_t, sec> read(stream_socket x, span<byte> buf);
/// @returns The number of written bytes on success, otherwise an error code.
/// @relates stream_socket
/// @post either the result is a `sec` or a positive (non-zero) integer
variant<size_t, sec> write(stream_socket x, span<const byte> buf);
variant<size_t, sec> CAF_NET_EXPORT write(stream_socket x,
span<const byte> buf);
/// Transmits data from `x` to its peer.
/// @param x Connected endpoint.
......@@ -68,13 +71,13 @@ variant<size_t, sec> write(stream_socket x, span<const byte> buf);
/// @relates stream_socket
/// @post either the result is a `sec` or a positive (non-zero) integer
/// @pre `bufs.size() < 10`
variant<size_t, sec> write(stream_socket x,
std::initializer_list<span<const byte>> bufs);
variant<size_t, sec> CAF_NET_EXPORT
write(stream_socket x, std::initializer_list<span<const byte>> bufs);
/// Converts the result from I/O operation on a ::stream_socket to either an
/// error code or a non-zero positive integer.
/// @relates stream_socket
variant<size_t, sec>
check_stream_socket_io_res(std::make_signed<size_t>::type res);
CAF_NET_EXPORT check_stream_socket_io_res(std::make_signed<size_t>::type res);
} // namespace caf::net
......@@ -18,6 +18,7 @@
#pragma once
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include "caf/net/fwd.hpp"
#include "caf/net/network_socket.hpp"
......@@ -26,7 +27,7 @@
namespace caf::net {
/// Represents a TCP acceptor in listening mode.
struct tcp_accept_socket : network_socket {
struct CAF_NET_EXPORT tcp_accept_socket : network_socket {
using super = network_socket;
using super::super;
......@@ -37,8 +38,8 @@ struct tcp_accept_socket : network_socket {
/// Passing the address `0.0.0.0` will accept incoming connection from any host.
/// Passing port 0 lets the OS choose the port.
/// @relates tcp_accept_socket
expected<tcp_accept_socket> make_tcp_accept_socket(ip_endpoint node,
bool reuse_addr = false);
expected<tcp_accept_socket> CAF_NET_EXPORT
make_tcp_accept_socket(ip_endpoint node, bool reuse_addr = false);
/// Creates a new TCP socket to accept connections on a given port.
/// @param node The endpoint to listen on and the filter for incoming addresses.
......@@ -47,7 +48,7 @@ expected<tcp_accept_socket> make_tcp_accept_socket(ip_endpoint node,
/// @param reuse_addr Optionally sets the SO_REUSEADDR option on the socket.
/// @relates tcp_accept_socket
expected<tcp_accept_socket>
make_tcp_accept_socket(const uri::authority_type& node,
CAF_NET_EXPORT make_tcp_accept_socket(const uri::authority_type& node,
bool reuse_addr = false);
/// Accepts a connection on `x`.
......@@ -55,6 +56,6 @@ make_tcp_accept_socket(const uri::authority_type& node,
/// @returns The socket that handles the accepted connection on success, an
/// error otherwise.
/// @relates tcp_accept_socket
expected<tcp_stream_socket> accept(tcp_accept_socket x);
expected<tcp_stream_socket> CAF_NET_EXPORT accept(tcp_accept_socket x);
} // namespace caf::net
......@@ -18,6 +18,7 @@
#pragma once
#include "caf/detail/net_export.hpp"
#include "caf/ip_endpoint.hpp"
#include "caf/net/socket.hpp"
#include "caf/net/stream_socket.hpp"
......@@ -26,7 +27,7 @@
namespace caf::net {
/// Represents a TCP connection.
struct tcp_stream_socket : stream_socket {
struct CAF_NET_EXPORT tcp_stream_socket : stream_socket {
using super = stream_socket;
using super::super;
......@@ -36,13 +37,14 @@ struct tcp_stream_socket : stream_socket {
/// @param node Host and port of the remote node.
/// @returns The connected socket or an error.
/// @relates tcp_stream_socket
expected<tcp_stream_socket> make_connected_tcp_stream_socket(ip_endpoint node);
expected<tcp_stream_socket>
CAF_NET_EXPORT make_connected_tcp_stream_socket(ip_endpoint node);
/// Create a `tcp_stream_socket` connected to `auth`.
/// @param node Host and port of the remote node.
/// @returns The connected socket or an error.
/// @relates tcp_stream_socket
expected<tcp_stream_socket>
expected<tcp_stream_socket> CAF_NET_EXPORT
make_connected_tcp_stream_socket(const uri::authority_type& node);
} // namespace caf::net
......@@ -20,12 +20,13 @@
#include <stdexcept>
#include "caf/detail/net_export.hpp"
#include "caf/error.hpp"
#include "caf/net/host.hpp"
namespace {
struct host_fixture {
struct CAF_NET_EXPORT host_fixture {
host_fixture() {
if (auto err = caf::net::this_host::startup())
throw std::logic_error("this_host::startup failed");
......
......@@ -18,6 +18,7 @@
#pragma once
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include "caf/net/network_socket.hpp"
......@@ -25,7 +26,7 @@ namespace caf::net {
/// A datagram-oriented network communication endpoint for bidirectional
/// byte transmission.
struct udp_datagram_socket : network_socket {
struct CAF_NET_EXPORT udp_datagram_socket : network_socket {
using super = network_socket;
using super::super;
......@@ -37,12 +38,12 @@ struct udp_datagram_socket : network_socket {
/// port that was bound.
/// @returns The connected socket or an error.
/// @relates udp_datagram_socket
expected<std::pair<udp_datagram_socket, uint16_t>>
expected<std::pair<udp_datagram_socket, uint16_t>> CAF_NET_EXPORT
make_udp_datagram_socket(ip_endpoint ep, bool reuse_addr = false);
/// Enables or disables `SIO_UDP_CONNRESET` error on `x`.
/// @relates udp_datagram_socket
error allow_connreset(udp_datagram_socket x, bool new_value);
error CAF_NET_EXPORT allow_connreset(udp_datagram_socket x, bool new_value);
/// Receives the next datagram on socket `x`.
/// @param x The UDP socket for receiving datagrams.
......@@ -52,8 +53,8 @@ error allow_connreset(udp_datagram_socket x, bool new_value);
/// @relates udp_datagram_socket
/// @post buf was modified and the resulting integer represents the length of
/// the received datagram, even if it did not fit into the given buffer.
variant<std::pair<size_t, ip_endpoint>, sec> read(udp_datagram_socket x,
span<byte> buf);
variant<std::pair<size_t, ip_endpoint>, sec>
CAF_NET_EXPORT read(udp_datagram_socket x, span<byte> buf);
/// Sends the content of `bufs` as a datagram to the endpoint `ep` on socket
/// `x`.
......@@ -64,7 +65,8 @@ variant<std::pair<size_t, ip_endpoint>, sec> read(udp_datagram_socket x,
/// @returns The number of written bytes on success, otherwise an error code.
/// @relates udp_datagram_socket
/// @pre `bufs.size() < 10`
variant<size_t, sec> write(udp_datagram_socket x, span<std::vector<byte>*> bufs,
variant<size_t, sec> CAF_NET_EXPORT write(udp_datagram_socket x,
span<std::vector<byte>*> bufs,
ip_endpoint ep);
/// Sends the content of `buf` as a datagram to the endpoint `ep` on socket `x`.
......@@ -73,13 +75,13 @@ variant<size_t, sec> write(udp_datagram_socket x, span<std::vector<byte>*> bufs,
/// @param ep The enpoint to send the datagram to.
/// @returns The number of written bytes on success, otherwise an error code.
/// @relates udp_datagram_socket
variant<size_t, sec> write(udp_datagram_socket x, span<const byte> buf,
ip_endpoint ep);
variant<size_t, sec> CAF_NET_EXPORT write(udp_datagram_socket x,
span<const byte> buf, ip_endpoint ep);
/// Converts the result from I/O operation on a ::udp_datagram_socket to either
/// an error code or a non-zero positive integer.
/// @relates udp_datagram_socket
variant<size_t, sec>
variant<size_t, sec> CAF_NET_EXPORT
check_udp_datagram_socket_io_res(std::make_signed<size_t>::type res);
} // namespace caf::net
......@@ -18,6 +18,8 @@
#include "caf/detail/convert_ip_endpoint.hpp"
#include <cstring>
#include "caf/error.hpp"
#include "caf/ipv4_endpoint.hpp"
#include "caf/ipv6_endpoint.hpp"
......
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