diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9bf750e..a1e0c2a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,6 +24,24 @@ jobs: cmake -S test -B build \ -DFFTW_TEST_COMPONENTS="${fftw_components}" + - name: Configure test with version 3 + run: | + cmake -S test -B build \ + -DFFTW_TEST_COMPONENTS="${fftw_components}" \ + -DFFTW_TEST_VERSION=3 + + - name: Configure test with invalid version + run: | + set +e + cmake -S test -B build_version_fail -DFFTW_TEST_VERSION=999.99.9 2>/dev/null + STATUS=$? + if [ $STATUS -ne 0 ]; then + echo "PASS: find_package correctly rejected version 999.99.9" + else + echo "FAIL: find_package should have rejected version 999.99.9 but succeeded" + exit 1 + fi + test-source: name: Test source install runs-on: ubuntu-latest @@ -79,6 +97,13 @@ jobs: -DFFTW_ROOT="$HOME/fftw_install" \ -DFFTW_TEST_COMPONENTS="${fftw_components}" + - name: Configure test with version 3 + run: | + cmake -S test -B build \ + -DFFTW_ROOT="$HOME/fftw_install" \ + -DFFTW_TEST_COMPONENTS="${fftw_components}" \ + -DFFTW_TEST_VERSION=3 + test-conda: name: Test conda-forge install runs-on: ubuntu-latest @@ -99,3 +124,11 @@ jobs: cmake -S test -B build \ -DFFTW_ROOT="$CONDA_PREFIX" \ -DFFTW_TEST_COMPONENTS="${fftw_components}" + + - name: Configure test with version 3 + shell: micromamba-shell {0} + run: | + cmake -S test -B build \ + -DFFTW_ROOT="$CONDA_PREFIX" \ + -DFFTW_TEST_COMPONENTS="${fftw_components}" \ + -DFFTW_TEST_VERSION=3 diff --git a/FindFFTW.cmake b/FindFFTW.cmake index 7b2788c..5f1e486 100644 --- a/FindFFTW.cmake +++ b/FindFFTW.cmake @@ -7,7 +7,7 @@ # Copyright (c) 2017, Patrick Bos # # Usage: -# find_package(FFTW [REQUIRED] [QUIET] [COMPONENTS component1 ... componentX] ) +# find_package(FFTW [] [REQUIRED] [QUIET] [COMPONENTS component1 ... componentX] ) # # It sets the following variables: # FFTW_FOUND ... true if fftw is found on the system @@ -15,6 +15,7 @@ # FFTW_LIBRARIES ... full paths to all found fftw libraries # FFTW_[component]_LIB ... full path to one of the components (see below) # FFTW_INCLUDE_DIRS ... fftw include directory paths +# FFTW_VERSION ... version of the found fftw library # # The following variables will be checked by the function # FFTW_USE_STATIC_LIBS ... if true, only static libraries are found, otherwise both static and shared. @@ -44,9 +45,31 @@ endif() # Check if we can use PkgConfig find_package(PkgConfig) -#Determine from PKG +# Determine from PKG if( PKG_CONFIG_FOUND AND NOT FFTW_ROOT ) pkg_check_modules( PKG_FFTW QUIET "fftw3" ) + set( FFTW_VERSION ${PKG_FFTW_VERSION} ) +else() + # If pkg-config was skipped, there seems no way to get the version directly. + # Try to deduce the version from fftw-wisdom-to-conf instead. + # (From @kprussing. See https://github.com/egpbos/findFFTW/pull/8) + execute_process(COMMAND ${FFTW_ROOT}/bin/fftw-wisdom-to-conf -V + RESULT_VARIABLE _fftw_wtc_success + OUTPUT_VARIABLE _fftw_wtc_stdout + ERROR_VARIABLE _fftw_wtc_stderr) + if (_fftw_wtc_success EQUAL 0) + string(REGEX MATCH "FFTW *version *([0-9]+([.][0-9]+([.][0-9]+)?)?)" + _fftw_wtc_version ${_fftw_wtc_stdout}) + string(REPLACE " " ";" _fftw_wtc_version_list ${_fftw_wtc_version}) + list(GET _fftw_wtc_version_list -1 FFTW_VERSION) + else() + message(WARNING "Error running ${FFTW_ROOT}/bin/fftw-wisdom-to-conf. " + "Could not determine FFTW version. +Output: +${_fftw_wtc_stdout} +Error: +${_fftw_wtc_stderr}") + endif() endif() #Check whether to search static or dynamic libs @@ -398,6 +421,7 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(FFTW REQUIRED_VARS FFTW_INCLUDE_DIRS + VERSION_VAR FFTW_VERSION HANDLE_COMPONENTS ) diff --git a/README.md b/README.md index 1226f88..7633f6c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ CMake module for finding FFTW 3 using find_package Once added to your project, this module allows you to find FFTW libraries and headers using the CMake `find_package` command: ```cmake -find_package(FFTW [REQUIRED] [QUIET] [COMPONENTS component1 ... componentX] ) +find_package(FFTW [] [REQUIRED] [QUIET] [COMPONENTS component1 ... componentX] ) ``` This module sets the following variables: @@ -14,6 +14,7 @@ This module sets the following variables: - `FFTW_LIBRARIES` ... full paths to all found fftw libraries - `FFTW_[component]_LIB` ... full path to one of the components (see below) - `FFTW_INCLUDE_DIRS` ... fftw include directory paths +- `FFTW_VERSION` ... version of the found fftw library The following variables will be checked by the module: - `FFTW_USE_STATIC_LIBS` ... if true, only static libraries are found, otherwise both static and shared. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2a65116..b4e9049 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,10 +6,10 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/..") # Find FFTW. If FFTW_TEST_COMPONENTS is given (semicolon-separated list), those # components are required; otherwise we just require that FFTW itself is found. -if(DEFINED FFTW_TEST_COMPONENTS) - find_package(FFTW REQUIRED COMPONENTS ${FFTW_TEST_COMPONENTS}) +if(FFTW_TEST_COMPONENTS) + find_package(FFTW ${FFTW_TEST_VERSION} REQUIRED COMPONENTS ${FFTW_TEST_COMPONENTS}) else() - find_package(FFTW REQUIRED) + find_package(FFTW ${FFTW_TEST_VERSION} REQUIRED) endif() # --------------------------------------------------------------------------- @@ -27,6 +27,20 @@ if(NOT FFTW_LIBRARIES) message(FATAL_ERROR "FFTW_LIBRARIES is empty after find_package(FFTW REQUIRED)") endif() +if(NOT FFTW_VERSION) + message(FATAL_ERROR "FFTW_VERSION is empty after find_package(FFTW REQUIRED)") +endif() + +# --------------------------------------------------------------------------- +# Version checks +# --------------------------------------------------------------------------- +if(FFTW_TEST_VERSION) + if(NOT "${FFTW_VERSION}" VERSION_GREATER_EQUAL "${FFTW_TEST_VERSION}") + message(FATAL_ERROR + "Expected FFTW_VERSION >= ${FFTW_TEST_VERSION} but got ${FFTW_VERSION}") + endif() +endif() + # --------------------------------------------------------------------------- # Map component names to their CMake imported target names # --------------------------------------------------------------------------- @@ -71,6 +85,7 @@ endforeach() # --------------------------------------------------------------------------- message(STATUS "FindFFTW test passed!") message(STATUS " FFTW_FOUND: ${FFTW_FOUND}") +message(STATUS " FFTW_VERSION: ${FFTW_VERSION}") message(STATUS " FFTW_INCLUDE_DIRS: ${FFTW_INCLUDE_DIRS}") message(STATUS " FFTW_LIBRARIES: ${FFTW_LIBRARIES}")