diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 52ae953..9be6d73 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -11,7 +11,7 @@ defaults: shell: bash -l -eo pipefail {0} jobs: - build_linux: + linux_build_from_conda_forge: runs-on: ubuntu-latest strategy: matrix: @@ -20,22 +20,63 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Create build environment uses: mamba-org/setup-micromamba@v2 with: environment-file: ./environment-dev.yml environment-name: build_env cache-environment: true - - name: Build sparrow-ipc + + - name: Configure using cmake run: | - cmake -B build/ -G Ninja \ - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ - -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ - -DCMAKE_PREFIX_PATH=$CONDA_PREFIX \ - -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} \ - -DBUILD_TESTS=ON - cmake --build build/ --parallel + cmake -G Ninja \ + -Bbuild \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX% \ + -DCMAKE_PREFIX_PATH=%CONDA_PREFIX% \ + -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} \ + -DSPARROW_IPC_BUILD_TESTS=ON + + - name: Build sparrow-ipc + working-directory: build + run: cmake --build . --target sparrow-ipc + + - name: Build tests + working-directory: build + run: cmake --build . --target test_sparrow_ipc_lib + - name: Run tests + working-directory: build + run: cmake --build . --target run_tests_with_junit_report + + linux_build_fetch_from_source: + runs-on: ubuntu-latest + strategy: + matrix: + build_type: [Release, Debug] + build_shared: [ON, OFF] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Configure using cmake run: | - cd build - ctest --output-on-failure + cmake -G Ninja \ + -Bbuild \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} \ + -DSPARROW_IPC_BUILD_TESTS=ON \ + -DFETCH_DEPENDENCIES_WITH_CMAKE=MISSING + + - name: Build sparrow-ipc + working-directory: build + run: cmake --build . --target sparrow-ipc + + - name: Build tests + working-directory: build + run: cmake --build . --target test_sparrow_ipc_lib + + - name: Run tests + working-directory: build + run: cmake --build . --target run_tests_with_junit_report diff --git a/.github/workflows/osx.yml b/.github/workflows/osx.yml index cfb760f..ea4c739 100644 --- a/.github/workflows/osx.yml +++ b/.github/workflows/osx.yml @@ -11,7 +11,7 @@ defaults: shell: bash -l -eo pipefail {0} jobs: - build_osx: + osx_build_from_conda_forge: runs-on: macos-latest strategy: matrix: @@ -20,22 +20,73 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + + - name: Select XCode version + run: | + sudo xcode-select --switch /Applications/Xcode_16.4.app/Contents/Developer + xcodebuild -version + - name: Create build environment uses: mamba-org/setup-micromamba@v2 with: environment-file: ./environment-dev.yml environment-name: build_env cache-environment: true - - name: Build sparrow-ipc + + - name: Configure using cmake run: | - cmake -B build/ -G Ninja \ - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ - -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ - -DCMAKE_PREFIX_PATH=$CONDA_PREFIX \ - -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} \ - -DBUILD_TESTS=ON - cmake --build build/ --parallel + cmake -G Ninja \ + -Bbuild \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX% \ + -DCMAKE_PREFIX_PATH=%CONDA_PREFIX% \ + -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} \ + -DSPARROW_IPC_BUILD_TESTS=ON + + - name: Build sparrow-ipc + working-directory: build + run: cmake --build . --target sparrow-ipc + + - name: Build tests + working-directory: build + run: cmake --build . --target test_sparrow_ipc_lib + - name: Run tests + working-directory: build + run: cmake --build . --target run_tests_with_junit_report + + osx_build_fetch_from_source: + runs-on: macos-latest + strategy: + matrix: + build_type: [Release, Debug] + build_shared: [ON, OFF] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Select XCode version run: | - cd build - ctest --output-on-failure + sudo xcode-select --switch /Applications/Xcode_16.4.app/Contents/Developer + xcodebuild -version + + - name: Configure using cmake + run: | + cmake -G Ninja \ + -Bbuild \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} \ + -DSPARROW_IPC_BUILD_TESTS=ON \ + -DFETCH_DEPENDENCIES_WITH_CMAKE=MISSING + + - name: Build sparrow-ipc + working-directory: build + run: cmake --build . --target sparrow-ipc + + - name: Build tests + working-directory: build + run: cmake --build . --target test_sparrow_ipc_lib + + - name: Run tests + working-directory: build + run: cmake --build . --target run_tests_with_junit_report diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 3f57427..73768b2 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -8,11 +8,10 @@ on: defaults: run: - # micromamba activation - shell: cmd /C call {0} + shell: bash -e -l {0} jobs: - build_windows: + windows_build_from_conda_forge: runs-on: windows-latest strategy: matrix: @@ -21,27 +20,63 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Create build environment uses: mamba-org/setup-micromamba@v2 with: environment-file: ./environment-dev.yml environment-name: build_env + init-shell: bash cache-environment: true - init-shell: cmd.exe + + - name: Configure using cmake + run: | + cmake -S ./ -B ./build \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX% \ + -DCMAKE_PREFIX_PATH=%CONDA_PREFIX% \ + -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} \ + -DSPARROW_IPC_BUILD_TESTS=ON + - name: Build sparrow-ipc + working-directory: build + run: cmake --build . --target sparrow-ipc + + - name: Build tests + working-directory: build + run: cmake --build . --target test_sparrow_ipc_lib + + - name: Run tests + working-directory: build run: | - cmake -B build/ -G Ninja ^ - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} ^ - -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX% ^ - -DCMAKE_PREFIX_PATH=%CONDA_PREFIX% ^ - -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} ^ - -DBUILD_TESTS=ON - if %errorlevel% neq 0 exit /b %errorlevel% - cmake --build build/ --parallel - if %errorlevel% neq 0 exit /b %errorlevel% - # TODO this is failing (to debug when dependencies can be fetched and built locally with debug mode) - #- name: Run tests - #run: | - #cd build - #ctest --output-on-failure - #if %errorlevel% neq 0 exit /b %errorlevel% + cmake --build . --target run_tests + + windows_build_fetch_from_source: + runs-on: windows-latest + strategy: + matrix: + build_type: [Release, Debug] + build_shared: [ON, OFF] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Configure using cmake + run: | + cmake -S ./ -B ./build \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DSPARROW_IPC_BUILD_SHARED=${{ matrix.build_shared }} \ + -DSPARROW_IPC_BUILD_TESTS=ON \ + -DFETCH_DEPENDENCIES_WITH_CMAKE=MISSING + + - name: Build sparrow-ipc + working-directory: build + run: cmake --build . --target sparrow-ipc + + - name: Build tests + working-directory: build + run: cmake --build . --target test_sparrow_ipc_lib + + - name: Run tests + working-directory: build + run: cmake --build . --target run_tests_with_junit_report diff --git a/.gitignore b/.gitignore index 8e81a66..a6780cd 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ # Build directories /build*/ +.cache +.vscode diff --git a/CMakeLists.txt b/CMakeLists.txt index e9c3053..d27a2db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,17 @@ cmake_minimum_required(VERSION 3.28) project(sparrow-ipc CXX) -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 20 CACHE STRING "C++ Standard") +set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL "C++ Standard Required") +set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_SCAN_FOR_MODULES OFF) include(CMakeDependentOption) +list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") +message(DEBUG "CMake module path: ${CMAKE_MODULE_PATH}") + +include(external_dependencies) + set(SPARROW_IPC_COMPILE_DEFINITIONS "" CACHE STRING "List of public compile definitions of the sparrow-ipc target") # Linter options @@ -35,8 +41,8 @@ else() list(APPEND SPARROW_IPC_COMPILE_DEFINITIONS SPARROW_IPC_STATIC_LIB) endif() -OPTION(BUILD_TESTS "Build sparrow-ipc test suite" OFF) -MESSAGE(STATUS "๐Ÿ”ง Build tests: ${BUILD_TESTS}") +OPTION(SPARROW_IPC_BUILD_TESTS "Build sparrow-ipc test suite" OFF) +MESSAGE(STATUS "๐Ÿ”ง Build tests: ${SPARROW_IPC_BUILD_TESTS}") set(SPARROW_IPC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) set(SPARROW_IPC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) @@ -51,16 +57,8 @@ set(SPARROW_IPC_SRC ${SPARROW_IPC_SOURCE_DIR}/utils.cpp ) -set(SCHEMA_DIR ${CMAKE_BINARY_DIR}/format) -set(FLATBUFFERS_GENERATED_DIR ${CMAKE_BINARY_DIR}/generated) - -find_program(FLATC_EXECUTABLE flatc) - -if(NOT FLATC_EXECUTABLE) - message(FATAL_ERROR "flatc not found. Please install Flatbuffers.") -endif() - # Fetch schemas from apache arrow +set(SCHEMA_DIR ${CMAKE_BINARY_DIR}/format) set(SCHEMA_URLS "https://raw.githubusercontent.com/apache/arrow/refs/heads/main/format/File.fbs" "https://raw.githubusercontent.com/apache/arrow/refs/heads/main/format/Message.fbs" @@ -76,14 +74,17 @@ file(MAKE_DIRECTORY ${SCHEMA_DIR}) set(FLATBUFFERS_SCHEMAS "") foreach(url IN LISTS SCHEMA_URLS) get_filename_component(filename ${url} NAME) - message(STATUS "Downloading schema: ${url}") - file(DOWNLOAD ${url} ${SCHEMA_DIR}/${filename} - STATUS status - SHOW_PROGRESS) + if(NOT EXISTS ${SCHEMA_DIR}/${filename}) + message(STATUS "Downloading schema: ${url}") + file(DOWNLOAD ${url} ${SCHEMA_DIR}/${filename} + STATUS status) + endif() + list(APPEND FLATBUFFERS_SCHEMAS ${SCHEMA_DIR}/${filename}) endforeach() # Generate Flatbuffers C++ headers from the schemas +set(FLATBUFFERS_GENERATED_DIR ${CMAKE_BINARY_DIR}/generated) file(MAKE_DIRECTORY ${FLATBUFFERS_GENERATED_DIR}) # Generate output files list @@ -96,7 +97,7 @@ endforeach() add_custom_command( OUTPUT ${FLATBUFFERS_GENERATED_HEADERS} - COMMAND ${FLATC_EXECUTABLE} --cpp -o ${FLATBUFFERS_GENERATED_DIR} --cpp-std c++17 --scoped-enums ${FLATBUFFERS_SCHEMAS} + COMMAND flatc --cpp -o ${FLATBUFFERS_GENERATED_DIR} --cpp-std c++17 --scoped-enums ${FLATBUFFERS_SCHEMAS} DEPENDS ${FLATBUFFERS_SCHEMAS} COMMENT "Generating FlatBuffers C++ headers from schemas" ) @@ -110,11 +111,16 @@ add_library(flatbuffers_interface INTERFACE) target_include_directories(flatbuffers_interface INTERFACE ${FLATBUFFERS_GENERATED_DIR}) add_dependencies(flatbuffers_interface generate_flatbuffers_headers) -find_package(FlatBuffers CONFIG REQUIRED) -find_package(sparrow CONFIG REQUIRED) - add_library(sparrow-ipc ${SPARROW_IPC_LIBRARY_TYPE} ${SPARROW_IPC_SRC} ${SPARROW_IPC_HEADERS}) -target_compile_definitions(sparrow-ipc PUBLIC ${SPARROW_IPC_COMPILE_DEFINITIONS}) + +target_compile_options(sparrow-ipc + PRIVATE + ${compile_options} +) + +target_compile_definitions(sparrow-ipc + PUBLIC + ${SPARROW_IPC_COMPILE_DEFINITIONS}) if(UNIX) target_compile_options(sparrow-ipc PRIVATE "-fvisibility=hidden") @@ -122,18 +128,22 @@ else() target_compile_definitions(sparrow-ipc PRIVATE SPARROW_IPC_EXPORTS) endif() -target_compile_options(sparrow-ipc +target_include_directories(sparrow-ipc + PUBLIC + ${SPARROW_IPC_INCLUDE_DIR} PRIVATE - ${compile_options} -) + ${SPARROW_IPC_SOURCE_DIR} ) -target_include_directories(sparrow-ipc PUBLIC ${SPARROW_IPC_INCLUDE_DIR} PRIVATE ${SPARROW_IPC_SOURCE_DIR} ) -target_link_libraries(sparrow-ipc PRIVATE flatbuffers_interface) -target_link_libraries(sparrow-ipc PUBLIC flatbuffers::flatbuffers sparrow::sparrow) +target_link_libraries(sparrow-ipc + PUBLIC + sparrow::sparrow + flatbuffers::flatbuffers + PRIVATE + flatbuffers_interface) add_dependencies(sparrow-ipc generate_flatbuffers_headers) -if(BUILD_TESTS) +if(SPARROW_IPC_BUILD_TESTS) message(STATUS "๐Ÿงช Create tests targets") enable_testing() add_subdirectory(tests) diff --git a/cmake/external_dependencies.cmake b/cmake/external_dependencies.cmake new file mode 100644 index 0000000..742a3c9 --- /dev/null +++ b/cmake/external_dependencies.cmake @@ -0,0 +1,74 @@ +include(FetchContent) + +OPTION(FETCH_DEPENDENCIES_WITH_CMAKE "Fetch dependencies with CMake: Can be OFF, ON, or MISSING. If the latter, CMake will download only dependencies which are not previously found." OFF) +MESSAGE(STATUS "๐Ÿ”ง FETCH_DEPENDENCIES_WITH_CMAKE: ${FETCH_DEPENDENCIES_WITH_CMAKE}") + +if(FETCH_DEPENDENCIES_WITH_CMAKE STREQUAL "OFF") + set(FIND_PACKAGE_OPTIONS REQUIRED) +else() + set(FIND_PACKAGE_OPTIONS QUIET) +endif() + +function(find_package_or_fetch) + set(options) + set(oneValueArgs PACKAGE_NAME VERSION GIT_REPOSITORY TAG) + set(multiValueArgs) + cmake_parse_arguments(PARSE_ARGV 0 arg + "${options}" "${oneValueArgs}" "${multiValueArgs}" + ) + if(NOT FETCH_DEPENDENCIES_WITH_CMAKE STREQUAL "ON") + find_package(${arg_PACKAGE_NAME} ${FIND_PACKAGE_OPTIONS}) + endif() + if(FETCH_DEPENDENCIES_WITH_CMAKE STREQUAL "ON" OR FETCH_DEPENDENCIES_WITH_CMAKE STREQUAL "MISSING") + if(NOT ${arg_PACKAGE_NAME}_FOUND) + message(STATUS "๐Ÿ“ฆ Fetching ${arg_PACKAGE_NAME}") + FetchContent_Declare( + ${arg_PACKAGE_NAME} + GIT_SHALLOW TRUE + GIT_REPOSITORY ${arg_GIT_REPOSITORY} + GIT_TAG ${arg_TAG} + GIT_PROGRESS TRUE + SYSTEM + EXCLUDE_FROM_ALL) + FetchContent_MakeAvailable(${arg_PACKAGE_NAME}) + message(STATUS "\tโœ… Fetched ${arg_PACKAGE_NAME}") + else() + message(STATUS "๐Ÿ“ฆ ${arg_PACKAGE_NAME} found here: ${arg_PACKAGE_NAME}_DIR") + endif() + endif() +endfunction() + +set(SPARROW_BUILD_SHARED ${SPARROW_IPC_BUILD_SHARED}) +find_package_or_fetch( + PACKAGE_NAME sparrow + VERSION 1.0.0 + GIT_REPOSITORY https://github.com/man-group/sparrow.git + TAG 1.0.0 +) + +if(NOT TARGET sparrow::sparrow) + add_library(sparrow::sparrow ALIAS sparrow) +endif() + +set(FLATBUFFERS_BUILD_TESTS OFF) +set(FLATBUFFERS_BUILD_SHAREDLIB ${SPARROW_IPC_BUILD_SHARED}) +find_package_or_fetch( + PACKAGE_NAME FlatBuffers + VERSION v25.2.10 + GIT_REPOSITORY https://github.com/google/flatbuffers.git + TAG v25.2.10 +) + +if(NOT TARGET flatbuffers::flatbuffers) + add_library(flatbuffers::flatbuffers ALIAS flatbuffers) +endif() +unset(FLATBUFFERS_BUILD_TESTS CACHE) + +if(SPARROW_IPC_BUILD_TESTS) + find_package_or_fetch( + PACKAGE_NAME doctest + VERSION v2.4.12 + GIT_REPOSITORY https://github.com/doctest/doctest.git + TAG v2.4.12 + ) +endif() \ No newline at end of file diff --git a/environment-dev.yml b/environment-dev.yml index 05b16b6..c27e3eb 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -4,11 +4,9 @@ channels: dependencies: # Build dependencies - cmake - - make - ninja - cxx-compiler # Libraries dependencies - flatbuffers - sparrow - # Tests - doctest diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e761543..eafa5d7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,15 +1,28 @@ cmake_minimum_required(VERSION 3.28) -find_package(doctest CONFIG REQUIRED) - set(test_target "test_sparrow_ipc_lib") add_executable(${test_target} main.cpp test_primitive_array.cpp test_utils.cpp) + target_link_libraries(${test_target} PRIVATE sparrow-ipc doctest::doctest ) + +if(WIN32) + add_custom_command( + TARGET ${test_target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "$" + "$" + COMMAND ${CMAKE_COMMAND} -E copy + "$" + "$" + COMMENT "Copying sparrow and sparrow-ipc DLLs to executable directory" + ) +endif() + target_include_directories(${test_target} PRIVATE ${CMAKE_BINARY_DIR}/generated @@ -17,3 +30,25 @@ target_include_directories(${test_target} ) add_dependencies(${test_target} generate_flatbuffers_headers) add_test(NAME sparrow-ipc-tests COMMAND ${test_target}) + +add_custom_target(run_tests + COMMAND ${test_target} + DEPENDS + ${test_target} + COMMENT "Running tests" + USES_TERMINAL +) + +set_target_properties(run_tests PROPERTIES FOLDER "Tests utilities") + +set(JUNIT_REPORT_FILE_DOCTEST ${CMAKE_CURRENT_BINARY_DIR}/test_sparrow-ipc_lib_report_doctest.xml) + +add_custom_target(run_tests_with_junit_report + COMMAND ${test_target} --reporters=junit --out=${JUNIT_REPORT_FILE_DOCTEST} --no-path-filenames=true # TODO: use better junit as in sparrow + DEPENDS + ${test_target} + COMMENT "Running tests with JUnit reports saved to: ${JUNIT_REPORT_FILE_DOCTEST}" + USES_TERMINAL +) + +set_target_properties(run_tests_with_junit_report PROPERTIES FOLDER "Tests utilities")