|
| 1 | +# SPDX-License-Identifier: GPL-3.0-or-later; (c) 2025 Andrew D Smith (author) |
| 2 | +#[=======================================================================[.rst: |
| 3 | +FindHTSLIB |
| 4 | +-------- |
| 5 | +
|
| 6 | +Find the native HTSLib includes and library. Based on the ZLIB module. |
| 7 | +
|
| 8 | +#]=======================================================================] |
| 9 | + |
| 10 | +cmake_policy(PUSH) |
| 11 | +cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n> |
| 12 | + |
| 13 | +if(HTSLIB_FIND_COMPONENTS AND NOT HTSLIB_FIND_QUIETLY) |
| 14 | + message(AUTHOR_WARNING |
| 15 | + "HTSLib does not provide any COMPONENTS. Calling\n" |
| 16 | + " find_package(HTSLIB COMPONENTS ...)\n" |
| 17 | + "will always fail." |
| 18 | + ) |
| 19 | +endif() |
| 20 | + |
| 21 | +set(_HTSLIB_SEARCHES) |
| 22 | + |
| 23 | +# Search HTSLIB_ROOT first if it is set. |
| 24 | +if(HTSLIB_ROOT) |
| 25 | + set(_HTSLIB_SEARCH_ROOT PATHS ${HTSLIB_ROOT} NO_DEFAULT_PATH) |
| 26 | + list(APPEND _HTSLIB_SEARCHES _HTSLIB_SEARCH_ROOT) |
| 27 | +endif() |
| 28 | + |
| 29 | +# Normal search. |
| 30 | +# Windows stuff |
| 31 | +set(_HTSLIB_x86 "(x86)") |
| 32 | +set(_HTSLIB_SEARCH_NORMAL |
| 33 | + PATHS "$ENV{ProgramFiles}/htslib" |
| 34 | + "$ENV{ProgramFiles${_HTSLIB_x86}}/htslib") |
| 35 | +unset(_HTSLIB_x86) |
| 36 | +list(APPEND _HTSLIB_SEARCHES _HTSLIB_SEARCH_NORMAL) |
| 37 | + |
| 38 | +if(HTSLIB_USE_STATIC_LIBS) |
| 39 | + set(HTSLIB_NAMES hts) |
| 40 | + set(HTSLIB_NAMES_DEBUG hts) |
| 41 | +else() |
| 42 | + set(HTSLIB_NAMES hts) |
| 43 | + set(HTSLIB_NAMES_DEBUG hts) |
| 44 | +endif() |
| 45 | + |
| 46 | +# Try each search configuration. |
| 47 | +foreach(search ${_HTSLIB_SEARCHES}) |
| 48 | + find_path(HTSLIB_INCLUDE_DIR NAMES htslib ${${search}} PATH_SUFFIXES include) |
| 49 | +endforeach() |
| 50 | + |
| 51 | +# Allow HTSLIB_LIBRARY to be set manually, as the location of the htslib library |
| 52 | +if(NOT HTSLIB_LIBRARY) |
| 53 | + if(DEFINED CMAKE_FIND_LIBRARY_PREFIXES) |
| 54 | + set(_htslib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}") |
| 55 | + else() |
| 56 | + set(_htslib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES) |
| 57 | + endif() |
| 58 | + if(DEFINED CMAKE_FIND_LIBRARY_SUFFIXES) |
| 59 | + set(_htslib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}") |
| 60 | + else() |
| 61 | + set(_htslib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) |
| 62 | + endif() |
| 63 | + # Prefix/suffix of the win32/Makefile.gcc build |
| 64 | + if(WIN32) |
| 65 | + list(APPEND CMAKE_FIND_LIBRARY_PREFIXES "" "lib") |
| 66 | + list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a") |
| 67 | + endif() |
| 68 | + # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES |
| 69 | + if(HTSLIB_USE_STATIC_LIBS) |
| 70 | + if(WIN32) |
| 71 | + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) |
| 72 | + else() |
| 73 | + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) |
| 74 | + endif() |
| 75 | + endif() |
| 76 | + |
| 77 | + foreach(search ${_HTSLIB_SEARCHES}) |
| 78 | + find_library(HTSLIB_LIBRARY_RELEASE NAMES ${HTSLIB_NAMES} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) |
| 79 | + find_library(HTSLIB_LIBRARY_DEBUG NAMES ${HTSLIB_NAMES_DEBUG} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) |
| 80 | + endforeach() |
| 81 | + |
| 82 | + # Restore the original find library ordering |
| 83 | + if(DEFINED _htslib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) |
| 84 | + set(CMAKE_FIND_LIBRARY_SUFFIXES "${_htslib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}") |
| 85 | + else() |
| 86 | + set(CMAKE_FIND_LIBRARY_SUFFIXES) |
| 87 | + endif() |
| 88 | + if(DEFINED _htslib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES) |
| 89 | + set(CMAKE_FIND_LIBRARY_PREFIXES "${_htslib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES}") |
| 90 | + else() |
| 91 | + set(CMAKE_FIND_LIBRARY_PREFIXES) |
| 92 | + endif() |
| 93 | + |
| 94 | + include(SelectLibraryConfigurations) |
| 95 | + select_library_configurations(HTSLIB) |
| 96 | +endif() |
| 97 | + |
| 98 | +unset(HTSLIB_NAMES) |
| 99 | +unset(HTSLIB_NAMES_DEBUG) |
| 100 | + |
| 101 | +mark_as_advanced(HTSLIB_INCLUDE_DIR) |
| 102 | + |
| 103 | +if(HTSLIB_INCLUDE_DIR AND EXISTS "${HTSLIB_INCLUDE_DIR}/htslib/hts.h") |
| 104 | + # Example: #define HTS_VERSION 101300 |
| 105 | + file(STRINGS "${HTSLIB_INCLUDE_DIR}/htslib/hts.h" HTSLIB_H_LIST REGEX "^#define HTS_VERSION") |
| 106 | + list(GET HTSLIB_H_LIST 0 HTSLIB_H) # Take the first matching line |
| 107 | + if (HTSLIB_H MATCHES "#define[ \t]+HTS_VERSION[ \t]+\([0-9]+\)") |
| 108 | + set(NUMERIC_VERSION "${CMAKE_MATCH_1}") |
| 109 | + # Extract digits by position in string |
| 110 | + # XYYYZZ => X = major, YYY = minor, ZZ = patch |
| 111 | + string(SUBSTRING "${NUMERIC_VERSION}" 0 1 HTSLIB_VERSION_MAJOR) |
| 112 | + string(SUBSTRING "${NUMERIC_VERSION}" 1 3 HTSLIB_VERSION_MINOR) |
| 113 | + string(SUBSTRING "${NUMERIC_VERSION}" 4 2 HTSLIB_VERSION_PATCH) |
| 114 | + else() |
| 115 | + set(HTSLIB_VERSION_STRING "") |
| 116 | + set(HTSLIB_VERSION_MAJOR "") |
| 117 | + set(HTSLIB_VERSION_MINOR "") |
| 118 | + set(HTSLIB_VERSION_PATCH "") |
| 119 | + endif() |
| 120 | + |
| 121 | + # Make sure the version numbers don't have leading zeros |
| 122 | + # The minor version is encoded in such a way that it often will |
| 123 | + foreach(part HTSLIB_VERSION_MAJOR HTSLIB_VERSION_MINOR HTSLIB_VERSION_PATCH) |
| 124 | + if(${${part}} MATCHES "^[0]+$") |
| 125 | + set(${part} "0") |
| 126 | + else() |
| 127 | + string(REGEX REPLACE "^0+" "" ${part} "${${part}}") |
| 128 | + endif() |
| 129 | + endforeach() |
| 130 | + |
| 131 | + # Set canonical variables |
| 132 | + set(HTSLIB_MAJOR_VERSION "${HTSLIB_VERSION_MAJOR}") |
| 133 | + set(HTSLIB_MINOR_VERSION "${HTSLIB_VERSION_MINOR}") |
| 134 | + set(HTSLIB_PATCH_VERSION "${HTSLIB_VERSION_PATCH}") |
| 135 | + # Build the standard version string |
| 136 | + set(HTSLIB_VERSION "${HTSLIB_VERSION_MAJOR}.${HTSLIB_VERSION_MINOR}") |
| 137 | + # Only append patch if it's not "00" |
| 138 | + if(NOT HTSLIB_VERSION_PATCH STREQUAL "00") |
| 139 | + set(HTSLIB_VERSION "${HTSLIB_VERSION}.${HTSLIB_VERSION_PATCH}") |
| 140 | + endif() |
| 141 | +endif() |
| 142 | + |
| 143 | +include(FindPackageHandleStandardArgs) |
| 144 | +FIND_PACKAGE_HANDLE_STANDARD_ARGS( |
| 145 | + HTSLIB |
| 146 | + REQUIRED_VARS |
| 147 | + HTSLIB_LIBRARY |
| 148 | + HTSLIB_INCLUDE_DIR |
| 149 | + VERSION_VAR |
| 150 | + HTSLIB_VERSION |
| 151 | + HANDLE_COMPONENTS |
| 152 | +) |
| 153 | + |
| 154 | +if(HTSLIB_FOUND) |
| 155 | + set(HTSLIB_INCLUDE_DIRS ${HTSLIB_INCLUDE_DIR}) |
| 156 | + if(NOT HTSLIB_LIBRARIES) |
| 157 | + set(HTSLIB_LIBRARIES ${HTSLIB_LIBRARY}) |
| 158 | + endif() |
| 159 | + if(NOT TARGET HTSLIB::HTSLIB) |
| 160 | + add_library(HTSLIB::HTSLIB UNKNOWN IMPORTED) |
| 161 | + set_target_properties(HTSLIB::HTSLIB PROPERTIES |
| 162 | + INTERFACE_INCLUDE_DIRECTORIES "${HTSLIB_INCLUDE_DIRS}") |
| 163 | + if(HTSLIB_LIBRARY_RELEASE) |
| 164 | + set_property(TARGET HTSLIB::HTSLIB APPEND PROPERTY |
| 165 | + IMPORTED_CONFIGURATIONS RELEASE) |
| 166 | + set_target_properties(HTSLIB::HTSLIB PROPERTIES |
| 167 | + IMPORTED_LOCATION_RELEASE "${HTSLIB_LIBRARY_RELEASE}") |
| 168 | + endif() |
| 169 | + if(HTSLIB_LIBRARY_DEBUG) |
| 170 | + set_property(TARGET HTSLIB::HTSLIB APPEND PROPERTY |
| 171 | + IMPORTED_CONFIGURATIONS DEBUG) |
| 172 | + set_target_properties(HTSLIB::HTSLIB PROPERTIES |
| 173 | + IMPORTED_LOCATION_DEBUG "${HTSLIB_LIBRARY_DEBUG}") |
| 174 | + endif() |
| 175 | + if(NOT HTSLIB_LIBRARY_RELEASE AND NOT HTSLIB_LIBRARY_DEBUG) |
| 176 | + set_property(TARGET HTSLIB::HTSLIB APPEND PROPERTY |
| 177 | + IMPORTED_LOCATION "${HTSLIB_LIBRARY}") |
| 178 | + endif() |
| 179 | + endif() |
| 180 | +endif() |
| 181 | + |
| 182 | +cmake_policy(POP) |
0 commit comments