diff --git a/.travis.yml b/.travis.yml index 0c83802f..45e75ae8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,53 +1,46 @@ -dist: trusty -language: cpp -compiler: - #- clang - - g++ +language: c++ -branches: - only: - - master - - dev - - osx_support +os: + - linux env: - global: - - CI_HOME=`pwd` + matrix: + - RPCLIB_CXX_STANDARD=14 BUILD_TYPE=Release + - RPCLIB_CXX_STANDARD=11 BUILD_TYPE=Release + +compiler: + - gcc + - clang addons: apt: sources: + - llvm-toolchain-precise-3.8 - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.7 - george-edison55-precise-backports packages: - - gcc-5 + - libsfml-dev - g++-5 + - gcc-5 + - clang-3.8 - cmake - cmake-data install: + - if [ "$CXX" == "g++" ]; then export CXX="g++-5" CC="gcc-5"; fi + - if [ "$CXX" == "clang++" ]; then export CXX="clang++-3.8" CC="clang-3.8"; fi - pip install --user cpp-coveralls - - if [ "$CXX" = "g++" ]; then export CXX="g++-5" CC="gcc-5"; fi + - pip install --user conan + - conan remote add conan-community https://api.bintray.com/conan/conan-community/conan script: - - g++-5 --version - - gcc-5 --version - - cd $CI_HOME - - git submodule init - - git submodule update --init --recursive - - mkdir build14 && cd build14 - - cmake -DRPCLIB_ENABLE_COVERAGE=ON -DRPCLIB_BUILD_TESTS=ON -DRPCLIB_CXX_STANDARD=14 .. - - make -j2 - - cd .. - - mkdir build11 && cd build11 - - cmake -DRPCLIB_ENABLE_COVERAGE=ON -DRPCLIB_BUILD_TESTS=ON -DRPCLIB_CXX_STANDARD=11 .. - - make -j2 - - cd .. + - mkdir build ; cd build + - conan install .. -r conan-community + - . ./activate.sh + - cmake -DRPCLIB_ENABLE_COVERAGE=$COV -DRPCLIB_BUILD_TESTS=ON -DRPCLIB_CXX_STANDARD=$RPCLIB_CXX_STANDARD -DCMAKE_INSTALL_PREFIX=../install .. + - cmake --build . --config $BUILD_TYPE + - cmake --build . --target install after_success: - - ./build14/output/bin/rpc_test - - ./build11/output/bin/rpc_test + - ./output/bin/rpc_test - coveralls --exclude dependencies --exclude test --exclude include/rpc/msgpack --exclude include/rcp/msgpack.hpp --gcov /usr/bin/gcov-5 - - diff --git a/CMakeLists.txt b/CMakeLists.txt index 39bb2ee1..7f120e4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,403 +1,251 @@ -cmake_minimum_required(VERSION 3.0.0) -project(rpc) +cmake_minimum_required(VERSION 3.9.0) +project(rpc VERSION 3.0.0) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") -################################################################################ +include(policies) +include(msvc_support) + # # Options # -################################################################################ - -option(RPCLIB_BUILD_TESTS "Build unit RPCLIB_BUILD_TESTS." OFF) -option(RPCLIB_GENERATE_COMPDB "Generate compilation database. Useful for YCM." OFF) -option(RPCLIB_BUILD_EXAMPLES "Build examples." OFF) -option(RPCLIB_ENABLE_LOGGING "ALlow logging in the library for debug purposes. Also usable in a release build." OFF) -option(RPCLIB_ENABLE_COVERAGE "Generate coverage information" OFF) -option(RPCLIB_FORCE_M64 "Force -m64 in CXXFLAGS" OFF) -option(RPCLIB_FORCE_M32 "Force -m32 in CXXFLAGS" OFF) -option(RPCLIB_MSVC_STATIC_RUNTIME "MSVC only: build with /MT instead of /MD" OFF) - -################################################################################ +option(RPCLIB_BUILD_TESTS + "Build unit RPCLIB_BUILD_TESTS." + OFF) +option(RPCLIB_GENERATE_COMPDB + "Generate compilation database. Useful for YCM." + OFF) +option(RPCLIB_BUILD_EXAMPLES + "Build examples." + OFF) +option(RPCLIB_ENABLE_LOGGING + "ALlow logging in the library for debug purposes." + OFF) +option(RPCLIB_ENABLE_COVERAGE + "Generate coverage information" + OFF) +option(RPCLIB_MSVC_STATIC_RUNTIME + "MSVC only: build with /MT instead of /MD" + OFF) + +# Perform steps and checks required for MSVC support +rpclib_msvc_support() + # # Other configuration values # -################################################################################ +set(RPCLIB_DEFAULT_PORT 8080 + CACHE STRING "Default port used for running tests and examples") +set(RPCLIB_DEFAULT_BUFFER_SIZE "1024 << 10" + CACHE STRING "Default buffer size") +set(RPCLIB_CXX_STANDARD 11 CACHE STRING + "C++ version used to build rpclib (Currently: Only 11 and 14 supported)") -set(RPCLIB_DEFAULT_PORT 8080 CACHE STRING "Default port used for running tests and examples") -set(RPCLIB_DEFAULT_BUFFER_SIZE "1024 << 10" CACHE STRING "Default buffer size") -set(RPCLIB_CXX_STANDARD 11 CACHE STRING "C++ version used to build rpclib (Currently: Only 11 and 14 supported)") +if(RPCLIB_GENERATE_COMPDB) + set(CMAKE_EXPORT_COMPILE_COMMANDS "ON") # for YCM + add_custom_command(PROJECT_NAME ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E + copy ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_BINARY_DIR}/../compile_commands.json) +endif() -if(NOT ${RPCLIB_CXX_STANDARD} EQUAL 14 AND NOT ${RPCLIB_CXX_STANDARD} EQUAL 11) - message(fatal_error "Unsupported C++ standard: ${RPCLIB_CXX_STANDARD}") +if(NOT ${RPCLIB_CXX_STANDARD} EQUAL 14 AND + NOT ${RPCLIB_CXX_STANDARD} EQUAL 11) + message(fatal_error "Unsupported C++ standard: ${RPCLIB_CXX_STANDARD}") endif() -################################################################################ # # Compile & install the library # -################################################################################ - -include(TargetArch) - -set(RPCLIB_VERSION_MAJOR 2) -set(RPCLIB_VERSION_MINOR 1) -set(RPCLIB_VERSION_PATCH 0) - -target_architecture(TARGET_ARCH) - -if(RPCLIB_FORCE_M32) - message(STATUS "Compiling for 32-bit") - set(RPCLIB_ARCH_DEF "RPCLIB_ARCH_X86") - set(RPCLIB_TARGET_ARCH "x86") - set(RPCLIB_DEB_ARCH "i386") -elseif(RPCLIB_FORCE_M64) - message(STATUS "Compiling for 64-bit") - set(RPCLIB_ARCH_DEF "RPCLIB_ARCH_X64") - set(RPCLIB_TARGET_ARCH "x64") - set(RPCLIB_DEB_ARCH "amd64") -elseif (${TARGET_ARCH} STREQUAL "i386") - message(STATUS "Compiling for 32-bit") - set(RPCLIB_ARCH_DEF "RPCLIB_ARCH_X86") - set(RPCLIB_TARGET_ARCH "x86") - set(RPCLIB_DEB_ARCH "i386") -elseif(${TARGET_ARCH} STREQUAL "x86_64") - message(STATUS "Compiling for 64-bit") - set(RPCLIB_ARCH_DEF "RPCLIB_ARCH_X64") - set(RPCLIB_TARGET_ARCH "x64") - set(RPCLIB_DEB_ARCH "amd64") -endif() - if (WIN32) - set(RPCLIB_OS_DEF "RPCLIB_WIN32") + set(RPCLIB_OS_DEF "RPCLIB_WIN32") elseif (LINUX) - set(RPCLIB_OS_DEF "RPCLIB_LINUX") + set(RPCLIB_OS_DEF "RPCLIB_LINUX") elseif (APPLE) - set(RPCLIB_OS_DEF "RPCLIB_MAC") + set(RPCLIB_OS_DEF "RPCLIB_MAC") endif() -# This function sets the rpclib-specific flags that are used for -# development. You do not need this in your project. Instead, -# Findrpclib.cmake supplies a (possibly empty) RPCLIB_EXTRA_FLAGS variable -# that you should append to your build flags. -function(set_rpclib_flags TARGET) - # clang is the compiler used for developing mainly, so - # this is where I set the highest warning level - # but feel free to add similar flags to GCC - if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") - - set(RPCLIB_BUILD_FLAGS - "-Wall -pedantic -Weverything -Wno-c++98-compat\ - -Wno-c++98-compat-pedantic -Wno-padded -Wno-missing-prototypes\ - -Wno-undef -pthread") - if(RPCLIB_CXX_STANDARD EQUAL 14) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} -std=c++14") - elseif(RPCLIB_CXX_STANDARD EQUAL 11) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} -std=c++11") - endif() - - if(RPCLIB_ENABLE_COVERAGE) - set_target_properties(${TARGET} - PROPERTIES - LINK_FLAGS "-lgcov --coverage") - endif() - - if(RPCLIB_FORCE_M32) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} -m32") - elseif(RPCLIB_FORCE_M64) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} -m64") - endif() - - set(RPCLIB_DEP_LIBRARIES "pthread") - - elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") - - set(RPCLIB_BUILD_FLAGS "-Wall -pedantic -pthread") - if(RPCLIB_CXX_STANDARD EQUAL 14) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} -std=c++14") - elseif(RPCLIB_CXX_STANDARD EQUAL 11) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} -std=c++11") - endif() - - if(RPCLIB_ENABLE_COVERAGE) - set_target_properties(${TARGET} - PROPERTIES - LINK_FLAGS "-lgcov --coverage") - endif() - - if(RPCLIB_FORCE_M32) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} -m32") - elseif(RPCLIB_FORCE_M64) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} -m64") - endif() - - set(RPCLIB_DEP_LIBRARIES "pthread") - - elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") - - set(RPCLIB_COMPILE_DEFINITIONS - "${RPCLIB_COMPILE_DEFINITIONS}" - "WIN32_LEAN_AND_MEAN" - "NOMINMAX" - "VC_EXTRALEAN" - "_CRT_SECURE_NO_WARNINGS" - "_CRT_NONSTDC_NO_DEPRECATE" - "_WIN32_WINNT=0x0501" - "_GNU_SOURCE" - "ASIO_HAS_STD_ADDRESSOF" - "ASIO_HAS_STD_ARRAY" - "ASIO_HAS_CSTDINT" - "ASIO_HAS_STD_SHARED_PTR" - "ASIO_HAS_STD_TYPE_TRAITS") - - endif() - - if (RPCLIB_EXTRA_BUILD_FLAGS) - set(RPCLIB_BUILD_FLAGS "${RPCLIB_BUILD_FLAGS} ${RPCLIB_EXTRA_BUILD_FLAGS}") - endif() - - set(RPCLIB_COMPILE_DEFINITIONS - "${RPCLIB_COMPILE_DEFINITIONS}" - "${RPCLIB_ARCH_DEF}" - "${RPCLIB_OS_DEF}" - "ASIO_STANDALONE" - "RPCLIB_ASIO=clmdep_asio" - "RPCLIB_FMT=clmdep_fmt" - "RPCLIB_MSGPACK=clmdep_msgpack" - ) - - if(RPCLIB_ENABLE_LOGGING) - set(RPCLIB_COMPILE_DEFINITIONS - "${RPCLIB_COMPILE_DEFINITIONS};RPCLIB_ENABLE_LOGGING") - endif() - - if(RPCLIB_BUILD_FLAGS) - set_target_properties(${TARGET} - PROPERTIES - COMPILE_FLAGS "${RPCLIB_BUILD_FLAGS}") - endif() - - if(RPCLIB_COMPILE_DEFINITIONS) - set_target_properties(${TARGET} - PROPERTIES - COMPILE_DEFINITIONS "${RPCLIB_COMPILE_DEFINITIONS}") - endif() - - target_link_libraries(${TARGET} ${RPCLIB_DEP_LIBRARIES}) - target_include_directories( - ${TARGET} - PUBLIC include - PRIVATE include/rpc - ) - target_include_directories( - ${TARGET} SYSTEM - PRIVATE dependencies/include - ) - -endfunction() - -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/bin) +set(RPCLIB_DEPENDENCIES "${CMAKE_CURRENT_LIST_DIR}/dependencies") configure_file( - "${PROJECT_SOURCE_DIR}/include/rpc/version.h.in" - "${PROJECT_SOURCE_DIR}/include/rpc/version.h") + "${PROJECT_SOURCE_DIR}/include/rpc/version.h.in" + "${PROJECT_SOURCE_DIR}/include/rpc/version.h") configure_file( - "${PROJECT_SOURCE_DIR}/include/rpc/config.h.in" - "${PROJECT_SOURCE_DIR}/include/rpc/config.h") + "${PROJECT_SOURCE_DIR}/include/rpc/config.h.in" + "${PROJECT_SOURCE_DIR}/include/rpc/config.h") configure_file( - "${PROJECT_SOURCE_DIR}/doc/pages/versions.md.in" - "${PROJECT_SOURCE_DIR}/doc/pages/versions.md") + "${PROJECT_SOURCE_DIR}/doc/pages/versions.md.in" + "${PROJECT_SOURCE_DIR}/doc/pages/versions.md") file(GLOB_RECURSE RPCLIB_HEADERS - include/rpc/*.h - include/msgpack/*.hpp) + include/rpc/*.h + include/msgpack/*.hpp) file(GLOB_RECURSE DEP_HEADERS - dependencies/include/*.h - dependencies/include/*.hpp) + ${RPCLIB_DEPENDENCIES}/include/*.h + ${RPCLIB_DEP_LIBRARIDEPENDENCIES}/include/*.hpp) -if(RPCLIB_NAME_SUFFIX) - set(OUTPUT_LIBRARY_NAME ${CMAKE_PROJECT_NAME}-${RPCLIB_NAME_SUFFIX}) -else() - set(OUTPUT_LIBRARY_NAME ${CMAKE_PROJECT_NAME}) +set(DEP_SOURCES + ${RPCLIB_DEPENDENCIES}/src/format.cc + ${RPCLIB_DEPENDENCIES}/src/posix.cc) + +add_library(${PROJECT_NAME} + lib/rpc/dispatcher.cc + lib/rpc/server.cc + lib/rpc/client.cc + lib/rpc/this_handler.cc + lib/rpc/this_session.cc + lib/rpc/this_server.cc + lib/rpc/rpc_error.cc + lib/rpc/detail/server_session.cc + lib/rpc/detail/response.cc + lib/rpc/detail/client_error.cc + lib/rpc/nonstd/optional.cc + ${DEP_SOURCES} + ${DEP_HEADERS} + ${RPCLIB_HEADERS}) + +set(RPCLIB_BUILD_FLAGS "") # reset flags + +if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + target_compile_options(${PROJECT_NAME} PUBLIC + -std=c++${RPCLIB_CXX_STANDARD}) endif() -set(DEP_SOURCES - dependencies/src/format.cc - dependencies/src/posix.cc) - -add_library(${OUTPUT_LIBRARY_NAME} - lib/rpc/dispatcher.cc - lib/rpc/server.cc - lib/rpc/client.cc - lib/rpc/this_handler.cc - lib/rpc/this_session.cc - lib/rpc/this_server.cc - lib/rpc/rpc_error.cc - lib/rpc/detail/server_session.cc - lib/rpc/detail/response.cc - lib/rpc/detail/client_error.cc - lib/rpc/nonstd/optional.cc - ${DEP_SOURCES} - ${DEP_HEADERS} - ${RPCLIB_HEADERS}) - - -set_rpclib_flags(${OUTPUT_LIBRARY_NAME}) - -target_link_libraries(${OUTPUT_LIBRARY_NAME}) - -# When building via conan, respect the compilation settings. -if ("${CONAN_LINK_RUNTIME}" STREQUAL "/MT") - set(RPCLIB_MSVC_STATIC_RUNTIME ON) +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + # clang is the compiler used for developing mainly, so + # this is where I set the highest warning level + list(APPEND RPCLIB_BUILD_FLAGS + -Wall -pedantic -Weverything -Wno-c++98-compat + -Wno-c++98-compat-pedantic -Wno-padded -Wno-missing-prototypes + -Wno-undef -pthread) endif() -# MSVC static runtime support -# -# While this pollutes global flags (when using add_library), you would not want to -# build with a disparity anyway. (also, CMake still has no support for this, so you -# would end up doing something like this yourself). -if (RPCLIB_MSVC_STATIC_RUNTIME) - # Set compiler options. - set(variables - CMAKE_C_FLAGS_DEBUG - CMAKE_C_FLAGS_MINSIZEREL - CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_RELWITHDEBINFO - CMAKE_CXX_FLAGS_DEBUG - CMAKE_CXX_FLAGS_MINSIZEREL - CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_RELWITHDEBINFO - ) - - message(STATUS - "MSVC -> forcing use of statically-linked runtime." - ) - - foreach(variable ${variables}) - if(${variable} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}") - endif() - endforeach() +if(RPCLIB_ENABLE_COVERAGE) + target_compile_options(${PROJECT_NAME} PUBLIC "--coverage") + # yes, this is ugly as "--coverage" is not a library, but a flag. + # however, this does not work with the LINK_FLAGS target property + list(APPEND RPCLIB_DEP_LIBRARIES "--coverage") +endif() +if (RPCLIB_EXTRA_BUILD_FLAGS) + list(APPEND RPCLIB_BUILD_FLAGS ${RPCLIB_EXTRA_BUILD_FLAGS}) endif() -install(TARGETS ${OUTPUT_LIBRARY_NAME} DESTINATION lib) -install(DIRECTORY include/ - DESTINATION include - FILES_MATCHING - PATTERN "*.h" - PATTERN "*.hpp" - PATTERN "*.inl" - PATTERN "*.in" EXCLUDE) -install(FILES ${PROJECT_SOURCE_DIR}/include/rpc/version.h DESTINATION include/rpc) +target_compile_definitions(${PROJECT_NAME} PRIVATE + "${RPCLIB_COMPILE_DEFINITIONS}" + "${RPCLIB_ARCH_DEF}" + "${RPCLIB_OS_DEF}" + "ASIO_STANDALONE" + "RPCLIB_ASIO=clmdep_asio" + "RPCLIB_FMT=clmdep_fmt") -if(RPCLIB_GENERATE_COMPDB) - set(CMAKE_EXPORT_COMPILE_COMMANDS "ON") # for YCM - add_custom_command(TARGET ${OUTPUT_LIBRARY_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E - copy ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_BINARY_DIR}/../compile_commands.json) +target_compile_definitions(${PROJECT_NAME} PUBLIC + "RPCLIB_MSGPACK=clmdep_msgpack") + +if(RPCLIB_ENABLE_LOGGING) + target_compile_definitions(${PROJECT_NAME} PRIVATE "RPCLIB_ENABLE_LOGGING") endif() -################################################################################ +if(RPCLIB_BUILD_FLAGS) + target_compile_options(${PROJECT_NAME} PRIVATE ${RPCLIB_BUILD_FLAGS}) +endif() + +if(RPCLIB_COMPILE_DEFINITIONS) + set_target_properties(${PROJECT_NAME} + PROPERTIES + COMPILE_DEFINITIONS "${RPCLIB_COMPILE_DEFINITIONS}") +endif() + +target_link_libraries(${PROJECT_NAME} ${RPCLIB_DEP_LIBRARIES}) +target_include_directories( + ${PROJECT_NAME} PUBLIC + $ + $ + ) +target_include_directories( + ${PROJECT_NAME} SYSTEM + PRIVATE ${RPCLIB_DEPENDENCIES}/include + ) + +install(TARGETS ${PROJECT_NAME} DESTINATION lib EXPORT rpclibTargets) +install(DIRECTORY include/ + DESTINATION include + FILES_MATCHING + PATTERN "*.h" + PATTERN "*.hpp" + PATTERN "*.inl" + PATTERN "*.in" EXCLUDE) + # # Unit tests # -################################################################################ - if(RPCLIB_BUILD_TESTS) - set(TEST_PROJECT_NAME ${CMAKE_PROJECT_NAME}_test) - set(TEST_SOURCES - dependencies/src/gmock-gtest-all.cc - tests/testmain.cc - tests/testutils.h - tests/rpc/dispatcher_test.cc - tests/rpc/client_test.cc - tests/rpc/response_test.cc - tests/rpc/server_test.cc - tests/rpc/this_handler_test.cc - tests/rpc/this_session_test.cc - tests/rpc/server_session_test.cc - tests/rpc/this_server_test.cc) - - - add_executable(${TEST_PROJECT_NAME} ${TEST_SOURCES}) - set_rpclib_flags(${TEST_PROJECT_NAME}) - target_include_directories(${TEST_PROJECT_NAME} SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/tests") - target_link_libraries( - ${TEST_PROJECT_NAME} - ${OUTPUT_LIBRARY_NAME} - ${RPCLIB_DEP_LIBRARIES}) - - # Set less strict warning for tests, since google test is not quite - # warning-clean - if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") - get_target_property(ORIGINAL_FLAGS ${TEST_PROJECT_NAME} COMPILE_FLAGS) - set_target_properties(${TEST_PROJECT_NAME} PROPERTIES COMPILE_FLAGS - "${ORIGINAL_FLAGS} -Wno-sign-conversion -Wno-weak-vtables -Wno-unused-member-function \ - -Wno-global-constructors -Wno-used-but-marked-unused -Wno-covered-switch-default \ - -Wno-missing-variable-declarations -Wno-deprecated -Wno-unused-macros -Wno-undef \ - -Wno-exit-time-destructors -Wno-switch-enum -Wno-format-nonliteral -Wno-unused-parameter -Wno-disabled-macro-expansion") - endif() - + add_subdirectory(tests) endif() -################################################################################ # # Example programs # -################################################################################ - if(RPCLIB_BUILD_EXAMPLES) - set(RPCLIB_ROOT_DIR "${PROJECT_SOURCE_DIR}") - set(RPCLIB_PROJECT_NAME "${CMAKE_PROJECT_NAME}") - set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/localbuild") - set(ENV{RPCLIB_DEFAULT_PORT} "${RPCLIB_DEFAULT_PORT}") - #add_subdirectory(examples/server) - #add_subdirectory(examples/client) - add_subdirectory(examples/echo) - add_subdirectory(examples/mandelbrot) - add_subdirectory(examples/calculator) + set(RPCLIB_ROOT_DIR "${PROJECT_SOURCE_DIR}") + set(RPCLIB_PROJECT_NAME "${CMAKE_PROJECT_NAME}") + set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/localbuild") + set(ENV{RPCLIB_DEFAULT_PORT} "${RPCLIB_DEFAULT_PORT}") + add_subdirectory(examples/echo) + add_subdirectory(examples/mandelbrot) + add_subdirectory(examples/calculator) endif() +# +# Cmake Package +# +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/cmake/rpclibConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion + ) + +set(CONFIG_PACKAGE_LOCATION lib/cmake/rpclib) +set(INCLUDE_INSTALL_DIR include/ ) + +configure_package_config_file(cmake/rpclibConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/cmake/rpclibConfig.cmake + INSTALL_DESTINATION ${CONFIG_PACKAGE_LOCATION} + PATH_VARS INCLUDE_INSTALL_DIR + ) + +export(EXPORT rpclibTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/rpclibTargets.cmake" + NAMESPACE rpclib:: + ) + +install(EXPORT rpclibTargets + FILE rpclibTargets.cmake + NAMESPACE rpclib:: + DESTINATION ${CONFIG_PACKAGE_LOCATION} + ) +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/cmake/rpclibConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/rpclibConfigVersion.cmake + DESTINATION ${CONFIG_PACKAGE_LOCATION} + ) -################################################################################ # -# CPack +# Pkg-config # -################################################################################ - -include(InstallRequiredSystemLibraries) - -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Modern msgpack-rpc library for C++") -set(CPACK_PACKAGE_DESCRIPTION "rpclib is a modern msgpack-rpc library for C++. It allows connecting applications through a network channel where they can talk to each other using the msgpack-rpc protocol. It provides both a client and server, which can be used independently.") -set(CPACK_PACKAGE_VENDOR "Tamás Szelei") -set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md") -set(CPACK_PACKAGE_VERSION_MAJOR "${RPCLIB_VERSION_MAJOR}") -set(CPACK_PACKAGE_VERSION_MINOR "${RPCLIB_VERSION_MINOR}") -set(CPACK_PACKAGE_VERSION_PATCH "${RPCLIB_VERSION_PATCH}") -set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/output/pkg") -set(CPACK_PACKAGE_EXECUTABLES "librpc" "rpc") -set(CPACK_PACKAGE_NAME "lib${CMAKE_PROJECT_NAME}_${RPCLIB_DEB_ARCH}") -set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${RPCLIB_DEB_ARCH}) -set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Tamás Szelei") -set(CPACK_DEBIAN_PACKAGE_CONTACT "Tamás Szelei") -if(WIN32) - set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") +if(NOT MSVC) # Don't install pkg-config files when building with MSVC + # Variables for pkg-config files + set(prefix "${CMAKE_INSTALL_PREFIX}") + set(exec_prefix "") + set(libdir "${CMAKE_INSTALL_PREFIX}/lib") + set(includedir "${CMAKE_INSTALL_PREFIX}/include") + set(rpclib_version ${PROJECT_VERSION}) + get_target_property(rpclib_cflags ${PROJECT_NAME} COMPILE_OPTIONS) + string(REPLACE ";" " " rpclib_cflags "${rpclib_cflags}") # Convert list to string + + configure_file(rpclib.pc.in "${CMAKE_CURRENT_BINARY_DIR}/rpclib.pc" @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rpclib.pc" DESTINATION "${libdir}/pkgconfig") endif() -if(WIN32) - #set(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp") - #set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\MyExecutable.exe") - set(CPACK_PACKAGE_INSTALL_DIRECTORY "librpc ${RPCLIB_VERSION_MAJOR}.${RPCLIB_VERSION_MINOR}.${RPCLIB_VERSION_PATCH}") - set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} rpclib") - #set(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.my-project-home-page.org") - set(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\github.com/sztomi/rpc") - #set(CPACK_NSIS_CONTACT "me@my-personal-home-page.com") - set(CPACK_NSIS_MODIFY_PATH ON) -endif() -include(CPack) diff --git a/cmake/TargetArch.cmake b/cmake/TargetArch.cmake deleted file mode 100644 index 3761e4df..00000000 --- a/cmake/TargetArch.cmake +++ /dev/null @@ -1,134 +0,0 @@ -# Based on the Qt 5 processor detection code, so should be very accurate -# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h -# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64) - -# Regarding POWER/PowerPC, just as is noted in the Qt source, -# "There are many more known variants/revisions that we do not handle/detect." - -set(archdetect_c_code " -#if defined(__arm__) || defined(__TARGET_ARCH_ARM) - #if defined(__ARM_ARCH_7__) \\ - || defined(__ARM_ARCH_7A__) \\ - || defined(__ARM_ARCH_7R__) \\ - || defined(__ARM_ARCH_7M__) \\ - || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7) - #error cmake_ARCH armv7 - #elif defined(__ARM_ARCH_6__) \\ - || defined(__ARM_ARCH_6J__) \\ - || defined(__ARM_ARCH_6T2__) \\ - || defined(__ARM_ARCH_6Z__) \\ - || defined(__ARM_ARCH_6K__) \\ - || defined(__ARM_ARCH_6ZK__) \\ - || defined(__ARM_ARCH_6M__) \\ - || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6) - #error cmake_ARCH armv6 - #elif defined(__ARM_ARCH_5TEJ__) \\ - || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5) - #error cmake_ARCH armv5 - #else - #error cmake_ARCH arm - #endif -#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) - #error cmake_ARCH i386 -#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) - #error cmake_ARCH x86_64 -#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) - #error cmake_ARCH ia64 -#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\ - || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\ - || defined(_M_MPPC) || defined(_M_PPC) - #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) - #error cmake_ARCH ppc64 - #else - #error cmake_ARCH ppc - #endif -#endif - -#error cmake_ARCH unknown -") - -# Set ppc_support to TRUE before including this file or ppc and ppc64 -# will be treated as invalid architectures since they are no longer supported by Apple - -function(target_architecture output_var) - if(APPLE AND CMAKE_OSX_ARCHITECTURES) - # On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set - # First let's normalize the order of the values - - # Note that it's not possible to compile PowerPC applications if you are using - # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we - # disable it by default - # See this page for more information: - # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4 - - # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime. - # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise. - - foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES}) - if("${osx_arch}" STREQUAL "ppc" AND ppc_support) - set(osx_arch_ppc TRUE) - elseif("${osx_arch}" STREQUAL "i386") - set(osx_arch_i386 TRUE) - elseif("${osx_arch}" STREQUAL "x86_64") - set(osx_arch_x86_64 TRUE) - elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support) - set(osx_arch_ppc64 TRUE) - else() - message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}") - endif() - endforeach() - - # Now add all the architectures in our normalized order - if(osx_arch_ppc) - list(APPEND ARCH ppc) - endif() - - if(osx_arch_i386) - list(APPEND ARCH i386) - endif() - - if(osx_arch_x86_64) - list(APPEND ARCH x86_64) - endif() - - if(osx_arch_ppc64) - list(APPEND ARCH ppc64) - endif() - else() - file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}") - - enable_language(C) - - # Detect the architecture in a rather creative way... - # This compiles a small C program which is a series of ifdefs that selects a - # particular #error preprocessor directive whose message string contains the - # target architecture. The program will always fail to compile (both because - # file is not a valid C program, and obviously because of the presence of the - # #error preprocessor directives... but by exploiting the preprocessor in this - # way, we can detect the correct target architecture even when cross-compiling, - # since the program itself never needs to be run (only the compiler/preprocessor) - try_run( - run_result_unused - compile_result_unused - "${CMAKE_BINARY_DIR}" - "${CMAKE_BINARY_DIR}/arch.c" - COMPILE_OUTPUT_VARIABLE ARCH - CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} - ) - - # Parse the architecture name from the compiler output - string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}") - - # Get rid of the value marker leaving just the architecture name - string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}") - - # If we are compiling with an unknown architecture this variable should - # already be set to "unknown" but in the case that it's empty (i.e. due - # to a typo in the code), then set it to unknown - if (NOT ARCH) - set(ARCH unknown) - endif() - endif() - - set(${output_var} "${ARCH}" PARENT_SCOPE) -endfunction() diff --git a/cmake/msvc_support.cmake b/cmake/msvc_support.cmake new file mode 100644 index 00000000..a063bf8c --- /dev/null +++ b/cmake/msvc_support.cmake @@ -0,0 +1,55 @@ + +function(rpclib_msvc_support) + if(MSVC) + # When building via conan, respect the compilation settings. + if ("${CONAN_LINK_RUNTIME}" STREQUAL "/MT") + set(RPCLIB_MSVC_STATIC_RUNTIME ON) + endif() + + if(RPCLIB_ENABLE_COVERAGE) + message(FATAL_ERROR "Coverage is only supported with non-MS compilers") + endif() + + target_compile_definitions(${PROJECT_NAME} PRIVATE + "WIN32_LEAN_AND_MEAN" + "NOMINMAX" + "VC_EXTRALEAN" + "_CRT_SECURE_NO_WARNINGS" + "_CRT_NONSTDC_NO_DEPRECATE" + "_WIN32_WINNT=0x0501" + "_GNU_SOURCE" + "ASIO_HAS_STD_ADDRESSOF" + "ASIO_HAS_STD_ARRAY" + "ASIO_HAS_CSTDINT" + "ASIO_HAS_STD_SHARED_PTR" + "ASIO_HAS_STD_TYPE_TRAITS") + + # MSVC static runtime support + # + # While this pollutes global flags (when using add_library), you would not want to + # build with a disparity anyway. (also, CMake still has no support for this, so you + # would end up doing something like this yourself). + if (RPCLIB_MSVC_STATIC_RUNTIME) + set(variables + CMAKE_C_FLAGS_DEBUG + CMAKE_C_FLAGS_MINSIZEREL + CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_RELWITHDEBINFO + ) + message(STATUS + "MSVC -> forcing use of statically-linked runtime." + ) + + foreach(variable ${variables}) + if(${variable} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}") + endif() + endforeach() + + endif() + endif() +endfunction() diff --git a/cmake/policies.cmake b/cmake/policies.cmake new file mode 100644 index 00000000..914d69a6 --- /dev/null +++ b/cmake/policies.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0054 NEW) + diff --git a/cmake/rpclibConfig.cmake.in b/cmake/rpclibConfig.cmake.in new file mode 100644 index 00000000..1f7c385f --- /dev/null +++ b/cmake/rpclibConfig.cmake.in @@ -0,0 +1,10 @@ +# Example usage: +# find_package(rpclib REQUIRED) +# add_executable(foo main.cpp) +# target_link_libraries(foo rpclib::rpc) + +@PACKAGE_INIT@ + +set(RPCLIB_VERSION @RPCLIB_VERSION_MAJOR@.@RPCLIB_VERSION_MINOR@.@RPCLIB_VERSION_PATCH@) + +include("${CMAKE_CURRENT_LIST_DIR}/rpclibTargets.cmake") diff --git a/conanfile.txt b/conanfile.txt new file mode 100644 index 00000000..0911f43d --- /dev/null +++ b/conanfile.txt @@ -0,0 +1,5 @@ +[requires] +cmake_installer/1.0@conan/stable + +[generators] +virtualenv diff --git a/doc/pages/versions.md b/doc/pages/versions.md index 971a2108..7fcf6355 100644 --- a/doc/pages/versions.md +++ b/doc/pages/versions.md @@ -1,4 +1,4 @@ -You are reading the documentation of 2.1.0. +You are reading the documentation of ... If, for some reason you need the documentation of older versions, you can download them from this page. * [1.0.0](/archive/rpclib_docs_1.0.0.zip) diff --git a/include/rpc/config.h b/include/rpc/config.h index 06890879..66620ef3 100644 --- a/include/rpc/config.h +++ b/include/rpc/config.h @@ -30,7 +30,7 @@ struct constants RPCLIB_FINAL { #endif /* ifndef RPCLIB_MSGPACK */ #ifndef RPCLIB_CXX_STANDARD -#define RPCLIB_CXX_STANDARD 14 +#define RPCLIB_CXX_STANDARD 11 #endif #endif /* end of include guard: CONFIG_H_L7IVDSPZ */ diff --git a/include/rpc/nonstd/optional.hpp b/include/rpc/nonstd/optional.hpp index e88a4318..d9888cf4 100644 --- a/include/rpc/nonstd/optional.hpp +++ b/include/rpc/nonstd/optional.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #define optional_lite_VERSION "2.0.0" @@ -1066,7 +1067,7 @@ using namespace optional_lite; namespace std { template< class T > -class hash< nonstd::optional > +struct hash< nonstd::optional > { public: std::size_t operator()( nonstd::optional const & v ) const optional_noexcept diff --git a/include/rpc/version.h b/include/rpc/version.h index 54e2899e..f5c0a1df 100644 --- a/include/rpc/version.h +++ b/include/rpc/version.h @@ -5,8 +5,8 @@ namespace rpc { -static constexpr unsigned VERSION_MAJOR = 2; -static constexpr unsigned VERSION_MINOR = 1; +static constexpr unsigned VERSION_MAJOR = 3; +static constexpr unsigned VERSION_MINOR = 0; static constexpr unsigned VERSION_PATCH = 0; } /* rpc */ diff --git a/include/rpc/version.h.in b/include/rpc/version.h.in index f278fa79..d6edfd8f 100644 --- a/include/rpc/version.h.in +++ b/include/rpc/version.h.in @@ -5,9 +5,9 @@ namespace rpc { -static constexpr unsigned VERSION_MAJOR = @RPCLIB_VERSION_MAJOR@; -static constexpr unsigned VERSION_MINOR = @RPCLIB_VERSION_MINOR@; -static constexpr unsigned VERSION_PATCH = @RPCLIB_VERSION_PATCH@; +static constexpr unsigned VERSION_MAJOR = @rpc_VERSION_MAJOR@; +static constexpr unsigned VERSION_MINOR = @rpc_VERSION_MINOR@; +static constexpr unsigned VERSION_PATCH = @rpc_VERSION_PATCH@; } /* rpc */ diff --git a/rpclib.pc.in b/rpclib.pc.in new file mode 100644 index 00000000..10e5c16d --- /dev/null +++ b/rpclib.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: rpclib +Description: rpclib is a msgpack-rpc library written using modern C++ +Version: @rpclib_version@ +Libs: -L${libdir} -l@OUTPUT_LIBRARY_NAME@ +Cflags: -I${includedir} @rpclib_cflags@ \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 00000000..73e522a4 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,35 @@ +set(TEST_PROJECT_NAME ${CMAKE_PROJECT_NAME}_test) +set(TEST_SOURCES + ${RPCLIB_DEPENDENCIES}/src/gmock-gtest-all.cc + testmain.cc + testutils.h + rpc/dispatcher_test.cc + rpc/client_test.cc + rpc/response_test.cc + rpc/server_test.cc + rpc/this_handler_test.cc + rpc/this_session_test.cc + rpc/server_session_test.cc + rpc/this_server_test.cc) + +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) + +add_executable(${TEST_PROJECT_NAME} ${TEST_SOURCES}) + +target_include_directories(${TEST_PROJECT_NAME} + SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/tests" + PRIVATE "${RPCLIB_DEPENDENCIES}/include") + +target_link_libraries(${TEST_PROJECT_NAME} ${PROJECT_NAME} Threads::Threads) + +# Set less strict warning for tests, since google test is not quite +# warning-clean +if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") + get_target_property(ORIGINAL_FLAGS ${TEST_PROJECT_NAME} COMPILE_OPTION) + target_compile_options(${TEST_PROJECT_NAME} PRIVATE -Wno-sign-conversion -Wno-weak-vtables -Wno-unused-member-function + -Wno-global-constructors -Wno-used-but-marked-unused -Wno-covered-switch-default + -Wno-missing-variable-declarations -Wno-deprecated -Wno-unused-macros -Wno-undef + -Wno-exit-time-destructors -Wno-switch-enum -Wno-format-nonliteral -Wno-unused-parameter -Wno-disabled-macro-expansion) +endif() + diff --git a/tests/rpc/client_test.cc b/tests/rpc/client_test.cc index 36363a1b..bf44e107 100644 --- a/tests/rpc/client_test.cc +++ b/tests/rpc/client_test.cc @@ -4,8 +4,8 @@ #include "rpc/server.h" #include "rpc/rpc_error.h" #include "testutils.h" -#include "format.h" +#include #include #include @@ -88,10 +88,12 @@ TEST_F(client_test, timeout_right_msg) { client.call("sleep", short_timeout + 10); FAIL() << "There was no exception thrown."; } catch (rpc::timeout &t) { - auto expected_msg = RPCLIB_FMT::format( - "rpc::timeout: Timeout of {}ms while calling RPC function '{}'", - *client.get_timeout(), "sleep"); - EXPECT_TRUE(str_match(t.what(), expected_msg)); + std::stringstream ss; + ss + << "rpc::timeout: Timeout of " + << *client.get_timeout() + << "ms while calling RPC function 'sleep'"; + EXPECT_TRUE(str_match(t.what(), ss.str())); } } diff --git a/tests/testutils.h b/tests/testutils.h index 6a92b006..bc8e7ccf 100644 --- a/tests/testutils.h +++ b/tests/testutils.h @@ -4,7 +4,7 @@ #define TESTUTILS_H_LHCAMVUX #include "gmock/gmock.h" -#include "msgpack.hpp" +#include "rpc/msgpack.hpp" #include #include #include