diff --git a/.github/workflows/build-ubuntu.yml b/.github/workflows/build-ubuntu.yml index 789cc11..fd71b20 100644 --- a/.github/workflows/build-ubuntu.yml +++ b/.github/workflows/build-ubuntu.yml @@ -11,12 +11,28 @@ env: jobs: build-ubuntu: + + strategy: + matrix: + library_type: [static, shared] + os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04] + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. # You can convert this to a matrix build if you need cross-platform coverage. # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} steps: + + - name: Set Variables + run: | + if [[ '${{ matrix.library_type }}' == 'static' ]]; then + echo "build_shared_libs=OFF" >> "$GITHUB_ENV" + echo "package_postfix=static" >> "$GITHUB_ENV" + else + echo "build_shared_libs=ON" >> "$GITHUB_ENV" + echo "package_postfix=shared" >> "$GITHUB_ENV" + fi - name: Checkout uses: actions/checkout@v2 @@ -24,13 +40,59 @@ jobs: submodules: 'true' fetch-depth: 0 - + ############################################ + # Test-compile the project + ############################################ + - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/_build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + run: | + cmake -B ${{github.workspace}}/_build \ + -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ + -DBUILD_SHARED_LIBS=${{ env.build_shared_libs }} - name: Build # Build your program with the given configuration run: cmake --build ${{github.workspace}}/_build --config ${{env.BUILD_TYPE}} + + - name: CPack + run: cpack -G DEB + working-directory: ${{ github.workspace }}/_build + + - name: Upload binaries + uses: actions/upload-artifact@v2 + with: + name: tcp-pubsub-${{ matrix.os }}-${{ env.package_postfix }} + path: ${{github.workspace}}/_build/_package/*.deb + + + ############################################ + # Test if our binary can be linked against + ############################################ + + - name: Install binaries + shell: bash + run: sudo dpkg -i ${{ github.workspace }}/_build/_package/*.deb + + - name: Compile integration test (Release) + run: | + cmake -B ${{github.workspace}}/samples/integration_test/_build/release -DCMAKE_BUILD_TYPE=Release + cmake --build ${{github.workspace}}/samples/integration_test/_build/release + working-directory: ${{ github.workspace }}/samples/integration_test + + - name: Run integration test (Release) + run: ./integration_test + working-directory: ${{ github.workspace }}/samples/integration_test/_build/release + + - name: Compile integration test (Debug) + run: | + cmake -B ${{github.workspace}}/samples/integration_test/_build/debug -DCMAKE_BUILD_TYPE=Debug + cmake --build ${{github.workspace}}/samples/integration_test/_build/debug + working-directory: ${{ github.workspace }}/samples/integration_test + + - name: Run integration test (Debug) + run: ./integration_test + working-directory: ${{ github.workspace }}/samples/integration_test/_build/debug + diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 231d6e0..d53544f 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -7,30 +7,112 @@ on: env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release + INSTALL_PREFIX: _install jobs: build-windows: + strategy: + matrix: + library_type: [static, shared] + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. # You can convert this to a matrix build if you need cross-platform coverage. # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: windows-latest + runs-on: windows-2019 steps: + - name: Set Variables + run: | + if ( '${{ matrix.library_type }}' -eq 'static' ) + { + echo "build_shared_libs=OFF" >> "$Env:GITHUB_ENV" + echo "package_postfix=static" >> "$Env:GITHUB_ENV" + } + else + { + echo "build_shared_libs=ON" >> "$Env:GITHUB_ENV" + echo "package_postfix=shared" >> "$Env:GITHUB_ENV" + } + - name: Checkout uses: actions/checkout@v2 with: submodules: 'true' fetch-depth: 0 + ############################################ + # Test-compile the project + ############################################ - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/_build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + shell: cmd + run: | + cmake -B ${{github.workspace}}/_build ^ + -G "Visual Studio 16 2019" ^ + -A x64 ^ + -T v140 ^ + -DCMAKE_INSTALL_PREFIX=${{env.INSTALL_PREFIX}} ^ + -DBUILD_SHARED_LIBS=${{ env.build_shared_libs }} - - name: Build + - name: Build (Release) # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/_build --config ${{env.BUILD_TYPE}} + shell: cmd + run: | + cmake --build ${{github.workspace}}/_build --config Release --parallel + cmake --build ${{github.workspace}}/_build --config Release --target INSTALL + - name: Build (Debug) + # Build your program with the given configuration + shell: cmd + run: | + cmake --build ${{github.workspace}}/_build --config Debug --parallel + cmake --build ${{github.workspace}}/_build --config Debug --target INSTALL + + - name: Upload binaries + uses: actions/upload-artifact@v2 + with: + name: tcp-pubsub-win64-${{ matrix.library_type }} + path: ${{github.workspace}}/${{env.INSTALL_PREFIX}} + + ############################################ + # Test if our binary can be linked against + ############################################ + + - name: CMake integration test + shell: cmd + run: | + cmake -B ${{github.workspace}}/samples/integration_test/_build ^ + -A x64 ^ + -DCMAKE_PREFIX_PATH=${{github.workspace}}/${{env.INSTALL_PREFIX}} + working-directory: ${{ github.workspace }}/samples/integration_test + + - name: Compile integration test (Release) + shell: cmd + run: cmake --build ${{github.workspace}}/samples/integration_test/_build --config Release + working-directory: ${{ github.workspace }}/samples/integration_test + + - name: Run integration test (Release) + run: | + if ( '${{ matrix.library_type }}' -eq 'shared' ) + { + $Env:Path = '${{github.workspace}}/${{env.INSTALL_PREFIX}}/bin;' + $Env:Path + } + .\integration_test.exe + working-directory: ${{ github.workspace }}/samples/integration_test/_build/Release + + - name: Compile integration test (Debug) + shell: cmd + run: cmake --build ${{github.workspace}}/samples/integration_test/_build --config Debug + working-directory: ${{ github.workspace }}/samples/integration_test + + - name: Run integration test (Debug) + run: | + if ( '${{ matrix.library_type }}' -eq 'shared' ) + { + $Env:Path = '${{github.workspace}}/${{env.INSTALL_PREFIX}}/bin;' + $Env:Path + } + .\integration_test.exe + working-directory: ${{ github.workspace }}/samples/integration_test/_build/Debug \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5b7f317..5a258f0 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,4 @@ CMakeLists.txt.user #Build dir /_build - +/samples/integration_test/_build diff --git a/CMakeLists.txt b/CMakeLists.txt index edd11de..cdf73fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,23 +1,51 @@ cmake_minimum_required(VERSION 3.5.1) +# Project call +include("${CMAKE_CURRENT_LIST_DIR}/tcp_pubsub/version.cmake") +project(tcp_pubsub VERSION ${TCP_PUBSUB_VERSION_MAJOR}.${TCP_PUBSUB_VERSION_MINOR}.${TCP_PUBSUB_VERSION_PATCH}) + # Normalize backslashes from Windows paths file(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH) file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH) message(STATUS "Module Path: ${CMAKE_MODULE_PATH}") message(STATUS "Prefix Path: ${CMAKE_PREFIX_PATH}") +# CMake Options +option(TCP_PUBSUB_BUILD_SAMPLES + "Build project samples" + ON) + +option(TCP_PUBSUB_BUILD_ECAL_SAMPLES + "Build eCAL-based project samples. Requires eCAL to be findable by CMake." + OFF) + +# Module path for finding asio list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/modules) -project(tcp_pubsub) +# Set Debug postfix +set(CMAKE_DEBUG_POSTFIX d) +set(CMAKE_MINSIZEREL_POSTFIX minsize) +set(CMAKE_RELWITHDEBINFO_POSTFIX reldbg) +# Add main tcp_pubsub library add_subdirectory(tcp_pubsub) +# Recycle dependency. It's header only and not in the API, so we add it with EXCLUDE_FOR_ALL, so it won't be installed add_subdirectory(thirdparty/recycle EXCLUDE_FROM_ALL) -add_subdirectory(samples/performance_publisher) -add_subdirectory(samples/performance_subscriber) -add_subdirectory(samples/hello_world_publisher) -add_subdirectory(samples/hello_world_subscriber) +# Generic samples +if (TCP_PUBSUB_BUILD_SAMPLES) + add_subdirectory(samples/performance_publisher) + add_subdirectory(samples/performance_subscriber) + add_subdirectory(samples/hello_world_publisher) + add_subdirectory(samples/hello_world_subscriber) +endif() + +# Specific eCAL Samples that tunnel an eCAL Topic through TCP +if(TCP_PUBSUB_BUILD_ECAL_SAMPLES) + add_subdirectory(samples/ecal_to_tcp) + add_subdirectory(samples/tcp_to_ecal) +endif() -# add_subdirectory(samples/ecal_to_tcp) -# add_subdirectory(samples/tcp_to_ecal) +# Make this package available for packing with CPack +include("${CMAKE_CURRENT_LIST_DIR}/cpack_config.cmake") diff --git a/cpack_config.cmake b/cpack_config.cmake new file mode 100644 index 0000000..85d8e88 --- /dev/null +++ b/cpack_config.cmake @@ -0,0 +1,20 @@ +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A low-level publish-subscribe library operating on TCP/IP") +set(CPACK_PACKAGE_VENDOR "Eclipse eCAL") +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) +set(CPACK_PACKAGE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_package") + +set(CPACK_PACKAGE_CONTACT "florian.reimold@continental-corporation.com") + +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Florian Reimold ") +set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/eclipse-ecal/tcp_pubsub") +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) +set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON) + +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_LIST_DIR}/LICENSE") +set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_LIST_DIR}/README.md") + +include(CPack) diff --git a/samples/ecal_to_tcp/CMakeLists.txt b/samples/ecal_to_tcp/CMakeLists.txt index 78c1388..b3fde95 100644 --- a/samples/ecal_to_tcp/CMakeLists.txt +++ b/samples/ecal_to_tcp/CMakeLists.txt @@ -8,6 +8,7 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) find_package(tcp_pubsub REQUIRED) find_package(eCAL REQUIRED) +find_package(Threads REQUIRED) set(sources src/main.cpp @@ -20,4 +21,5 @@ add_executable (${PROJECT_NAME} target_link_libraries (${PROJECT_NAME} tcp_pubsub::tcp_pubsub eCAL::core + Threads::Threads ) diff --git a/samples/integration_test/CMakeLists.txt b/samples/integration_test/CMakeLists.txt new file mode 100644 index 0000000..3d4cd99 --- /dev/null +++ b/samples/integration_test/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(integration_test) + +set(CMAKE_CXX_STANDARD 14) + +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) +find_package(tcp_pubsub REQUIRED) + +set(sources + src/main.cpp +) + +add_executable (${PROJECT_NAME} + ${sources} +) + +target_link_libraries (${PROJECT_NAME} + tcp_pubsub::tcp_pubsub +) diff --git a/samples/integration_test/src/main.cpp b/samples/integration_test/src/main.cpp new file mode 100644 index 0000000..e344946 --- /dev/null +++ b/samples/integration_test/src/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Continental. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for details. + +#include +#include + +#include + +int main() +{ + { + std::shared_ptr executor = std::make_shared(6); + tcp_pubsub::Publisher hello_world_publisher(executor, 1588); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + return 0; +} diff --git a/samples/performance_publisher/CMakeLists.txt b/samples/performance_publisher/CMakeLists.txt index 9ec8a7e..0556772 100644 --- a/samples/performance_publisher/CMakeLists.txt +++ b/samples/performance_publisher/CMakeLists.txt @@ -6,6 +6,7 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) find_package(tcp_pubsub REQUIRED) +find_package(Threads REQUIRED) set(sources src/main.cpp @@ -17,4 +18,5 @@ add_executable (${PROJECT_NAME} target_link_libraries (${PROJECT_NAME} tcp_pubsub::tcp_pubsub + Threads::Threads ) diff --git a/samples/performance_subscriber/CMakeLists.txt b/samples/performance_subscriber/CMakeLists.txt index 83508e3..9719444 100644 --- a/samples/performance_subscriber/CMakeLists.txt +++ b/samples/performance_subscriber/CMakeLists.txt @@ -6,6 +6,7 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) find_package(tcp_pubsub REQUIRED) +find_package(Threads REQUIRED) set(sources src/main.cpp @@ -17,4 +18,5 @@ add_executable (${PROJECT_NAME} target_link_libraries (${PROJECT_NAME} tcp_pubsub::tcp_pubsub + Threads::Threads ) diff --git a/samples/tcp_to_ecal/CMakeLists.txt b/samples/tcp_to_ecal/CMakeLists.txt index 3ac1e9d..73700cd 100644 --- a/samples/tcp_to_ecal/CMakeLists.txt +++ b/samples/tcp_to_ecal/CMakeLists.txt @@ -8,6 +8,7 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) find_package(tcp_pubsub REQUIRED) find_package(eCAL REQUIRED) +find_package(Threads REQUIRED) set(sources src/main.cpp @@ -20,4 +21,5 @@ add_executable (${PROJECT_NAME} target_link_libraries (${PROJECT_NAME} tcp_pubsub::tcp_pubsub eCAL::core + Threads::Threads ) diff --git a/tcp_pubsub/CMakeLists.txt b/tcp_pubsub/CMakeLists.txt index e26c5ab..45bceac 100644 --- a/tcp_pubsub/CMakeLists.txt +++ b/tcp_pubsub/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.5.1) -project(tcp_pubsub VERSION 1.0.0) +include("${CMAKE_CURRENT_LIST_DIR}/version.cmake") +project(tcp_pubsub VERSION ${TCP_PUBSUB_VERSION_MAJOR}.${TCP_PUBSUB_VERSION_MINOR}.${TCP_PUBSUB_VERSION_PATCH}) set(CMAKE_POSITION_INDEPENDENT_CODE ON) @@ -112,27 +113,56 @@ set_target_properties(${PROJECT_NAME} PROPERTIES include(sourcetree.cmake) create_source_tree(${includes} ${sources}) -################################## +################################################################################ +### Installation rules +################################################################################ set(TCP_PUBSUB_INSTALL_CMAKE_DIR "lib/cmake/tcp_pubsub") +# Install Runtime install( TARGETS ${PROJECT_NAME} - EXPORT tcp_pubsubTargets - LIBRARY DESTINATION "lib" - ARCHIVE DESTINATION "lib" + EXPORT tcp_pubsubRuntime + RUNTIME DESTINATION "bin" + COMPONENT tcp_pubsub_runtime +) + +# Install libs (-> dev package) +install( + TARGETS ${PROJECT_NAME} + EXPORT tcp_pubsubTargets + LIBRARY DESTINATION "lib" + ARCHIVE DESTINATION "lib" + COMPONENT tcp_pubsub_dev ) -install(DIRECTORY "include/tcp_pubsub" DESTINATION "include" FILES_MATCHING PATTERN "*.h") -install(DIRECTORY "${PROJECT_BINARY_DIR}/include/tcp_pubsub" DESTINATION "include" FILES_MATCHING PATTERN "*.h") +# Install public header files (-> dev package) +install( + DIRECTORY "include/tcp_pubsub" + DESTINATION "include" + COMPONENT tcp_pubsub_dev + FILES_MATCHING PATTERN "*.h" +) +# Install the auto-generated header with the export macros (-> dev package) +install( + DIRECTORY "${PROJECT_BINARY_DIR}/include/tcp_pubsub" + DESTINATION "include" + COMPONENT tcp_pubsub_dev + FILES_MATCHING PATTERN "*.h" +) + +# Install Target.cmake file (-> dev packag) install( EXPORT tcp_pubsubTargets FILE tcp_pubsubTargets.cmake DESTINATION ${TCP_PUBSUB_INSTALL_CMAKE_DIR} NAMESPACE tcp_pubsub:: + COMPONENT tcp_pubsub_dev ) +# Create and install Config.cmake file (-> dev package) + include(CMakePackageConfigHelpers) configure_package_config_file( @@ -141,5 +171,9 @@ configure_package_config_file( INSTALL_DESTINATION ${TCP_PUBSUB_INSTALL_CMAKE_DIR} PATH_VARS TCP_PUBSUB_INSTALL_CMAKE_DIR ) -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/tcp_pubsubConfig.cmake" DESTINATION ${TCP_PUBSUB_INSTALL_CMAKE_DIR}) +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/tcp_pubsubConfig.cmake" + DESTINATION ${TCP_PUBSUB_INSTALL_CMAKE_DIR} + COMPONENT tcp_pubsub_dev +) diff --git a/tcp_pubsub/version.cmake b/tcp_pubsub/version.cmake new file mode 100644 index 0000000..23ea458 --- /dev/null +++ b/tcp_pubsub/version.cmake @@ -0,0 +1,3 @@ +set(TCP_PUBSUB_VERSION_MAJOR 1) +set(TCP_PUBSUB_VERSION_MINOR 0) +set(TCP_PUBSUB_VERSION_PATCH 1) diff --git a/thirdparty/modules/Findasio.cmake b/thirdparty/modules/Findasio.cmake index 5151a88..e2e12de 100644 --- a/thirdparty/modules/Findasio.cmake +++ b/thirdparty/modules/Findasio.cmake @@ -1,32 +1,30 @@ -find_path(Asio_INCLUDE_DIR +find_path(asio_INCLUDE_DIR NAMES asio.hpp - PATHS - ${CMAKE_CURRENT_LIST_DIR}/../asio/asio/include - include + HINTS + "${CMAKE_CURRENT_LIST_DIR}/../asio/asio/include" + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH ) -if(Asio_INCLUDE_DIR-NOTFOUND) - message(FATAL_ERROR "Could not find Asio library") - set(Asio_FOUND False) +if(asio_INCLUDE_DIR-NOTFOUND) + message(FATAL_ERROR "Could not find asio library") + set(asio_FOUND FALSE) else() - set(Asio_FOUND True) - # Add workaround for stupid eprosima_find_package() - set(ASIO_INCLUDE_DIR ${Asio_INCLUDE_DIR}) + set(asio_FOUND TRUE) + set(ASIO_INCLUDE_DIR ${asio_INCLUDE_DIR}) endif() -if(Asio_FOUND) +if(asio_FOUND) include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(Asio - REQUIRED_VARS Asio_INCLUDE_DIR - ) + find_package_handle_standard_args(asio + REQUIRED_VARS asio_INCLUDE_DIR) if(NOT TARGET asio::asio) - set(Asio_INCLUDE_DIRS ${Asio_INCLUDE_DIR}) - + set(asio_INCLUDE_DIRS ${asio_INCLUDE_DIR}) add_library(asio::asio INTERFACE IMPORTED) set_target_properties(asio::asio PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${Asio_INCLUDE_DIR} + INTERFACE_INCLUDE_DIRECTORIES ${asio_INCLUDE_DIR} INTERFACE_COMPILE_DEFINITIONS ASIO_STANDALONE) - mark_as_advanced(Asio_INCLUDE_DIR) + mark_as_advanced(asio_INCLUDE_DIR) endif() endif()