diff --git a/.circleci/config.yml b/.circleci/config.yml index e55b18e3..acbfc4f7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,14 @@ --- version: 2.1 +parameters: + GCC_VERSION: + type: string + default: "14" + CLANG_VERSION: + type: string + default: "19" + jobs: build-linux: parameters: @@ -19,19 +27,20 @@ jobs: ubsan: type: boolean default: false + environment: + GCC_VERSION: << pipeline.parameters.GCC_VERSION >> + CLANG_VERSION: << pipeline.parameters.CLANG_VERSION >> machine: image: ubuntu-2404:2024.11.1 resource_class: arm.medium steps: - checkout - - run: - name: Checkout submodules - command: git submodule update --init - run: name: Installing dependencies (common) command: | sudo apt-get update - sudo apt-get install -y libboost-dev + sudo apt-get install -y libboost-dev libgtest-dev libgmock-dev \ + libbenchmark-dev valgrind - when: condition: equal: ["gcc", << parameters.compiler >>] @@ -39,7 +48,7 @@ jobs: - run: name: Installing dependencies (GCC) command: | - sudo apt-get install -y g++-14 + sudo apt-get install -y g++-${GCC_VERSION} - when: condition: equal: ["clang", << parameters.compiler >>] @@ -47,8 +56,9 @@ jobs: - run: name: Installing dependencies (LLVM common) command: | - sudo apt-get install -y clang-19 clang-tidy-19 iwyu \ - libstdc++-14-dev + sudo apt-get install -y clang-${CLANG_VERSION} \ + clang-tidy-${CLANG_VERSION} iwyu \ + libstdc++-${GCC_VERSION}-dev - when: condition: and: @@ -58,7 +68,8 @@ jobs: - run: name: Installing dependencies (LLVM Release) command: | - sudo apt-get install -y libomp5-19 llvm-19 lld-19 + sudo apt-get install -y libomp5-${CLANG_VERSION} \ + llvm-${CLANG_VERSION} lld-${CLANG_VERSION} - when: condition: << parameters.tsan >> @@ -69,37 +80,66 @@ jobs: # https://github.com/google/sanitizers/issues/1716 has # propagated everywhere command: sudo sysctl vm.mmap_rnd_bits=28 + - when: + condition: + not: + or: + - << parameters.asan >> + - << parameters.tsan >> + - << parameters.ubsan >> + steps: + - run: + name: Configure CMake (examples) + command: | + readonly BUILD_TYPE=<< parameters.build_type >> + readonly COMPILER=<< parameters.compiler >> + if [[ $COMPILER == "gcc" ]]; then + export CC=gcc-$GCC_VERSION + export CXX=g++-$GCC_VERSION + elif [[ $COMPILER == "clang" ]]; then + export CC=clang-$CLANG_VERSION + export CXX=clang++-$CLANG_VERSION + fi + cmake -S examples -B build-examples \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE + - run: + name: Examples + working_directory: build-examples + command: make -j2 -k examples + - run: + name: Valgrind examples + working_directory: build-examples + command: make -k valgrind_examples - run: - name: Create build environment - command: mkdir build + name: Checkout submodules + command: git submodule update --init - run: name: Configure CMake - working_directory: build command: | + mkdir build + cd build readonly BUILD_TYPE=<< parameters.build_type >> readonly COMPILER=<< parameters.compiler >> readonly ASAN=<< parameters.asan >> readonly TSAN=<< parameters.tsan >> readonly UBSAN=<< parameters.ubsan >> if [[ $COMPILER == "gcc" ]]; then - V=14 - export CC=gcc-$V - export CXX=g++-$V + export CC=gcc-$GCC_VERSION + export CXX=g++-$GCC_VERSION EXTRA_CMAKE_ARGS=() elif [[ $COMPILER == "clang" ]]; then - V=19 - export CC=clang-$V - export CXX=clang++-$V + export CC=clang-$CLANG_VERSION + export CXX=clang++-$CLANG_VERSION if [[ $BUILD_TYPE == "Release" ]]; then EXTRA_CMAKE_ARGS=(\ - "-DLLVMAR_EXECUTABLE=/usr/bin/llvm-ar-$V" \ - "-DLLVMNM_EXECUTABLE=/usr/bin/llvm-nm-$V" \ - "-DLLVMRANLIB_EXECUTABLE=/usr/bin/llvm-ranlib-$V") + "-DLLVMAR_EXECUTABLE=/usr/bin/llvm-ar-$CLANG_VERSION" \ + "-DLLVMNM_EXECUTABLE=/usr/bin/llvm-nm-$CLANG_VERSION" \ + "-DLLVMRANLIB_EXECUTABLE=/usr/bin/llvm-ranlib-$CLANG_VERSION") else EXTRA_CMAKE_ARGS=() fi EXTRA_CMAKE_ARGS=("${EXTRA_CMAKE_ARGS[@]}" \ - "-DCLANG_TIDY_EXE=/usr/bin/clang-tidy-$V") + "-DCLANG_TIDY_EXE=/usr/bin/clang-tidy-$CLANG_VERSION") fi cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSTANDALONE=ON \ -DMAINTAINER_MODE=ON -DSANITIZE_ADDRESS=$ASAN \ @@ -109,10 +149,6 @@ jobs: name: Build working_directory: build command: make -j2 -k - - run: - name: Examples - working_directory: build - command: make -k examples - run: name: Correctness test working_directory: build @@ -139,9 +175,7 @@ jobs: - run: name: Valgrind test working_directory: build - command: | - sudo NEEDRESTART_MODE=a apt-get install -y valgrind - make -k valgrind + command: make -k valgrind build-macos: parameters: @@ -162,20 +196,39 @@ jobs: resource_class: macos.m1.medium.gen1 steps: - checkout - - run: - name: Checkout submodules - command: git submodule update --init --recursive - run: name: Install dependencies command: | sudo -H pip install setuptools brew install boost cmake + - when: + condition: + not: + or: + - << parameters.asan >> + - << parameters.tsan >> + - << parameters.ubsan >> + steps: + - run: + name: Installing dependencies (examples) + command: brew install googletest google-benchmark + - run: + name: Configure CMake (examples) + command: | + readonly BUILD_TYPE=<< parameters.build_type >> + export CC=clang + export CXX=clang++ + cmake -S examples -B build-examples \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE + - run: + name: Examples + working_directory: build-examples + command: make -j3 -k examples - run: - name: Create build environment - command: mkdir build + name: Checkout submodules + command: git submodule update --init --recursive - run: name: Configure CMake - working_directory: build command: | readonly BUILD_TYPE=<< parameters.build_type >> readonly ASAN=<< parameters.asan >> @@ -183,17 +236,13 @@ jobs: readonly UBSAN=<< parameters.ubsan >> export CC=clang export CXX=clang++ - cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSTANDALONE=ON \ + cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSTANDALONE=ON \ -DMAINTAINER_MODE=OFF -DSANITIZE_ADDRESS=$ASAN \ -DSANITIZE_THREAD=$TSAN -DSANITIZE_UB=$UBSAN - run: name: Build working_directory: build command: make -j3 -k - - run: - name: Examples - working_directory: build - command: make -k examples - run: name: Correctness test working_directory: build @@ -214,80 +263,80 @@ workflows: build: jobs: - build-linux: - name: GCC 14 Debug + name: GCC << pipeline.parameters.GCC_VERSION >> Debug build_type: Debug compiler: gcc - build-linux: - name: GCC 14 Debug with ASan + name: GCC << pipeline.parameters.GCC_VERSION >> Debug with ASan build_type: Debug compiler: gcc asan: true - build-linux: - name: GCC 14 Debug with TSan + name: GCC << pipeline.parameters.GCC_VERSION >> Debug with TSan build_type: Debug compiler: gcc tsan: true - build-linux: - name: GCC 14 Debug with UBSan + name: GCC << pipeline.parameters.GCC_VERSION >> Debug with UBSan build_type: Debug compiler: gcc ubsan: true - build-linux: - name: GCC 14 Release + name: GCC << pipeline.parameters.GCC_VERSION >> Release build_type: Release compiler: gcc - build-linux: - name: GCC 14 Release with ASan + name: GCC << pipeline.parameters.GCC_VERSION >> Release with ASan build_type: Release compiler: gcc asan: true - build-linux: - name: GCC 14 Release with TSan + name: GCC << pipeline.parameters.GCC_VERSION >> Release with TSan build_type: Release compiler: gcc tsan: true - build-linux: - name: GCC 14 Release with UBSan + name: GCC << pipeline.parameters.GCC_VERSION >> Release with UBSan build_type: Release compiler: gcc ubsan: true - build-linux: - name: clang 19 Debug + name: clang << pipeline.parameters.CLANG_VERSION >> Debug build_type: Debug compiler: clang - build-linux: - name: clang 19 Debug with ASan + name: clang << pipeline.parameters.CLANG_VERSION >> Debug with ASan build_type: Debug compiler: clang asan: true - build-linux: - name: clang 19 Debug with TSan + name: clang << pipeline.parameters.CLANG_VERSION >> Debug with TSan build_type: Debug compiler: clang tsan: true - build-linux: - name: clang 19 Debug with UBSan + name: clang << pipeline.parameters.CLANG_VERSION >> Debug with UBSan build_type: Debug compiler: clang ubsan: true - build-linux: - name: clang 19 Release + name: clang << pipeline.parameters.CLANG_VERSION >> Release build_type: Release compiler: clang # Disabled until https://github.com/laurynas-biveinis/unodb/issues/700 is # fixed. # - build-linux: - # name: clang 19 Release with ASan + # name: clang << pipeline.parameters.CLANG_VERSION >> Release with ASan # build_type: Release # compiler: clang # asan: true - build-linux: - name: clang 19 Release with TSan + name: clang << pipeline.parameters.CLANG_VERSION >> Release with TSan build_type: Release compiler: clang tsan: true - build-linux: - name: clang 19 Release with UBSan + name: clang << pipeline.parameters.CLANG_VERSION >> Release with UBSan build_type: Release compiler: clang ubsan: true diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86f3f5b3..a14e2812 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ env: DEFAULT_COVERAGE: OFF DEFAULT_AVX2: ON -permissions: { } +permissions: {} jobs: build: @@ -349,14 +349,10 @@ jobs: run: brew install cppcheck if: runner.os == 'macOS' && env.CPPCHECK == 'ON' - - name: Create build environment - run: mkdir ${{github.workspace}}/build - - name: Configure CMake # Use a bash shell so we can use the same syntax for environment # variable access regardless of the host operating system shell: bash - working-directory: ${{github.workspace}}/build run: | COMPILER="${COMPILER:-$DEFAULT_COMPILER}" SANITIZE_ADDRESS="${SANITIZE_ADDRESS:-$DEFAULT_SANITIZE_ADDRESS}" @@ -407,7 +403,7 @@ jobs: export CC=clang export CXX=clang++ fi - cmake "$GITHUB_WORKSPACE" "$CBT" -DSTANDALONE=ON \ + cmake -B build "$GITHUB_WORKSPACE" "$CBT" -DSTANDALONE=ON \ -DMAINTAINER_MODE=ON -DIWYU=ON \ "-DSANITIZE_ADDRESS=${SANITIZE_ADDRESS}" \ "-DSANITIZE_THREAD=${SANITIZE_THREAD}" \ @@ -427,11 +423,6 @@ jobs: --force-analyze-debug-code make -j3 -k; if: env.STATIC_ANALYSIS == 'ON' && env.COMPILER == 'clang' - - name: Examples - working-directory: ${{github.workspace}}/build - run: make -k examples - if: env.STATIC_ANALYSIS != 'ON' && env.COVERAGE != 'ON' - - name: Correctness test working-directory: ${{github.workspace}}/build run: ctest -j3 -V diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6899a5bb..acd6b93d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,16 +39,13 @@ jobs: languages: ${{ matrix.language }} build-mode: manual - - name: Create build environment - run: mkdir ${{github.workspace}}/build - - name: Configure CMake # Use a bash shell so we can use the same syntax for environment # variable access regardless of the host operating system shell: bash - working-directory: ${{github.workspace}}/build run: | - cmake "$GITHUB_WORKSPACE" -DCMAKE_BUILD_TYPE=Release -DSTANDALONE=ON + cmake -B build "$GITHUB_WORKSPACE" -DCMAKE_BUILD_TYPE=Release \ + -DSTANDALONE=ON - name: Build working-directory: ${{github.workspace}}/build diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml new file mode 100644 index 00000000..ff9364a5 --- /dev/null +++ b/.github/workflows/examples.yml @@ -0,0 +1,57 @@ +--- +name: examples + +on: + push: + branches: + - master + pull_request: + +permissions: {} + +jobs: + build: + runs-on: ubuntu-22.04 + + env: + BUILD_TYPE: ${{matrix.BUILD_TYPE}} + TESTS: ${{matrix.TESTS}} + BENCHMARKS: ${{matrix.BENCHMARKS}} + + strategy: + fail-fast: false + + matrix: + BUILD_TYPE: [Release, Debug] + TESTS: [ON, OFF] + BENCHMARKS: [ON, OFF] + + steps: + - uses: actions/checkout@v4 + with: + submodules: false + + - name: Setup dependencies + run: | + sudo apt-get update + sudo apt-get install -y libboost-dev libc6-dev-i386 libc6-dbg \ + libgtest-dev libgmock-dev libbenchmark-dev + # Install a newer version than the one in APT + sudo snap install --classic valgrind + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment + # variable access regardless of the host operating system + shell: bash + run: | + cmake -B build "$GITHUB_WORKSPACE/examples" \ + "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" "-DTESTS=$TESTS" \ + "-DBENCHMARKS=$BENCHMARKS" + + - name: Examples + working-directory: ${{github.workspace}}/build + run: make -j3 -k examples + + - name: Valgrind examples + working-directory: ${{github.workspace}}/build + run: make -j3 -k valgrind_examples diff --git a/.github/workflows/experimental-build.yml b/.github/workflows/experimental-build.yml index bc1b00c1..c249edc2 100644 --- a/.github/workflows/experimental-build.yml +++ b/.github/workflows/experimental-build.yml @@ -7,7 +7,7 @@ on: - master pull_request: -permissions: { } +permissions: {} jobs: build: @@ -41,16 +41,12 @@ jobs: brew update brew install boost cppcheck - - name: Create build environment - run: mkdir ${{github.workspace}}/build - - name: Configure CMake with developer warnings shell: bash - working-directory: ${{github.workspace}}/build run: | export CC=clang export CXX=clang++ - cmake "$GITHUB_WORKSPACE" "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ + cmake -B build "$GITHUB_WORKSPACE" "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ -DCPPCHECK_AGGRESSIVE=ON -Wdev -Wdeprecated --warn-uninitialized - name: Build diff --git a/.github/workflows/feature-matrix-build.yml b/.github/workflows/feature-matrix-build.yml index e7eef05c..a95d8d8b 100644 --- a/.github/workflows/feature-matrix-build.yml +++ b/.github/workflows/feature-matrix-build.yml @@ -36,16 +36,12 @@ jobs: - name: Setup Boost run: sudo apt-get install -y libboost-dev - - name: Create build environment - run: mkdir ${{github.workspace}}/build - - name: Configure CMake # Use a bash shell so we can use the same syntax for environment # variable access regardless of the host operating system shell: bash - working-directory: ${{github.workspace}}/build run: | - cmake "$GITHUB_WORKSPACE" "-DSTANDALONE=$STANDALONE" \ + cmake -B build "$GITHUB_WORKSPACE" "-DSTANDALONE=$STANDALONE" \ "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" "-DTESTS=$TESTS" \ "-DBENCHMARKS=$BENCHMARKS" diff --git a/.github/workflows/msvc-build.yml b/.github/workflows/msvc-build.yml index 318e12e9..a800c5ea 100644 --- a/.github/workflows/msvc-build.yml +++ b/.github/workflows/msvc-build.yml @@ -7,12 +7,22 @@ on: - master pull_request: -permissions: { } +permissions: {} jobs: build: runs-on: windows-2022 + env: + EXAMPLE_PRESETS: >- + msvc-debug + msvc-release + msvc-llvm-debug + msvc-llvm-release + STATIC_ANALYSIS_PRESETS: >- + msvc-static-analysis-debug + msvc-static-analysis-release + strategy: fail-fast: false matrix: @@ -38,19 +48,19 @@ jobs: - name: MSVC Debug without AVX2 preset: "msvc-debug-no-avx2" - # MSVC static analysis false positive regression in 17.11: - # optimistic_lock.hpp(171) : warning C26493: Don't use C-style casts - # (type.4). - # - name: MSVC Static Analysis Debug - # preset: "msvc-static-analysis-debug" + # MSVC static analysis false positive regression in 17.11: + # optimistic_lock.hpp(171) : warning C26493: Don't use C-style casts + # (type.4). + # - name: MSVC Static Analysis Debug + # preset: "msvc-static-analysis-debug" - # - name: MSVC Static Analysis Release - # preset: "msvc-static-analysis-release" + # - name: MSVC Static Analysis Release + # preset: "msvc-static-analysis-release" steps: - uses: actions/checkout@v4 with: - submodules: true + submodules: false - name: Install Boost uses: MarkusJx/install-boost@v2.4.5 @@ -66,8 +76,35 @@ jobs: with: toolset: 14.42 - - name: Configure CMake + - name: Install dependencies + run: | + vcpkg install gtest benchmark + + - name: Configure CMake (examples) + working-directory: examples + run: | + # Ensure that we use clang-cl from MSVC, not LLVM + $env:path = $env:path -split ';' -notmatch 'C:\\Program Files\\LLVM\\bin' -join ';' + cmake --preset "${{ matrix.preset }}" + env: + BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }} + if: contains(env.EXAMPLE_PRESETS, matrix.preset) + + - name: Build (examples) + working-directory: examples run: | + cmake --build --preset "${{ matrix.preset }}" + if: contains(env.EXAMPLE_PRESETS, matrix.preset) + + - name: Run examples + working-directory: examples + run: | + cmake --build --preset "${{ matrix.preset }}" --target examples + if: contains(env.EXAMPLE_PRESETS, matrix.preset) + + - name: Populate git submodules and configure CMake + run: | + git submodule update --init --recursive # Ensure that we use clang-cl from MSVC, not LLVM $env:path = $env:path -split ';' -notmatch 'C:\\Program Files\\LLVM\\bin' -join ';' cmake --preset "${{ matrix.preset }}" @@ -86,29 +123,14 @@ jobs: with: name: sarif-file path: "${{github.workspace}}\\build\\${{matrix.preset}}\\msvc-${{matrix.preset}}.sarif" - if: > - always() - && (matrix.preset == 'msvc-static-analysis-release' - || matrix.preset == 'msvc-static-analysis-debug') - - - name: Examples - run: | - $Env:P = "${{ matrix.preset }}" - cmake --build --preset "$env:P" --target examples - if: > - (matrix.preset != 'msvc-static-analysis-release') - && (matrix.preset != 'msvc-static-analysis-debug') + if: contains(env.STATIC_ANALYSIS_PRESETS, matrix.preset) - name: Correctness test run: ctest -V --preset "${{ matrix.preset }}" - if: > - (matrix.preset != 'msvc-static-analysis-release') - && (matrix.preset != 'msvc-static-analysis-debug') + if: "!contains(env.STATIC_ANALYSIS_PRESETS, matrix.preset)" - name: Benchmark correctness test run: | $Env:P = "${{ matrix.preset }}" cmake --build --preset "$env:P" --target quick_benchmarks - if: > - (matrix.preset != 'msvc-static-analysis-release') - && (matrix.preset != 'msvc-static-analysis-debug') + if: "!contains(env.STATIC_ANALYSIS_PRESETS, matrix.preset)" diff --git a/.github/workflows/old-compilers.yml b/.github/workflows/old-compilers.yml index 275fa155..15780699 100644 --- a/.github/workflows/old-compilers.yml +++ b/.github/workflows/old-compilers.yml @@ -14,7 +14,7 @@ env: DEFAULT_SPINLOCK_LOOP: PAUSE DEFAULT_STATS: ON -permissions: { } +permissions: {} jobs: build: @@ -481,14 +481,10 @@ jobs: sudo apt-get install -y gcc if: env.COMPILER == 'gcc' && env.VERSION == '11' - - name: Create build environment - run: mkdir ${{github.workspace}}/build - - name: Configure CMake # Use a bash shell so we can use the same syntax for environment # variable access regardless of the host operating system shell: bash - working-directory: ${{github.workspace}}/build run: | SANITIZE_ADDRESS="${SANITIZE_ADDRESS:-$DEFAULT_SANITIZE_ADDRESS}" SANITIZE_THREAD="${SANITIZE_THREAD:-$DEFAULT_SANITIZE_THREAD}" @@ -514,7 +510,7 @@ jobs: EXTRA_CMAKE_ARGS=("${EXTRA_CMAKE_ARGS[@]}" "-DMAINTAINER_MODE=ON") fi fi - cmake "$GITHUB_WORKSPACE" -DSTANDALONE=ON \ + cmake -B build "$GITHUB_WORKSPACE" -DSTANDALONE=ON \ "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ "-DSANITIZE_ADDRESS=${SANITIZE_ADDRESS}" \ "-DSANITIZE_THREAD=${SANITIZE_THREAD}" \ @@ -526,10 +522,6 @@ jobs: working-directory: ${{github.workspace}}/build run: make -j3 -k - - name: Examples - working-directory: ${{github.workspace}}/build - run: make -k examples - - name: Correctness test working-directory: ${{github.workspace}}/build run: ctest -j3 -V diff --git a/.github/workflows/ubuntu-20.04.yml b/.github/workflows/ubuntu-20.04.yml index db08faef..164e7ccd 100644 --- a/.github/workflows/ubuntu-20.04.yml +++ b/.github/workflows/ubuntu-20.04.yml @@ -12,7 +12,7 @@ env: DEFAULT_SANITIZE_THREAD: OFF DEFAULT_SANITIZE_UB: OFF -permissions: { } +permissions: {} jobs: build: @@ -195,14 +195,10 @@ jobs: "lld-${VERSION}" if: env.COMPILER == 'clang' && env.BUILD_TYPE == 'Release' - - name: Create build environment - run: mkdir ${{github.workspace}}/build - - name: Configure CMake # Use a bash shell so we can use the same syntax for environment # variable access regardless of the host operating system shell: bash - working-directory: ${{github.workspace}}/build run: | SANITIZE_ADDRESS="${SANITIZE_ADDRESS:-$DEFAULT_SANITIZE_ADDRESS}" SANITIZE_THREAD="${SANITIZE_THREAD:-$DEFAULT_SANITIZE_THREAD}" @@ -222,7 +218,7 @@ jobs: "-DLLVMRANLIB_EXECUTABLE=/usr/bin/llvm-ranlib-${VERSION}") fi fi - cmake "$GITHUB_WORKSPACE" -DSTANDALONE=ON \ + cmake -B build "$GITHUB_WORKSPACE" -DSTANDALONE=ON \ "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ "-DSANITIZE_ADDRESS=${SANITIZE_ADDRESS}" \ "-DSANITIZE_THREAD=${SANITIZE_THREAD}" \ @@ -232,10 +228,6 @@ jobs: working-directory: ${{github.workspace}}/build run: make -j3 -k - - name: Examples - working-directory: ${{github.workspace}}/build - run: make -k examples - - name: Correctness test working-directory: ${{github.workspace}}/build run: ctest -j3 -V diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml index 2f41e8c3..359ccf88 100644 --- a/.github/workflows/valgrind.yml +++ b/.github/workflows/valgrind.yml @@ -33,18 +33,15 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libboost-dev libc6-dev-i386 libc6-dbg + # Install a newer version than the one in APT sudo snap install --classic valgrind - - name: Create build environment - run: mkdir ${{github.workspace}}/build - - name: Configure CMake # Use a bash shell so we can use the same syntax for environment # variable access regardless of the host operating system shell: bash - working-directory: ${{github.workspace}}/build run: | - cmake "$GITHUB_WORKSPACE" "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ + cmake -B build "$GITHUB_WORKSPACE" "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" \ "-DSTANDALONE=ON" "-DAVX2=$AVX2" - name: Build diff --git a/CMakeLists.txt b/CMakeLists.txt index 18ab22ee..d5d64b20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,23 +305,26 @@ message(STATUS "SANITIZER_ENV: ${SANITIZER_ENV}") option(STATIC_ANALYSIS "Enable compiler static analysis") -if(MSVC AND is_clang) - message(STATUS "Not enabling IPO/LTO due to MSVC LLVM not supporting it") -elseif(is_clang AND SANITIZE_ADDRESS AND CMAKE_CXX_COMPILER_VERSION - VERSION_GREATER_EQUAL 17.0) - # /usr/bin/ld: error: Failed to link module - # ../libunodb_qsbr.a.llvm.3080.qsbr.cpp: Expected at most one ThinLTO module - # per bitcode file - # ... - message(STATUS - "Not enabling IPO/LTO due to LLVM clang 17 w/ AddressSanitizer bug") -else() - include(CheckIPOSupported) - check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_SUPPORT_ERROR LANGUAGES CXX) - if(IPO_SUPPORTED) - message(STATUS "Enabling IPO/LTO for release config") +if(STANDALONE) + if(MSVC AND is_clang) + message(STATUS "Not enabling IPO/LTO due to MSVC LLVM not supporting it") + elseif(is_clang AND SANITIZE_ADDRESS AND CMAKE_CXX_COMPILER_VERSION + VERSION_GREATER_EQUAL 17.0) + # /usr/bin/ld: error: Failed to link module + # ../libunodb_qsbr.a.llvm.3080.qsbr.cpp: Expected at most one ThinLTO module + # per bitcode file + # ... + message(STATUS + "Not enabling IPO/LTO due to LLVM clang 17 w/ AddressSanitizer bug") else() - message(STATUS "IPO/LTO is not supported: ${IPO_SUPPORT_ERROR}") + include(CheckIPOSupported) + check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_SUPPORT_ERROR LANGUAGES + CXX) + if(IPO_SUPPORTED) + message(STATUS "Enabling IPO/LTO for release config") + else() + message(STATUS "IPO/LTO is not supported: ${IPO_SUPPORT_ERROR}") + endif() endif() endif() @@ -403,7 +406,8 @@ option(TESTS "Build tests, including fuzz ones if DeepState is available" ON) option(BENCHMARKS "Build benchmarks" ${STANDALONE}) -if(TESTS OR BENCHMARKS) +if((STANDALONE OR NOT TARGET GTest::gtest_main + OR NOT TARGET benchmark::benchmark) AND (TESTS OR BENCHMARKS)) string(REPLACE ";" " " CXX_FLAGS_FOR_SUBDIR_STR "${SANITIZER_CXX_FLAGS}") if(MSVC) string(REPLACE ";" " " MSVC_WARNING_FLAGS_FOR_SUBDIR_STR_TMP @@ -449,15 +453,18 @@ function(GLOBAL_CXX_TARGET_PROPERTIES TARGET) endfunction() if(TESTS) - # For Windows: Prevent overriding the parent project's compiler/linker settings - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + if (STANDALONE OR NOT TARGET GTest::gtest_main) + # For Windows: Prevent overriding the parent project's compiler/linker + # settings + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - ADD_CXX_FLAGS_FOR_SUBDIR() - add_subdirectory(3rd_party/googletest) - RESTORE_CXX_FLAGS_FOR_SUBDIR() + ADD_CXX_FLAGS_FOR_SUBDIR() + add_subdirectory(3rd_party/googletest) + RESTORE_CXX_FLAGS_FOR_SUBDIR() - global_cxx_target_properties(gtest) - global_cxx_target_properties(gtest_main) + global_cxx_target_properties(gtest) + global_cxx_target_properties(gtest_main) + endif() # Do not build DeepState: # - under Windows as it's not supported @@ -466,7 +473,8 @@ if(TESTS) # - with GCC under macOS due to # https://github.com/trailofbits/deepstate/issues/374 # - under macOS with ASan or TSan enabled - if(NOT (is_darwin AND (is_gxx OR SANITIZE_ADDRESS OR SANITIZE_THREAD)) + if(STANDALONE + AND NOT (is_darwin AND (is_gxx OR SANITIZE_ADDRESS OR SANITIZE_THREAD)) AND NOT is_windows AND is_x86_64) CHECK_INCLUDE_FILE(stdio.h CAN_BUILD_32BIT -m32) @@ -517,33 +525,35 @@ if(TESTS) endif() if(BENCHMARKS) - set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL - "Suppressing Google Benchmark tests" FORCE) - set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL - "Suppressing Google Benchmark installation" FORCE) - - if(IPO_SUPPORTED) - if(is_debug) - # It seems that Google Benchmark does not support multi-configuration - # generators if LTO is enabled - message(STATUS "Disabling LTO for Google Benchmark due to debug build") - elseif(is_apple_clang) - message(STATUS - "Disabling LTO for Google Benchmark because Apple clang is not \ - supported") - else() - set(BENCHMARK_ENABLE_LTO ON CACHE BOOL "Enabling LTO for Google Benchmark" - FORCE) - message(STATUS "Enabling LTO for Google Benchmark") + if(STANDALONE OR NOT TARGET benchmark::benchmark) + set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL + "Suppressing Google Benchmark tests" FORCE) + set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL + "Suppressing Google Benchmark installation" FORCE) + + if(IPO_SUPPORTED) + if(is_debug) + # It seems that Google Benchmark does not support multi-configuration + # generators if LTO is enabled + message(STATUS "Disabling LTO for Google Benchmark due to debug build") + elseif(is_apple_clang) + message(STATUS + "Disabling LTO for Google Benchmark because Apple clang is not \ + supported") + else() + set(BENCHMARK_ENABLE_LTO ON CACHE BOOL + "Enabling LTO for Google Benchmark" FORCE) + message(STATUS "Enabling LTO for Google Benchmark") + endif() endif() - endif() - ADD_CXX_FLAGS_FOR_SUBDIR() - add_subdirectory(3rd_party/benchmark) - RESTORE_CXX_FLAGS_FOR_SUBDIR() + ADD_CXX_FLAGS_FOR_SUBDIR() + add_subdirectory(3rd_party/benchmark) + RESTORE_CXX_FLAGS_FOR_SUBDIR() - global_cxx_target_properties(benchmark) - global_cxx_target_properties(benchmark_main) + global_cxx_target_properties(benchmark) + global_cxx_target_properties(benchmark_main) + endif() # Add benchmark_include_dirs by target_include_directories(... SYSTEM ...) # before target_link_libraries so that benchmark headers are included through @@ -643,19 +653,21 @@ function(COMMON_TARGET_PROPERTIES TARGET) set_target_properties(${TARGET} PROPERTIES CXX_EXTENSIONS OFF) global_cxx_target_properties(${TARGET}) target_compile_definitions(${TARGET} PUBLIC + # Features "$<${is_standalone}:UNODB_DETAIL_STANDALONE>" "$<${use_boost_stacktrace}:UNODB_DETAIL_BOOST_STACKTRACE>" "$<${with_stats}:UNODB_DETAIL_WITH_STATS>" "UNODB_SPINLOCK_LOOP_VALUE=${SPINLOCK_LOOP_VALUE}") + target_compile_options(${TARGET} PUBLIC + # Architecture + "$<${is_x86_64_any_msvc}:$>" + "$<${is_not_windows_x86_64}:$>") target_compile_options(${TARGET} PRIVATE "${SANITIZER_CXX_FLAGS}" "$<${is_msvc}:${MSVC_CXX_FLAGS}>" "$<${is_any_msvc}:${ANY_MSVC_CXX_FLAGS}>" "$<${is_not_windows}:${UNIX_CXX_FLAGS}>" "$<${is_clang_ge_14_not_windows}:${CLANG_GE_14_CXX_FLAGS}>" - # Architecture - "$<${is_x86_64_any_msvc}:$>" - "$<${is_not_windows_x86_64}:$>" # Warnings "$<${fatal_warnings_on}:$>" "$<${is_any_msvc}:${MSVC_CXX_WARNING_FLAGS}>" @@ -758,7 +770,9 @@ endif() set(VALGRIND_COMMAND "valgrind" "--error-exitcode=1" "--leak-check=full" "--trace-children=yes" "-v") -add_custom_target(valgrind DEPENDS valgrind_benchmarks valgrind_examples) +# If tests and/or benchmarks are enabled, their Valgrind targets will become +# dependencies of the main Valgrind target. +add_custom_target(valgrind) if(TESTS) add_dependencies(valgrind valgrind_tests) @@ -789,8 +803,6 @@ if(BENCHMARKS) add_subdirectory(benchmark) endif() -add_subdirectory(examples) - if(STANDALONE) set(BIN_DIR_CDB "${CMAKE_BINARY_DIR}/compile_commands.json") set(SRC_DIR_CDB "${CMAKE_SOURCE_DIR}/compile_commands.json") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6e37fcab..2df2a2be 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,23 +1,50 @@ -# Copyright 2024 Laurynas Biveinis +# Copyright 2024-2025 Laurynas Biveinis +cmake_minimum_required(VERSION 3.16) + +# This is a top-level CMake script and not an include of ../CMakeLists.txt. In +# fact, this one includes the one in the parent directory to show how another +# project can integrate UnoDB in its build. + +project(unodb-examples VERSION 0.1 + DESCRIPTION "unodb key-value store library examples" + HOMEPAGE_URL "https://github.com/laurynas-biveinis/unodb" LANGUAGES CXX) + +option(TESTS "Find Google Test in the parent project for UnoDB to use" ON) +option(BENCHMARKS "Find Google Benchmark in the parent project for UnoDB to use" + ON) + +# Search for Google Test and Google Benchmark before including UnoDB +if(TESTS) + find_package(GTest) +endif() +if(BENCHMARKS) + find_package(benchmark) +endif() + +# The TESTS and BENCHMARKS options will be passed to UnoDB too to configure the +# corresponding build parts. The parent project may also have different names or +# completely different logic, in which case the UnoDB options have to be set up +# explicitly. +add_subdirectory(.. unodb) add_executable(example_art example_art.cpp) -common_target_properties(example_art) target_link_libraries(example_art PRIVATE unodb) add_executable(example_art_stats example_art_stats.cpp) -common_target_properties(example_art_stats) target_link_libraries(example_art_stats PRIVATE unodb) add_executable(example_olc_art example_olc_art.cpp) -common_target_properties(example_olc_art) target_link_libraries(example_olc_art PRIVATE unodb) add_custom_target(examples - env ${SANITIZER_ENV} ./example_art - COMMAND env ${SANITIZER_ENV} ./example_art_stats - COMMAND env ${SANITIZER_ENV} ./example_olc_art + env ./example_art + COMMAND env ./example_art_stats + COMMAND env ./example_olc_art DEPENDS example_art example_art_stats example_olc_art) +set(VALGRIND_COMMAND "valgrind" "--error-exitcode=1" "--leak-check=full" + "--trace-children=yes" "-v") + add_custom_target(valgrind_examples COMMAND ${VALGRIND_COMMAND} ./example_art COMMAND ${VALGRIND_COMMAND} ./example_art_stats diff --git a/examples/CMakePresets.json b/examples/CMakePresets.json new file mode 100644 index 00000000..185192a7 --- /dev/null +++ b/examples/CMakePresets.json @@ -0,0 +1,93 @@ +{ + "version": 2, + "cmakeMinimumRequired": { + "major": 3, + "minor": 20, + "patch": 0 + }, + "configurePresets": [ + { + "name": "base-msvc", + "hidden": true, + "binaryDir": "${sourceDir}/build-examples/${presetName}", + "generator": "Ninja", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" + } + }, + { + "name": "base-msvc-llvm", + "hidden": true, + "inherits": "base-msvc", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang-cl", + "CMAKE_CXX_COMPILER": "clang-cl" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "intelliSenseMode": "windows-clang-x64" + } + } + }, + { + "name": "release", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "debug", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "msvc-debug", + "inherits": [ + "base-msvc", + "debug" + ] + }, + { + "name": "msvc-release", + "inherits": [ + "base-msvc", + "release" + ] + }, + { + "name": "msvc-llvm-debug", + "inherits": [ + "base-msvc-llvm", + "debug" + ] + }, + { + "name": "msvc-llvm-release", + "inherits": [ + "base-msvc-llvm", + "release" + ] + } + ], + "buildPresets": [ + { + "name": "msvc-debug", + "configurePreset": "msvc-debug" + }, + { + "name": "msvc-release", + "configurePreset": "msvc-release" + }, + { + "name": "msvc-llvm-debug", + "configurePreset": "msvc-llvm-debug" + }, + { + "name": "msvc-llvm-release", + "configurePreset": "msvc-llvm-release" + } + ] +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b1faeee6..44763644 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,32 +26,22 @@ endfunction() add_library(db_test_utils STATIC db_test_utils.hpp db_test_utils.cpp) common_target_properties(db_test_utils) -if(AWS_BUILD) - target_link_libraries(db_test_utils PUBLIC unodb Googletest::gtest Googletest::gtest_main Googlemock::gmock_main) -else() - target_link_libraries(db_test_utils PUBLIC unodb gtest_main gmock_main) -endif() +target_link_libraries(db_test_utils + PUBLIC unodb GTest::gtest_main GTest::gmock_main) set_clang_tidy_options(db_test_utils "${DO_CLANG_TIDY}") add_library(qsbr_test_utils STATIC qsbr_test_utils.hpp qsbr_test_utils.cpp qsbr_gtest_utils.hpp qsbr_gtest_utils.cpp) common_target_properties(qsbr_test_utils) -if(AWS_BUILD) - target_link_libraries(qsbr_test_utils PUBLIC Googletest::gtest Googletest::gtest_main) -else() - target_link_libraries(qsbr_test_utils PUBLIC gtest_main) -endif() +target_link_libraries(qsbr_test_utils PUBLIC GTest::gtest_main) target_link_libraries(qsbr_test_utils PRIVATE unodb_qsbr) set_clang_tidy_options(qsbr_test_utils "${DO_CLANG_TIDY}") function(ADD_TEST_TARGET TARGET) add_executable("${TARGET}" "${TARGET}.cpp") common_target_properties("${TARGET}") - if(AWS_BUILD) - target_link_libraries("${TARGET}" PRIVATE unodb_qsbr unodb_test Googletest::gtest Googletest::gtest_main) - else() - target_link_libraries("${TARGET}" PRIVATE unodb_qsbr unodb_test gtest_main) - endif() + target_link_libraries("${TARGET}" + PRIVATE unodb_qsbr unodb_test GTest::gtest_main) set_clang_tidy_options("${TARGET}" "${DO_CLANG_TIDY}") add_sanitized_test(NAME "${TARGET}" COMMAND "${TARGET}") endfunction()