From ab4be803e494f1f8764b6db9562394b0a1752814 Mon Sep 17 00:00:00 2001 From: Benjamin Wagner Date: Fri, 24 Nov 2023 13:46:30 +0100 Subject: [PATCH] Add Clang Toolchain to the CI This commit adds the clang toolchain to the CI. We turn the main jobs into a test matrix that either runs with the clang, or gcc toolchain. When using the gcc toolchain everything stays as-is. When using the clang toolchain we use clang/clang++ as C/C++ compilers, respectively. We also build `AnyBlob` using `-DANYBLOB_LIBCXX_COMPAT=1`, which ensures that `libcxx` is used as a standard library. In principle, the test matrix could be even bigger: we could build with libcxx and gcc, and gnu c++ and clang. But we don't tests this for now. --- .github/actions/do-build/action.yml | 35 ++++++++++++++++++++++ .github/actions/install-deps/action.yml | 11 +++++++ .github/workflows/integration-tests.yml | 26 +++++++++------- .github/workflows/unit-tests.yml | 30 +++++++++++-------- CMakeLists.txt | 2 +- test/unit/network/io_uring_socket_test.cpp | 4 --- test/unit/network/send_receiver_test.cpp | 4 --- 7 files changed, 81 insertions(+), 31 deletions(-) create mode 100644 .github/actions/do-build/action.yml create mode 100644 .github/actions/install-deps/action.yml diff --git a/.github/actions/do-build/action.yml b/.github/actions/do-build/action.yml new file mode 100644 index 0000000..2e7bb52 --- /dev/null +++ b/.github/actions/do-build/action.yml @@ -0,0 +1,35 @@ +name: "Build AnyBlob" +description: "Build AnyBlob using either clang or gcc" +inputs: + clang-toolchain: + required: false + description: "Build with clang and use libcxx as the standard library" + default: false + +runs: + using: "composite" + steps: + # CMake configuration option 1 - GCC toolchain + - name: Configure CMake + if: ${{ inputs.clang-toolchain == 'false' }} + run: | + cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + shell: bash + + # CMake configuration option 2 - Clang toolchain + - name: Configure CMake + if: ${{ inputs.clang-toolchain == 'true' }} + # Explicitly use clang-15. The runner comes with clang-13, 14, and 15. + # However, only clang-15 and up support `-Wno-unqualified-std-cast-call`. + run: | + sudo apt install libc++-15-dev libc++abi-15-dev + cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ + -DCMAKE_C_COMPILER=clang-15 \ + -DCMAKE_CXX_COMPILER=clang++-15 \ + -DANYBLOB_LIBCXX_COMPAT=1 + shell: bash + + # Build library and test binaries + - name: Build + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + shell: bash diff --git a/.github/actions/install-deps/action.yml b/.github/actions/install-deps/action.yml new file mode 100644 index 0000000..148c98c --- /dev/null +++ b/.github/actions/install-deps/action.yml @@ -0,0 +1,11 @@ +name: "Install Dependencies" +description: "Installs dynamic libraries required by AnyBlob" + +runs: + using: "composite" + steps: + # Install dependencies + - name: Install dependencies + run: sudo apt update && sudo apt install liburing-dev openssl libssl-dev libjemalloc-dev lld + shell: bash + diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 367a474..914c104 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -12,11 +12,19 @@ on: env: BUILD_TYPE: Debug + # False ASAN positives for alloc_dealloc_mismatch when running with clang + # https://github.com/llvm/llvm-project/issues/59432 + ASAN_OPTIONS: alloc_dealloc_mismatch=0 jobs: integration-test: + name: Integration Tests (Clang ${{ matrix.clang-toolchain }}) # Run on ubuntu runs-on: ubuntu-latest + # Use both the GCC and Clang Toolchain + strategy: + matrix: + clang-toolchain: [true, false] # Define the steps steps: @@ -39,17 +47,15 @@ jobs: with: submodules: true - # Install dependencies - - name: Install dependencies - run: sudo apt update && sudo apt install liburing-dev openssl libssl-dev libjemalloc-dev lld + # Use action to install dependencies + - name: Install Dependencies + uses: ./.github/actions/install-deps - # CMake configuration - - name: Configure CMake - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - # Build library and integration tester - - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + # Use action to build + - name: Build AnyBlob + uses: ./.github/actions/do-build + with: + clang-toolchain: ${{ matrix.clang-toolchain }} # Run the integration test - name: Integration Test diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index a3e64df..390500d 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -12,11 +12,19 @@ on: env: BUILD_TYPE: Debug + # False ASAN positives for alloc_dealloc_mismatch when running with clang + # https://github.com/llvm/llvm-project/issues/59432 + ASAN_OPTIONS: alloc_dealloc_mismatch=0 jobs: - uint-test: + unit-test: + name: Unit Tests (Clang ${{ matrix.clang-toolchain }}) # Run on ubuntu runs-on: ubuntu-latest + # Use both the GCC and Clang Toolchain + strategy: + matrix: + clang-toolchain: [true, false] # Define the steps steps: @@ -25,19 +33,17 @@ jobs: with: submodules: true - # Install dependencies - - name: Install dependencies - run: sudo apt update && sudo apt install liburing-dev openssl libssl-dev libjemalloc-dev lld + # Use action to install dependencies + - name: Install Dependencies + uses: ./.github/actions/install-deps - # CMake configuration - - name: Configure CMake - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - # Build library and tester - - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + # Use action to build + - name: Build AnyBlob + uses: ./.github/actions/do-build + with: + clang-toolchain: ${{ matrix.clang-toolchain }} - # Run the unit test + # Run the unit tests - name: Unit Test working-directory: ${{github.workspace}}/build run: ./tester diff --git a/CMakeLists.txt b/CMakeLists.txt index 5316aa4..a3a1e0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ endif() option(ANYBLOB_LIBCXX_COMPAT "Build AnyBlob in a way that's compatible with libcxx." OFF) if (ANYBLOB_LIBCXX_COMPAT) + message("Building AnyBlob with libcxx") # Update compiler flags to use libcxx as standard library. set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -stdlib=libc++") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -stdlib=libc++") @@ -123,7 +124,6 @@ add_library(AnyBlob STATIC ${SRC_CPP} ${INCLUDE_HPP}) target_link_libraries(AnyBlob PUBLIC OpenSSL::SSL Threads::Threads ${LIBURING_LIBRARY} jemalloc) target_include_directories(AnyBlob PUBLIC ${PROJECT_SOURCE_DIR}/include) if (ANYBLOB_LIBCXX_COMPAT) - # For libcxx compat some files like the throughput resolver cannot be compiled at the moment. target_compile_definitions(AnyBlob PRIVATE ANYBLOB_LIBCXX_COMPAT) endif() diff --git a/test/unit/network/io_uring_socket_test.cpp b/test/unit/network/io_uring_socket_test.cpp index 3ee14ce..051922c 100644 --- a/test/unit/network/io_uring_socket_test.cpp +++ b/test/unit/network/io_uring_socket_test.cpp @@ -1,7 +1,3 @@ -// Sadly, the include order matters here. PerfEvent depends on sstream but -// does not include the header. -#include - #include "catch2/single_include/catch2/catch.hpp" #include "cloud/aws_resolver.hpp" #include "network/io_uring_socket.hpp" diff --git a/test/unit/network/send_receiver_test.cpp b/test/unit/network/send_receiver_test.cpp index e167416..8c11d8e 100644 --- a/test/unit/network/send_receiver_test.cpp +++ b/test/unit/network/send_receiver_test.cpp @@ -1,7 +1,3 @@ -// Sadly, the include order matters here. PerfEvent depends on sstream but -// does not include the header. -#include - #include "catch2/single_include/catch2/catch.hpp" #include "network/original_message.hpp" #include "network/tasked_send_receiver.hpp"