Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci_coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ jobs:
--exclude-unreachable-branches \
--exclude-throw-branches \
--exclude-noncode-lines \
--merge-mode-functions separate \
-j \
--cobertura \
--output ${GITHUB_WORKSPACE}/build/coverage_report.xml
Expand Down
90 changes: 90 additions & 0 deletions .github/workflows/cron_no_optional_libraries.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# SPDX-FileCopyrightText: 2006-2025, Knut Reinert & Freie Universität Berlin
# SPDX-FileCopyrightText: 2016-2025, Knut Reinert & MPI für molekulare Genetik
# SPDX-License-Identifier: CC0-1.0

name: No Optional Libraries

on:
schedule:
- cron: "0 10 * * SUN"
workflow_dispatch:

concurrency:
group: no-optional-libraries-actions
cancel-in-progress: true

env:
SEQAN3_NO_VERSION_CHECK: 1
TZ: Europe/Berlin

defaults:
run:
shell: bash -Eeuxo pipefail {0}

jobs:
build:
name: ${{ matrix.build_type }} ${{ matrix.os }} (${{ matrix.zlib }}, ${{ matrix.bzip2 }}, ${{ matrix.cereal }})
runs-on: ${{ matrix.os }}
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
# Either all optional dependencies are disabled (true, true, true)
# Or only Bzip2 is disabled (false, true, false)
matrix:
os: [ubuntu-latest, macos-14]
build_type: [Release, Debug]
zlib: [true, false]
include:
- zlib: true
bzip2: true
cereal: true
- zlib: false
bzip2: true
cereal: false
- os: macos-14
compiler: clang-19
- os: ubuntu-latest
compiler: gcc-14
image: ghcr.io/seqan/gcc-14

container:
# If an image is defined for a matrix entry, use it.
# Otherwise, use the "empty"/'' image which means do not use a container at all.
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 ../test/analyse -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=${{ matrix.zlib }} \
-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=${{ matrix.bzip2 }} \
-DCMAKE_DISABLE_FIND_PACKAGE_cereal=${{ matrix.cereal }} \
-DSEQAN3_BENCHMARK_MIN_TIME=0.01s
make gtest_main benchmark_main

- name: Build tests
working-directory: build
run: make -k

- name: Run tests
working-directory: build
continue-on-error: true
id: test
run: ctest . -j --output-on-failure --no-tests=error

# Rerun failed tests with **one** thread. Some snippets touch the same file and fail in parallel.
- name: Rerun failed tests
if: steps.test.outcome == 'failure'
working-directory: build
run: ctest . -j1 --output-on-failure --no-tests=error --rerun-failed
1 change: 0 additions & 1 deletion cmake/cpack_install.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
# Only if creating the source package (`make package_source`):
# Copy dependency include directories into package's staging folder
if (CPACK_SOURCE_INSTALLED_DIRECTORIES)
file (COPY "@SEQAN3_CEREAL_INCLUDE_DIR@/" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/include/seqan3/vendor")
configure_file ("@CPM_DOWNLOAD_LOCATION@" "${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake" COPYONLY)
if ("@use_ccache_ADDED@" STREQUAL "YES")
configure_file ("@use_ccache_SOURCE_DIR@/ccache/CMakeLists.txt"
Expand Down
4 changes: 2 additions & 2 deletions cmake/package-lock.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ CPMDeclarePackage (cereal
NAME cereal
VERSION ${SEQAN3_CEREAL_VERSION}
GITHUB_REPOSITORY USCiLab/cereal
DOWNLOAD_ONLY TRUE
QUIET YES)
SYSTEM TRUE
OPTIONS "JUST_INSTALL_CEREAL ON" "CMAKE_MESSAGE_LOG_LEVEL WARNING")
# benchmark
set (SEQAN3_BENCHMARK_VERSION 1.9.1 CACHE STRING "" FORCE)
CPMDeclarePackage (benchmark
Expand Down
162 changes: 51 additions & 111 deletions cmake/seqan3-config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -134,32 +134,21 @@ else ()
endif ()

# ----------------------------------------------------------------------------
# Force-deactivate optional dependencies
# Force-(de)activate optional dependencies
# ----------------------------------------------------------------------------

# Cereal is auto-detected by default, i.e. used if found, not used if not found.
# You can optionally set a hard requirement so a build fails without cereal,
# or you can force-disable cereal even if present on the system.
option (SEQAN3_CEREAL "Require cereal and fail if not present." OFF)
option (SEQAN3_NO_CEREAL "Don't use cereal, even if present." OFF)
# https://cmake.org/cmake/help/latest/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.html
# https://cmake.org/cmake/help/latest/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName.html

if (SEQAN3_CEREAL AND SEQAN3_NO_CEREAL)
# this is always a user error, therefore we always error-out, even if SeqAn is not required
message (FATAL_ERROR "You may not specify SEQAN3_CEREAL and SEQAN3_NO_CEREAL at the same time.\n\
You can specify neither (use auto-detection), or specify either to force on/off.")
return ()
endif ()

if (SEQAN3_CEREAL)
set (SEQAN3_DEFINITIONS ${SEQAN3_DEFINITIONS} "-DSEQAN3_WITH_CEREAL=1")
elseif (SEQAN3_NO_CEREAL)
set (SEQAN3_DEFINITIONS ${SEQAN3_DEFINITIONS} "-DSEQAN3_WITH_CEREAL=0")
endif ()
## Example for deactivating
# cmake <path> -DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=TRUE
# -DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE
# -DCMAKE_DISABLE_FIND_PACKAGE_cereal=TRUE

# These two are "opt-in", because detected by CMake
# If you want to force-require these, just do find_package (zlib REQUIRED) before find_package (seqan3)
option (SEQAN3_NO_ZLIB "Don't use ZLIB, even if present." OFF)
option (SEQAN3_NO_BZIP2 "Don't use BZip2, even if present." OFF)
## Example for requiring
# cmake <path> -DCMAKE_REQUIRE_FIND_PACKAGE_ZLIB=TRUE
# -DCMAKE_REQUIRE_FIND_PACKAGE_BZip2=TRUE
# -DCMAKE_REQUIRE_FIND_PACKAGE_cereal=TRUE

# ----------------------------------------------------------------------------
# Check supported compilers
Expand All @@ -180,8 +169,8 @@ endif ()
set (THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package (Threads QUIET)

if (Threads_FOUND)
set (SEQAN3_LIBRARIES ${SEQAN3_LIBRARIES} Threads::Threads)
if (TARGET Threads::Threads)
list (APPEND SEQAN3_LIBRARIES Threads::Threads)
if ("${CMAKE_THREAD_LIBS_INIT}" STREQUAL "")
seqan3_config_print ("Thread support: builtin.")
else ()
Expand All @@ -192,114 +181,70 @@ else ()
endif ()

# ----------------------------------------------------------------------------
# Cereal dependency is optional, but may set as required
# Cereal dependency
# ----------------------------------------------------------------------------

if (NOT SEQAN3_NO_CEREAL)
find_path (SEQAN3_CEREAL_INCLUDE_DIR
NAMES cereal/version.hpp
HINTS "${SEQAN3_INCLUDE_DIR}/seqan3/vendor")
if (SEQAN3_HAS_CPM AND NOT CMAKE_DISABLE_FIND_PACKAGE_cereal)
CPMGetPackage (cereal)
else ()
find_package (cereal CONFIG QUIET)
endif ()

# 1) Check the vendor directory of SeqAn3. This directory exists for source packages and installed packages.
if (SEQAN3_CEREAL_INCLUDE_DIR)
if (SEQAN3_CEREAL)
seqan3_config_print ("Required dependency: Cereal found.")
else ()
seqan3_config_print ("Optional dependency: Cereal found.")
endif ()
set (SEQAN3_DEPENDENCY_INCLUDE_DIRS ${SEQAN3_CEREAL_INCLUDE_DIR} ${SEQAN3_DEPENDENCY_INCLUDE_DIRS})
# 2) Get package via CPM.
elseif (SEQAN3_HAS_CPM)
CPMGetPackage (cereal)

find_path (SEQAN3_CEREAL_INCLUDE_DIR
NAMES cereal/version.hpp
HINTS "${cereal_SOURCE_DIR}/include")

if (SEQAN3_CEREAL_INCLUDE_DIR)
if (SEQAN3_CEREAL)
seqan3_config_print ("Required dependency: Cereal found.")
else ()
seqan3_config_print ("Optional dependency: Cereal found.")
endif ()
set (SEQAN3_DEPENDENCY_INCLUDE_DIRS ${SEQAN3_CEREAL_INCLUDE_DIR} ${SEQAN3_DEPENDENCY_INCLUDE_DIRS})
else ()
if (SEQAN3_CEREAL)
seqan3_config_error ("The (optional) cereal library was marked as required, but wasn't found.")
else ()
seqan3_config_print ("Optional dependency: Cereal not found.")
endif ()
endif ()
else ()
if (SEQAN3_CEREAL)
seqan3_config_error ("The (optional) cereal library was marked as required, but wasn't found.")
else ()
seqan3_config_print ("Optional dependency: Cereal not found.")
endif ()
endif ()
if (TARGET cereal::cereal)
list (APPEND SEQAN3_LIBRARIES cereal::cereal)
seqan3_config_print ("Optional dependency: Cereal found.")
else ()
set (SEQAN3_DEFINITIONS ${SEQAN3_DEFINITIONS} "-DSEQAN3_HAS_CEREAL=0")
seqan3_config_print ("Optional dependency: Cereal not found.")
endif ()

# ----------------------------------------------------------------------------
# ZLIB dependency
# ----------------------------------------------------------------------------

if (NOT SEQAN3_NO_ZLIB)
find_package (ZLIB QUIET)
endif ()
find_package (ZLIB QUIET)

if (ZLIB_FOUND)
set (SEQAN3_LIBRARIES ${SEQAN3_LIBRARIES} ${ZLIB_LIBRARIES})
set (SEQAN3_DEPENDENCY_INCLUDE_DIRS ${SEQAN3_DEPENDENCY_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS})
set (SEQAN3_DEFINITIONS ${SEQAN3_DEFINITIONS} "-DSEQAN3_HAS_ZLIB=1")
if (TARGET ZLIB::ZLIB)
list (APPEND SEQAN3_LIBRARIES ZLIB::ZLIB)
seqan3_config_print ("Optional dependency: ZLIB-${ZLIB_VERSION_STRING} found.")
else ()
set (SEQAN3_DEFINITIONS ${SEQAN3_DEFINITIONS} "-DSEQAN3_HAS_ZLIB=0")
seqan3_config_print ("Optional dependency: ZLIB not found.")
endif ()

# ----------------------------------------------------------------------------
# BZip2 dependency
# ----------------------------------------------------------------------------

if (NOT SEQAN3_NO_BZIP2)
find_package (BZip2 QUIET)
endif ()
find_package (BZip2 QUIET)

if (NOT ZLIB_FOUND AND BZIP2_FOUND)
# NOTE (marehr): iostream_bzip2 uses the type `uInt`, which is defined by
# `zlib`. Therefore, `bzip2` will cause a ton of errors without `zlib`.
message (AUTHOR_WARNING "Disabling BZip2 [which was successfully found], "
"because ZLIB was not found. BZip2 depends on ZLIB.")
unset (BZIP2_FOUND)
endif ()

if (BZIP2_FOUND)
set (SEQAN3_LIBRARIES ${SEQAN3_LIBRARIES} ${BZIP2_LIBRARIES})
set (SEQAN3_DEPENDENCY_INCLUDE_DIRS ${SEQAN3_DEPENDENCY_INCLUDE_DIRS} ${BZIP2_INCLUDE_DIRS})
set (SEQAN3_DEFINITIONS ${SEQAN3_DEFINITIONS} "-DSEQAN3_HAS_BZIP2=1")
if (TARGET ZLIB::ZLIB AND TARGET BZip2::BZip2)
list (APPEND SEQAN3_LIBRARIES BZip2::BZip2)
seqan3_config_print ("Optional dependency: BZip2-${BZIP2_VERSION_STRING} found.")
else ()
set (SEQAN3_DEFINITIONS ${SEQAN3_DEFINITIONS} "-DSEQAN3_HAS_BZIP2=0")
seqan3_config_print ("Optional dependency: BZip2 not found.")
endif ()

if (NOT TARGET ZLIB::ZLIB AND TARGET BZip2::BZip2)
message (AUTHOR_WARNING "BZip2 was found but ZLIB was not found. BZip2 requires ZLIB.")
endif ()

# ----------------------------------------------------------------------------
# System dependencies
# ----------------------------------------------------------------------------

# librt
if ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
OR (${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD")
OR (${CMAKE_SYSTEM_NAME} STREQUAL "GNU"))
set (SEQAN3_LIBRARIES ${SEQAN3_LIBRARIES} rt)
find_library (SEQAN3_RT_LIB rt)
if (SEQAN3_RT_LIB)
list (APPEND SEQAN3_LIBRARIES ${SEQAN3_RT_LIB})
endif ()

# libexecinfo -- implicit
check_include_file_cxx (execinfo.h _SEQAN3_HAVE_EXECINFO)
mark_as_advanced (_SEQAN3_HAVE_EXECINFO)
if (_SEQAN3_HAVE_EXECINFO)
find_package (Backtrace QUIET)
if (TARGET Backtrace::Backtrace)
list (APPEND SEQAN3_LIBRARIES Backtrace::Backtrace)
seqan3_config_print ("Optional dependency: libexecinfo found.")
if ((${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") OR (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD"))
set (SEQAN3_LIBRARIES ${SEQAN3_LIBRARIES} execinfo elf)
endif ()
else ()
seqan3_config_print ("Optional dependency: libexecinfo not found.")
endif ()
Expand All @@ -308,19 +253,17 @@ endif ()
# Perform compilability test of platform.hpp (tests some requirements)
# ----------------------------------------------------------------------------

set (CXXSTD_TEST_SOURCE "#include <seqan3/core/platform.hpp>
int main() {}")

# using try_compile instead of check_cxx_source_compiles to capture output in case of failure
file (WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx" "${CXXSTD_TEST_SOURCE}\n")

# cmake-format: off
# Note: With CMake >= 3.25, the file WRITE can be removed, the second and third line in try_compile can be replaced by
# SOURCE_FROM_CONTENT "platform_test.cpp" "#include <seqan3/core/platform.hpp>\nint main() {}"
file (WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/platform_test.cpp"
"#include <seqan3/core/platform.hpp>\nint main() {}")

try_compile (SEQAN3_PLATFORM_TEST
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_INCLUDE_PATH};${SEQAN3_INCLUDE_DIR};${SEQAN3_DEPENDENCY_INCLUDE_DIRS}"
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/platform_test.cpp
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${SEQAN3_INCLUDE_DIR}"
COMPILE_DEFINITIONS ${SEQAN3_DEFINITIONS}
LINK_LIBRARIES ${SEQAN3_LIBRARIES}
CXX_STANDARD 23
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
Expand Down Expand Up @@ -358,7 +301,7 @@ foreach (package_var
endforeach ()

# propagate SEQAN3_INCLUDE_DIR into SEQAN3_INCLUDE_DIRS
set (SEQAN3_INCLUDE_DIRS ${SEQAN3_INCLUDE_DIR} ${SEQAN3_DEPENDENCY_INCLUDE_DIRS})
set (SEQAN3_INCLUDE_DIRS ${SEQAN3_INCLUDE_DIR})

# ----------------------------------------------------------------------------
# Export targets
Expand All @@ -371,9 +314,6 @@ if (SEQAN3_FOUND AND NOT TARGET seqan3::seqan3)
target_link_libraries (seqan3_seqan3 INTERFACE "${SEQAN3_LIBRARIES}")
# include seqan3/include/ as -I, because seqan3 should never produce warnings.
target_include_directories (seqan3_seqan3 INTERFACE "${SEQAN3_INCLUDE_DIR}")
# include everything except seqan3/include/ as -isystem, i.e.
# a system header which suppresses warnings of external libraries.
target_include_directories (seqan3_seqan3 SYSTEM INTERFACE "${SEQAN3_DEPENDENCY_INCLUDE_DIRS}")
add_library (seqan3::seqan3 ALIAS seqan3_seqan3)
endif ()

Expand Down
2 changes: 0 additions & 2 deletions cmake/seqan3-install.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,3 @@ install (FILES "${SEQAN3_CLONE_DIR}/cmake/seqan3-config.cmake" "${SEQAN3_CLONE_D

# install seqan3 header files in /include/seqan3
install (DIRECTORY "${SEQAN3_INCLUDE_DIR}/seqan3" TYPE INCLUDE)

install (DIRECTORY "${SEQAN3_CEREAL_INCLUDE_DIR}/cereal" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/seqan3/vendor")
4 changes: 2 additions & 2 deletions doc/cookbook/compression_threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: CC0-1.0

#if defined(SEQAN3_HAS_ZLIB)
#if SEQAN3_HAS_ZLIB
//![example]
# include <seqan3/io/all.hpp>

Expand All @@ -24,4 +24,4 @@ int main()
return 0;
}
//![example]
#endif // defined(SEQAN3_HAS_ZLIB)
#endif // SEQAN3_HAS_ZLIB
1 change: 1 addition & 0 deletions doc/howto/write_an_alphabet/dna2_semialphabet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

//! [semialphabet]
#include <cassert>
#include <iostream>

#include <seqan3/alphabet/concept.hpp> // alphabet concept checks

Expand Down
Loading
Loading