diff --git a/.github/workflows/ci_linux.yml b/.github/workflows/ci_linux.yml index cbb6561..b0d519d 100644 --- a/.github/workflows/ci_linux.yml +++ b/.github/workflows/ci_linux.yml @@ -1,140 +1,65 @@ -name: CI on Linux +# SPDX-FileCopyrightText: 2006-2023, Knut Reinert & Freie Universität Berlin +# SPDX-FileCopyrightText: 2016-2023, Knut Reinert & MPI für molekulare Genetik +# SPDX-License-Identifier: CC0-1.0 + +name: Linux on: push: branches: - - 'master' - 'main' pull_request: + workflow_dispatch: concurrency: group: linux-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.event_name != 'push' }} env: - CMAKE_VERSION: 3.10.3 - SEQAN3_NO_VERSION_CHECK: 1 TZ: Europe/Berlin defaults: run: - shell: bash -ex {0} + shell: bash -Eexuo pipefail {0} jobs: build: - name: ${{ matrix.name }} - runs-on: ubuntu-22.04 - timeout-minutes: 120 + runs-on: ubuntu-latest + name: ${{ matrix.compiler }} + if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch' strategy: - fail-fast: true + fail-fast: false matrix: - include: - - name: "Coverage gcc12" - cxx: "g++-12" - cc: "gcc-12" - build: coverage - build_type: Coverage - - - name: "gcc12" - cxx: "g++-12" - cc: "gcc-12" - build_type: Release - - - name: "gcc11" - cxx: "g++-11" - cc: "gcc-11" - build_type: Release - - - name: "gcc10" - cxx: "g++-10" - cc: "gcc-10" - build_type: Release - + compiler: ["clang-18", "clang-17", "gcc-14", "gcc-13", "gcc-12", "intel"] + container: + image: ghcr.io/seqan/${{ matrix.compiler }} + volumes: + - /home/runner:/home/runner steps: - name: Checkout - uses: actions/checkout@v3 - with: - path: needle - fetch-depth: 2 - submodules: recursive - - - name: Add package source - run: bash ./needle/lib/seqan3/.github/workflows/scripts/configure_apt.sh - - - name: Install CMake - run: bash ./needle/lib/seqan3/.github/workflows/scripts/install_cmake.sh - - - name: Install ccache - run: sudo apt-get install --yes ccache - - - name: Install compiler ${{ matrix.cxx }} - run: sudo apt-get install --yes ${{ matrix.cxx }} - - - name: Install lcov - if: matrix.build == 'coverage' - run: | - sudo apt-get install --yes lcov - sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-12 100 + uses: actions/checkout@v4 - name: Load ccache - uses: actions/cache@v3 + uses: actions/cache@v4 with: - path: .ccache - key: ${{ runner.os }}-${{ matrix.name }}-ccache-${{ github.ref }}-${{ github.run_number }} - # Restoring: From current branch, otherwise from base branch, otherwise from any branch. - restore-keys: | - ${{ runner.os }}-${{ matrix.name }}-ccache-${{ github.ref }} - ${{ runner.os }}-${{ matrix.name }}-ccache-${{ github.base_ref }} - ${{ runner.os }}-${{ matrix.name }}-ccache- - - - name: Tool versions - run: | - env cmake --version - env ${{ matrix.cxx }} --version + path: /home/runner/.ccache + save-always: true + key: ccache-${{ runner.os }}-${{ github.workflow }}-${{ matrix.compiler }}-${{ github.ref }} - name: Configure tests - env: - CXX: ${{ matrix.cxx }} - CC: ${{ matrix.cc }} run: | - mkdir build - cd build - cmake ../needle -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }} -Wno-interference-size" + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make gtest_main - name: Build tests - env: - CCACHE_BASEDIR: ${{ github.workspace }} - CCACHE_DIR: ${{ github.workspace }}/.ccache - CCACHE_COMPRESS: true - CCACHE_COMPRESSLEVEL: 6 - CCACHE_MAXSIZE: 500M - run: | - ccache -p || true - cd build - make -k -j2 api_test cli_test - ccache -s || true - - - name: Generate coverage baseline - if: matrix.build == 'coverage' + working-directory: build run: | - lcov --directory ./build/ --zerocounters - lcov --directory ./build/ --capture --initial --output-file ./build/coverage_report.baseline + ccache -z + make -k tests + ccache -svvx - name: Run tests - run: | - cd build - ctest . -j2 --output-on-failure + working-directory: build + run: ctest -j --output-on-failure --test-dir test - - name: Generate coverage report - if: matrix.build == 'coverage' - run: | - lcov --directory ./build/ --capture --output-file ./build/coverage_report.captured - lcov -a ./build/coverage_report.baseline -a ./build/coverage_report.captured --output-file ./build/coverage_report.total - lcov --remove ./build/coverage_report.total '/usr/*' '${{ github.workspace }}/needle/lib/*' '${{ github.workspace }}/needle/test/*' '${{ github.workspace }}/build/vendor/*' --output-file ./build/coverage_report - - - name: Submit coverage report - if: matrix.build == 'coverage' - uses: codecov/codecov-action@v2 - with: - files: ${{ github.workspace }}/build/coverage_report - root_dir: ${{ github.workspace }}/needle diff --git a/.github/workflows/ci_macos.yml b/.github/workflows/ci_macos.yml index 3e74e3b..bdd7397 100644 --- a/.github/workflows/ci_macos.yml +++ b/.github/workflows/ci_macos.yml @@ -1,115 +1,59 @@ -name: CI on macOS +# SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin +# SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik +# SPDX-License-Identifier: CC0-1.0 + +name: macOS on: push: branches: - - 'master' - 'main' pull_request: + workflow_dispatch: concurrency: group: macos-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.event_name != 'push' }} env: - CMAKE_VERSION: 3.10.3 - SEQAN3_NO_VERSION_CHECK: 1 TZ: Europe/Berlin defaults: run: - shell: bash -ex {0} + shell: bash -Eeuxo pipefail {0} jobs: build: - name: ${{ matrix.name }} - runs-on: macos-12 - timeout-minutes: 120 + name: ${{ matrix.compiler }} + runs-on: macos-14 + if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch' strategy: - fail-fast: true + fail-fast: false matrix: - include: - - name: "gcc12" - cxx: "g++-12" - cc: "gcc-12" - build_type: Release - - - name: "gcc11" - cxx: "g++-11" - cc: "gcc-11" - build_type: Release - - - name: "gcc10" - cxx: "g++-10" - cc: "gcc-10" - build_type: Release - + compiler: ["clang-18", "clang-17", "gcc-14", "gcc-13", "gcc-12"] steps: - name: Checkout - uses: actions/checkout@v3 - with: - path: needle - fetch-depth: 2 - submodules: recursive - - - name: Configure Homebrew - uses: Homebrew/actions/setup-homebrew@master + uses: actions/checkout@v4 - - name: Install CMake - run: bash ./needle/lib/seqan3/.github/workflows/scripts/install_cmake.sh - - - name: Install ccache - run: bash ./needle/lib/seqan3/.github/workflows/scripts/install_via_brew.sh ccache - - - name: Install compiler ${{ matrix.cxx }} - run: bash ./needle/lib/seqan3/.github/workflows/scripts/install_via_brew.sh gcc $(echo "${{ matrix.cxx }}" | sed "s/g++-//g") - - - name: Load ccache - uses: actions/cache@v3 + - name: Setup toolchain + uses: seqan/actions/setup-toolchain@main with: - path: .ccache - key: ${{ runner.os }}-${{ matrix.name }}-ccache-${{ github.ref }}-${{ github.run_number }} - # Restoring: From current branch, otherwise from base branch, otherwise from any branch. - restore-keys: | - ${{ runner.os }}-${{ matrix.name }}-ccache-${{ github.ref }} - ${{ runner.os }}-${{ matrix.name }}-ccache-${{ github.base_ref }} - ${{ runner.os }}-${{ matrix.name }}-ccache- - - - name: Tool versions - run: | - env cmake --version - env ${{ matrix.cxx }} --version - sudo xcode-select -s '/Applications/Xcode_13.4.1.app/Contents/Developer' # https://github.com/actions/runner-images/issues/6350 + compiler: ${{ matrix.compiler }} + ccache_size: 75M - name: Configure tests - env: - CXX: ${{ matrix.cxx }} - CC: ${{ matrix.cc }} run: | - mkdir build - cd build - cmake ../needle -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }} -Wno-interference-size" + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make gtest_main - - name: Build application - env: - CCACHE_BASEDIR: ${{ github.workspace }} - CCACHE_DIR: ${{ github.workspace }}/.ccache - CCACHE_COMPRESS: true - CCACHE_COMPRESSLEVEL: 6 - CCACHE_MAXSIZE: 500M + - name: Build tests + working-directory: build run: | - ccache -p || true - cd build - make -k -j3 - ccache -s || true + ccache -z + make -k tests + ccache -svvx - - name: Build and run tests - env: - CCACHE_BASEDIR: ${{ github.workspace }} - CCACHE_DIR: ${{ github.workspace }}/.ccache - CCACHE_COMPRESS: true - CCACHE_COMPRESSLEVEL: 6 - CCACHE_MAXSIZE: 500M - run: | - cd build - ctest . -j3 --output-on-failure + - name: Run tests + working-directory: build + run: ctest -j --output-on-failure --test-dir test diff --git a/.github/workflows/ci_misc.yml b/.github/workflows/ci_misc.yml deleted file mode 100644 index 7ea63ad..0000000 --- a/.github/workflows/ci_misc.yml +++ /dev/null @@ -1,137 +0,0 @@ -name: CI misc - -on: - push: - branches: - - 'master' - - 'main' - pull_request: - -concurrency: - group: misc-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -env: - SEQAN3_NO_VERSION_CHECK: 1 - TZ: Europe/Berlin - -defaults: - run: - shell: bash -ex {0} - -jobs: - build: - name: ${{ matrix.name }} - runs-on: ubuntu-22.04 - timeout-minutes: 120 - strategy: - fail-fast: false - matrix: - include: - - name: "Documentation" - build: documentation - build_threads: 2 - test_threads: 2 - cmake: 3.10.3 - doxygen: 1.9.4 - requires_toolchain: false - requires_ccache: false - skip_build_tests: true - skip_run_tests: false - - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - path: needle - fetch-depth: 2 - submodules: recursive - - - name: Add package source - run: bash ./needle/lib/seqan3/.github/workflows/scripts/configure_apt.sh - - - name: Install CMake - env: - BUILD: ${{ matrix.build }} - CMAKE_VERSION: ${{ matrix.cmake }} - run: bash ./needle/lib/seqan3/.github/workflows/scripts/install_cmake.sh - - - name: Install Doxygen - if: matrix.build == 'documentation' - env: - DOXYGEN_VERSION: ${{ matrix.doxygen }} - run: bash ./needle/lib/seqan3/.github/workflows/scripts/install_doxygen.sh - - - name: Install ccache - if: matrix.requires_ccache - run: sudo apt-get install --yes ccache - - - name: Install compiler ${{ matrix.cxx }} - if: matrix.requires_toolchain - run: sudo apt-get install --yes ${{ matrix.cxx }} - - - name: Load ccache - if: matrix.requires_ccache - uses: actions/cache@v3 - with: - path: .ccache - key: ${{ matrix.name }}-ccache-${{ github.ref }}-${{ github.run_number }} - # Restoring: From current branch, otherwise from base branch, otherwise from any branch. - restore-keys: | - ${{ matrix.name }}-ccache-${{ github.ref }} - ${{ matrix.name }}-ccache-${{ github.base_ref }} - ${{ matrix.name }}-ccache- - - - name: Tool versions - run: | - env cmake --version - env doxygen --version || true - env ${{ matrix.cxx }} --version || true - - - name: Configure tests - env: - CXX: ${{ matrix.cxx }} - CC: ${{ matrix.cc }} - run: | - mkdir build - cd build - cmake ../needle -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }} -Wno-interference-size" - - - name: Build tests - if: ${{!matrix.skip_build_tests}} - env: - CCACHE_BASEDIR: ${{ github.workspace }} - CCACHE_DIR: ${{ github.workspace }}/.ccache - CCACHE_COMPRESS: true - CCACHE_COMPRESSLEVEL: 6 - CCACHE_MAXSIZE: 500M - run: | - ccache -p || true - cd build - make -k -j${{ matrix.build_threads }} - ccache -s || true - - - name: Run tests - if: ${{!matrix.skip_run_tests}} - run: | - cd build - if [[ "${{ matrix.build }}" =~ ^(documentation)$ ]]; then - make -k -j2 doc 2>doxygen_warnings.txt - cat doxygen_warnings.txt - test ! -s doxygen_warnings.txt - else - ctest . -j${{ matrix.test_threads }} --output-on-failure - fi - - - name: Package documentation - if: matrix.build == 'documentation' - continue-on-error: true - run: tar -zcf documentation.tar.gz build - - - name: Upload documentation - if: matrix.build == 'documentation' - continue-on-error: true - uses: actions/upload-artifact@v3 - with: - name: documentation - path: documentation.tar.gz diff --git a/.github/workflows/ci_sanitizer.yml b/.github/workflows/ci_sanitizer.yml new file mode 100644 index 0000000..58f44f7 --- /dev/null +++ b/.github/workflows/ci_sanitizer.yml @@ -0,0 +1,99 @@ +# SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin +# SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik +# SPDX-License-Identifier: CC0-1.0 + +name: Sanitizer + +on: + schedule: + - cron: "0 6 * * SAT" + workflow_dispatch: + +concurrency: + group: sanitizer-actions + cancel-in-progress: true + +env: + TZ: Europe/Berlin + ASAN_OPTIONS: strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=1 + TSAN_OPTIONS: ignore_noninstrumented_modules=1 + UBSAN_OPTIONS: print_stacktrace=1 + +defaults: + run: + shell: bash -Eeuxo pipefail {0} + +jobs: + build: + name: ${{ matrix.name }} ${{ matrix.build_type }} ${{ matrix.os }} + runs-on: ${{ matrix.os }} + if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch' + strategy: + fail-fast: false + matrix: + name: [ASan, TSan, UBSan] + os: [ubuntu-latest, macos-14] + build_type: [Release, RelWithDebInfo, Debug] + exclude: + - name: "TSan" + os: macos-14 + include: + - name: "ASan" + os: ubuntu-latest + cxx_flags: "-fno-omit-frame-pointer -fsanitize=address -Wno-maybe-uninitialized" + + - name: "ASan" + os: macos-14 + cxx_flags: "-fno-omit-frame-pointer -fsanitize=address" + + - name: "TSan" + cxx_flags: "-fno-omit-frame-pointer -fsanitize=thread" + + - name: "UBSan" + os: ubuntu-latest + cxx_flags: "-fno-omit-frame-pointer -fsanitize=undefined,float-divide-by-zero" + + - name: "UBSan" + os: macos-14 + cxx_flags: "-fno-omit-frame-pointer -fsanitize=undefined,float-divide-by-zero,local-bounds,nullability -fno-sanitize=function -Wno-pass-failed" + + - os: macos-14 + compiler: clang-18 + + - os: ubuntu-latest + compiler: gcc-14 + image: ghcr.io/seqan/gcc-14 + + - name: "TSan" + os: ubuntu-latest + compiler: clang-18 + image: ghcr.io/seqan/clang-18 + container: + image: ${{ matrix.image || '' }} + volumes: + - /home/runner:/home/runner + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup compiler + if: contains(matrix.os, 'macos') + uses: seqan/actions/setup-compiler@main + with: + compiler: ${{ matrix.compiler }} + + - name: Configure tests + run: | + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }}" + make gtest_main + + - name: Build tests + working-directory: build + run: make -k tests + + - name: Run tests + working-directory: build + run: ctest -j1 --output-on-failure --test-dir test + diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index a31955e..0000000 --- a/.gitmodules +++ /dev/null @@ -1,7 +0,0 @@ -[submodule "lib/seqan3"] - path = lib/seqan3 - url = https://github.com/seqan/seqan3.git - branch = master -[submodule "lib/robin-hood-hashing"] - path = lib/robin-hood-hashing - url = https://github.com/martinus/robin-hood-hashing diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fb36bf..37bf56a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,52 +1,45 @@ -cmake_minimum_required (VERSION 3.10) - -## CUSTOMISE +cmake_minimum_required (VERSION 3.25) # Define the application name and version. -project (needle VERSION 1.0.3) - -## BUILD - -# Make Release default build type -if (NOT CMAKE_BUILD_TYPE) - set (CMAKE_BUILD_TYPE Release CACHE STRING - "Choose the type of build, options are: Debug Release Coverage RelWithDebInfo MinSizeRel." - FORCE) -endif () - -# Specify the directories where to store the built archives, libraries and executables -set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") -set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") -set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") - -# Messages -string (ASCII 27 Esc) -set (FontBold "${Esc}[1m") -set (FontReset "${Esc}[m") - -# Dependency: SeqAn3. -find_package (SeqAn3 QUIET REQUIRED HINTS lib/seqan3/build_system) - -# Use ccache. -include ("${SEQAN3_CLONE_DIR}/test/cmake/seqan3_require_ccache.cmake") -seqan3_require_ccache () - -# Dependency: robin_hood. -add_subdirectory(lib/robin-hood-hashing) - -# Add the application. +project (needle + LANGUAGES CXX + VERSION 1.0.3 + DESCRIPTION "A fast and space-efficient pre-filter for estimating the quantification of very large collections of nucleotide sequences" +) + +# This allows including `*.cmake` files from the `cmake` directory without specifying the full path. +list (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") + +# Specify the directories where to store the built archives, libraries and executables. +include (output_directories) + +# Add packages. +# We use CPM for package management: https://github.com/cpm-cmake/CPM.cmake +# The added packages (e.g., hibf, sharg, seqan3) are defined in the `cmake/package-lock.cmake` file. +include (CPM) +CPMUsePackageLock (${CMAKE_CURRENT_LIST_DIR}/cmake/package-lock.cmake) + +# Use ccache if available. This speeds up the build process by caching files that have been compiled before. +CPMGetPackage (use_ccache) +CPMGetPackage (seqan3) +CPMGetPackage (robin-hood) + +# Add the application. This will include `src/CMakeLists.txt`. add_subdirectory (src) -message (STATUS "${FontBold}You can run `make` to build the application.${FontReset}") +# An option to disable configuring and building the tests. Tests are enabled by default. +# If your project-name (line 8 of this file) is `app-template`, the option will be `app-template_TEST`. +# It can be used when calling CMake: `cmake .. -Dapp-template_TEST=OFF`. +# It is good practice to allow disabling tests. If another project includes your application, +# it might not want to build your tests. +option (${PROJECT_NAME}_TEST "Enable testing for ${PROJECT_NAME}." ON) -## DOCUMENTATION - -add_subdirectory (doc EXCLUDE_FROM_ALL) - -## TEST +if (${PROJECT_NAME}_TEST) + # Add the tests. This will include `test/CMakeLists.txt`. + add_subdirectory (test EXCLUDE_FROM_ALL) +endif () -enable_testing () -add_subdirectory (test EXCLUDE_FROM_ALL) +# add_subdirectory (doc EXCLUDE_FROM_ALL) ## PACKAGE # Change version in this file: project (needle VERSION x.x.x) @@ -74,15 +67,15 @@ add_subdirectory (test EXCLUDE_FROM_ALL) # This should be done in a clean directory, because everything in the needle checkout will be packaged, i.e., also # local build directories if they exist. -set (CPACK_GENERATOR "TXZ") +# set (CPACK_GENERATOR "TXZ") -set (CPACK_PACKAGE_VERSION "${needle_VERSION}") -set (CPACK_PACKAGE_VENDOR "seqan") -set (CPACK_PACKAGE_CHECKSUM "SHA256") -set (CPACK_RESOURCE_FILE_LICENSE "${needle_SOURCE_DIR}/LICENSE.md") -set (CPACK_RESOURCE_FILE_README "${needle_SOURCE_DIR}/README.md") +# set (CPACK_PACKAGE_VERSION "${needle_VERSION}") +# set (CPACK_PACKAGE_VENDOR "seqan") +# set (CPACK_PACKAGE_CHECKSUM "SHA256") +# set (CPACK_RESOURCE_FILE_LICENSE "${needle_SOURCE_DIR}/LICENSE.md") +# set (CPACK_RESOURCE_FILE_README "${needle_SOURCE_DIR}/README.md") -set (CPACK_SOURCE_GENERATOR "TXZ") -set (CPACK_SOURCE_IGNORE_FILES "\\\\.git($|/)") +# set (CPACK_SOURCE_GENERATOR "TXZ") +# set (CPACK_SOURCE_IGNORE_FILES "\\\\.git($|/)") -include (CPack) +# include (CPack) diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in deleted file mode 100644 index c6247af..0000000 --- a/CMakeLists.txt.in +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 2.8.2) - -project(googletest-download NONE) - -include(ExternalProject) -ExternalProject_Add(googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG master - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake new file mode 100644 index 0000000..baf2d8c --- /dev/null +++ b/cmake/CPM.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors + +set(CPM_DOWNLOAD_VERSION 0.40.2) +set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d") + +if(CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif() + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} +) + +include(${CPM_DOWNLOAD_LOCATION}) diff --git a/cmake/output_directories.cmake b/cmake/output_directories.cmake new file mode 100644 index 0000000..0fc7229 --- /dev/null +++ b/cmake/output_directories.cmake @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin +# SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik +# SPDX-License-Identifier: CC0-1.0 + +set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") +set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") +set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") diff --git a/cmake/package-lock.cmake b/cmake/package-lock.cmake new file mode 100644 index 0000000..e13cd33 --- /dev/null +++ b/cmake/package-lock.cmake @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: 2006-2023, Knut Reinert & Freie Universität Berlin +# SPDX-FileCopyrightText: 2016-2023, Knut Reinert & MPI für molekulare Genetik +# SPDX-License-Identifier: CC0-1.0 + +# CPM Package Lock +# This file should be committed to version control + +# seqan3 +set (NEEDLE_SEQAN3_VERSION d4a7c88fde0311e12e98e7822da772b99c887cb5) +CPMDeclarePackage (seqan3 + NAME seqan3 + GIT_TAG ${NEEDLE_SEQAN3_VERSION} + GITHUB_REPOSITORY seqan/seqan3 + SYSTEM TRUE + EXCLUDE_FROM_ALL TRUE + OPTIONS "INSTALL_SEQAN3 OFF" "CMAKE_MESSAGE_LOG_LEVEL WARNING" +) + +# googletest +set (NEEDLE_GOOGLETEST_VERSION 1.15.2) +CPMDeclarePackage (googletest + NAME googletest + VERSION ${NEEDLE_GOOGLETEST_VERSION} + GITHUB_REPOSITORY google/googletest + SYSTEM TRUE + OPTIONS "BUILD_GMOCK OFF" "INSTALL_GTEST OFF" "CMAKE_MESSAGE_LOG_LEVEL WARNING" + "CMAKE_CXX_STANDARD 20" +) + +# robin-hood-hashing +set (NEEDLE_ROBIN_HOOD_VERSION 7697343363af4cc3f42cab17be49e6af9ab181e2) +CPMDeclarePackage (robin-hood + NAME robin-hood + GIT_TAG ${NEEDLE_ROBIN_HOOD_VERSION} + GITHUB_REPOSITORY martinus/robin-hood-hashing + SYSTEM TRUE + EXCLUDE_FROM_ALL TRUE + OPTIONS "CMAKE_MESSAGE_LOG_LEVEL WARNING" +) + +# use_ccache +set (USE_CCACHE_VERSION d2a54ef555b6fc2d496a4c9506dbeb7cf899ce37) +CPMDeclarePackage (use_ccache + NAME use_ccache + GIT_TAG ${USE_CCACHE_VERSION} + GITHUB_REPOSITORY seqan/cmake-scripts + SOURCE_SUBDIR ccache + SYSTEM TRUE + EXCLUDE_FROM_ALL TRUE +) diff --git a/cmake/test/add_local_data.cmake b/cmake/test/add_local_data.cmake new file mode 100644 index 0000000..d8cf413 --- /dev/null +++ b/cmake/test/add_local_data.cmake @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin +# SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik +# SPDX-License-Identifier: CC0-1.0 + +set (DATASOURCES_DATA_DIR "${${PROJECT_NAME}_SOURCE_DIR}/test/data") + +file (GLOB_RECURSE datasources + LIST_DIRECTORIES false + RELATIVE ${DATASOURCES_DATA_DIR} + CONFIGURE_DEPENDS ${DATASOURCES_DATA_DIR}/* +) +list (REMOVE_ITEM datasources datasources.cmake README.md) +list (FILTER datasources EXCLUDE REGEX "\.license") + +foreach (datasource IN LISTS datasources) + get_filename_component (datasource_name "${datasource}" NAME) + file (SHA256 ${DATASOURCES_DATA_DIR}/${datasource} datasource_hash) + + declare_datasource (FILE ${datasource_name} + URL ${DATASOURCES_DATA_DIR}/${datasource} + URL_HASH SHA256=${datasource_hash} + ) +endforeach () diff --git a/cmake/test/config.cmake b/cmake/test/config.cmake new file mode 100644 index 0000000..90652fe --- /dev/null +++ b/cmake/test/config.cmake @@ -0,0 +1,66 @@ +# SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin +# SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik +# SPDX-License-Identifier: CC0-1.0 + +CPMGetPackage (googletest) + +list (APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure") # Must be before `enable_testing ()`. +enable_testing () + +# Set directories for test output files, input data and binaries. +file (MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/output) +add_definitions (-DOUTPUTDIR=\"${CMAKE_CURRENT_BINARY_DIR}/output/\") +add_definitions (-DDATADIR=\"${CMAKE_CURRENT_BINARY_DIR}/data/\") +add_definitions (-DBINDIR=\"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/\") +add_definitions (-DAPPNAME=\"${PROJECT_NAME}\") + +# Add the test interface library. +if (NOT TARGET ${PROJECT_NAME}_test) + add_library (${PROJECT_NAME}_test INTERFACE) + target_compile_options (${PROJECT_NAME}_lib PUBLIC "-pedantic" "-Wall" "-Wextra" "-Werror") + + + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + # Disable bogus warnings in GCC12. + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13) + target_compile_options (${PROJECT_NAME}_test INTERFACE "-Wno-array-bounds" "-Wno-stringop-overread") + endif () + + # Warn about failed return value optimization. + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 14) + target_compile_options (${PROJECT_NAME}_lib PUBLIC "-Wnrvo") + endif () + endif () + + target_link_libraries (${PROJECT_NAME}_test INTERFACE "${PROJECT_NAME}_lib" "GTest::gtest_main") + + # !Workaround: Get seqan3 test include dir from seqan3 target + find_path (SEQAN3_TEST_INCLUDE_DIR + NAMES seqan3/test/tmp_directory.hpp + HINTS "${seqan3_SOURCE_DIR}/test/include" + ) + target_include_directories (${PROJECT_NAME}_test SYSTEM INTERFACE "${SEQAN3_TEST_INCLUDE_DIR}") + + add_library (${PROJECT_NAME}::test ALIAS ${PROJECT_NAME}_test) +endif () + +# Add the check target that builds and runs tests. +add_custom_target (check COMMAND ${CMAKE_CTEST_COMMAND} ${CMAKE_CTEST_ARGUMENTS}) +add_custom_target (tests) + +macro (add_app_test test_filename) + file (RELATIVE_PATH source_file "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/${test_filename}") + get_filename_component (target "${source_file}" NAME_WE) + + add_executable (${target} ${test_filename}) + target_link_libraries (${target} ${PROJECT_NAME}::test) + + add_dependencies (${target} ${PROJECT_NAME}) + add_dependencies (check ${target}) + add_dependencies (tests ${target}) + + add_test (NAME ${target} COMMAND ${target}) + + unset (source_file) + unset (target) +endmacro () diff --git a/cmake/test/declare_datasource.cmake b/cmake/test/declare_datasource.cmake new file mode 100644 index 0000000..7955c4b --- /dev/null +++ b/cmake/test/declare_datasource.cmake @@ -0,0 +1,69 @@ +# SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin +# SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik +# SPDX-License-Identifier: CC0-1.0 + +include (ExternalProject) + +# Example call: +# +# ```cmake +# declare_datasource ( +# FILE pdb100d.ent.gz # build/data/pdb100d.ent.gz +# URL ftp://ftp.wwpdb.org/pub/pdb/data/structures/divided/pdb/00/pdb100d.ent.gz # 16KiloByte +# URL_HASH SHA256=c2b8f884568b07f58519966e256e2f3aa440508e8013bd10e0ee338e138e62a0) +# ``` +# +# Options: +# +# declare_datasource (FILE URL [...] [URL_HASH =] [