1# - Find the Catch test framework or download it (single header) 2# 3# This is a quick module for internal use. It assumes that Catch is 4# REQUIRED and that a minimum version is provided (not EXACT). If 5# a suitable version isn't found locally, the single header file 6# will be downloaded and placed in the build dir: PROJECT_BINARY_DIR. 7# 8# This code sets the following variables: 9# CATCH_INCLUDE_DIR - path to catch.hpp 10# CATCH_VERSION - version number 11 12if(NOT Catch_FIND_VERSION) 13 message(FATAL_ERROR "A version number must be specified.") 14elseif(Catch_FIND_REQUIRED) 15 message(FATAL_ERROR "This module assumes Catch is not required.") 16elseif(Catch_FIND_VERSION_EXACT) 17 message(FATAL_ERROR "Exact version numbers are not supported, only minimum.") 18endif() 19 20# Extract the version number from catch.hpp 21function(_get_catch_version) 22 file( 23 STRINGS "${CATCH_INCLUDE_DIR}/catch.hpp" version_line 24 REGEX "Catch v.*" 25 LIMIT_COUNT 1) 26 if(version_line MATCHES "Catch v([0-9]+)\\.([0-9]+)\\.([0-9]+)") 27 set(CATCH_VERSION 28 "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" 29 PARENT_SCOPE) 30 endif() 31endfunction() 32 33# Download the single-header version of Catch 34function(_download_catch version destination_dir) 35 message(STATUS "Downloading catch v${version}...") 36 set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp) 37 file(DOWNLOAD ${url} "${destination_dir}/catch.hpp" STATUS status) 38 list(GET status 0 error) 39 if(error) 40 message(FATAL_ERROR "Could not download ${url}") 41 endif() 42 set(CATCH_INCLUDE_DIR 43 "${destination_dir}" 44 CACHE INTERNAL "") 45endfunction() 46 47# Look for catch locally 48find_path( 49 CATCH_INCLUDE_DIR 50 NAMES catch.hpp 51 PATH_SUFFIXES catch2) 52if(CATCH_INCLUDE_DIR) 53 _get_catch_version() 54endif() 55 56# Download the header if it wasn't found or if it's outdated 57if(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION}) 58 if(DOWNLOAD_CATCH) 59 _download_catch(${Catch_FIND_VERSION} "${PROJECT_BINARY_DIR}/catch/") 60 _get_catch_version() 61 else() 62 set(CATCH_FOUND FALSE) 63 return() 64 endif() 65endif() 66 67add_library(Catch2::Catch2 IMPORTED INTERFACE) 68set_property(TARGET Catch2::Catch2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CATCH_INCLUDE_DIR}") 69 70set(CATCH_FOUND TRUE) 71