Merge "cmake: allow switch between single and double" into release-4-6
[alexxy/gromacs.git] / cmake / FindFFTW.cmake
1 # - Find FFTW 2/3 single double
2 # Find the native FFTW headers and libraries.
3 #
4 #  FFTW_INCLUDE_DIRS - where to find FFTW headers
5 #  FFTW_LIBRARIES    - List of libraries when using FFTW.
6 #  FFTW_PKG          - The name of the pkg-config package needed
7 #  FFTW_HAVE_SSE     - True if FFTW was build with SSE support
8 #  FFTW_FOUND        - True if FFTW was found
9 #
10 #  This file is part of Gromacs        Copyright (c) 2012
11
12 #  This program is free software; you can redistribute it and/or
13 #  modify it under the terms of the GNU General Public License
14 #  as published by the Free Software Foundation; either version 2
15 #  of the License, or (at your option) any later version.
16
17 #  To help us fund GROMACS development, we humbly ask that you cite
18 #  the research papers on the package. Check out http://www.gromacs.org
19
20 find_package(PkgConfig)
21 list(LENGTH FFTW_FIND_COMPONENTS FFTW_NUM_COMPONENTS_WANTED)
22 if(${FFTW_NUM_COMPONENTS_WANTED} LESS 1)
23   message(FATAL_ERROR "No FFTW component to search given")
24 elseif(${FFTW_NUM_COMPONENTS_WANTED} GREATER 1)
25   message(FATAL_ERROR "We only support finding one FFTW component at the time, go and implement it ;-)")
26 elseif(${FFTW_FIND_COMPONENTS} MATCHES "^fftw(f)?$")
27   if (${FFTW_FIND_VERSION} EQUAL 3 OR NOT FFTW_FIND_VERSION) #find FFTW3 by default
28     string(REGEX REPLACE "fftw" "fftw3" FFTW_PKG "${FFTW_FIND_COMPONENTS}")
29     set(FFTW_HEADER "fftw3.h")
30     set(FFTW_FUNCTION "${FFTW_FIND_COMPONENTS}_plan_r2r_1d")
31   #elseif(${FFTW_FIND_VERSION} EQUAL 2)
32   #  set(FFTW_PKG "${FFTW_FIND_COMPONENTS}")
33   #  set(FFTW_HEADER "${FFTW_FIND_COMPONENTS}.h")
34   else()
35     message(FATAL_ERROR "We only support finding FFTW version 3, go and implement it ;-)")
36   endif()
37 else()
38   message(FATAL_ERROR "We do not support finding ${FFTW_FIND_COMPONENTS}, go and implement it ;-)")
39 endif()
40
41 if(NOT __pkg_config_checked_PC_FFTW_${FFTW_PKG})
42   pkg_check_modules(PC_FFTW_${FFTW_PKG} "${FFTW_PKG}")
43 endif(NOT __pkg_config_checked_PC_FFTW_${FFTW_PKG})
44
45 if(FFTW_LIBRARY)
46   set(FFTW_LIBRARY_${FFTW_PKG} "${FFTW_LIBRARY}" CACHE INTERNAL "Path to ${FFTW_PKG} library" FORCE)
47 else(FFTW_LIBRARY)
48   set(FFTW_LIBRARY "" CACHE FILEPATH "Path to ${FFTW_PKG} library")
49 endif(FFTW_LIBRARY)
50
51 if(FFTW_INCLUDE_DIR)
52   set(FFTW_INCLUDE_DIR_${FFTW_PKG} "${FFTW_INCLUDE_DIR}" CACHE INTERNAL "Path to ${FFTW_HEADER}" FORCE)
53 else(FFTW_INCLUDE_DIR)
54   set(FFTW_INCLUDE_DIR "" CACHE DIRECTORY "Path to ${FFTW_HEADER}")
55 endif(FFTW_INCLUDE_DIR)
56
57 #we use _${FFTW_PKG} variables to have different cache entries for fftw3 and ffw3f
58 find_path(FFTW_INCLUDE_DIR_${FFTW_PKG} "${FFTW_HEADER}" HINTS ${PC_FFTW_${FFTW_PKG}_INCLUDE_DIRS})
59 find_library(FFTW_LIBRARY_${FFTW_PKG} NAMES "${FFTW_PKG}" HINTS ${PC_FFTW_${FFTW_PKG}_LIBRARY_DIRS})
60
61 #make _${FFTW_PKG} variables INTERNAL to avoid confusion in cmake-gui
62 set(FFTW_LIBRARY_${FFTW_PKG} ${FFTW_LIBRARY_${FFTW_PKG}} CACHE INTERNAL "Path to ${FFTW_PKG} library" FORCE)
63 set(FFTW_INCLUDE_DIR_${FFTW_PKG} ${FFTW_INCLUDE_DIR_${FFTW_PKG}} CACHE INTERNAL "Path to ${FFTW_HEADER}" FORCE)
64
65 # set default find_package outcome variables
66 set(FFTW_LIBRARIES "${FFTW_LIBRARY_${FFTW_PKG}}")
67 set(FFTW_INCLUDE_DIRS "${FFTW_INCLUDE_DIR_${FFTW_PKG}}")
68
69 set(FFTW_FOUND FALSE)
70 if (FFTW_LIBRARY_${FFTW_PKG} AND FFTW_INCLUDE_DIR_${FFTW_PKG})
71   set(FFTW_FOUND TRUE)
72 elseif (NOT FFTW_LIBRARY_${FFTW_PKG})
73   message("Could not find ${FFTW_PKG} library named lib${FFTW_PKG}, please specify its location in FFTW_LIBRARY by hand (e.g. -DFFTW_LIBRARY='/path/to/lib${FFTW_PKG}.so')")
74 elseif (NOT FFTW_INCLUDE_DIR_${FFTW_PKG})
75   message("Could not the ${FFTW_PKG} header ${FFTW_HEADER}, please specify its path in FFTW_INCLUDE_DIR by hand (e.g. -DFFTW_INCLUDE_DIR='/path/to/include')")
76 endif()
77
78 set(FFTW_HAVE_SSE FALSE CACHE BOOL "If ${FFTW_PKG} was built with SSE support")
79 if (FFTW_FOUND AND HAVE_LIBM AND NOT "${FFTW_LIBRARY_PREVIOUS}" STREQUAL "${FFTW_LIBRARY}")
80   #The user could specify trash in FFTW_LIBRARY, so test if we can link it
81   include(CheckLibraryExists)
82   #adding MATH_LIBRARIES here to allow static libs, this does not harm us as we are anyway using it
83   set(CMAKE_REQUIRED_LIBRARIES m)
84   unset(FOUND_FFTW_PLAN_${FFTW_PKG} CACHE)
85   check_library_exists("${FFTW_LIBRARIES}" "${FFTW_FUNCTION}" "" FOUND_FFTW_PLAN_${FFTW_PKG})
86   if(NOT FOUND_FFTW_PLAN_${FFTW_PKG})
87     message(FATAL_ERROR "Could not find ${FFTW_FUNCTION} in ${FFTW_LIBRARY_${FFTW_PKG}}, take a look at the error message in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log to find out what went wrong. If you are using a static lib (.a) make sure you have specified all dependencies of ${FFTW_PKG} in FFTW_LIBRARY by hand (e.g. -DFFTW_LIBRARY='/path/to/lib${FFTW_PKG}.so;/path/to/libm.so') !")
88   endif(NOT FOUND_FFTW_PLAN_${FFTW_PKG})
89   #in 3.3 sse function name has changed
90   foreach(SSE_FCT fftwf_have_simd_sse2;fftw_have_simd_sse2;fftwf_have_sse;fftw_have_sse2)
91     unset(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG} CACHE)
92     check_library_exists("${FFTW_LIBRARIES}" "${SSE_FCT}" "" FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
93     if(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
94       set(FFTW_HAVE_SSE_${FFTW_PKG} "${FFTW_HAVE_${SSE_FCT}_${FFTW_PKG}}")
95       break()
96     endif(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
97   endforeach()
98   set(FFTW_HAVE_SSE "${FFTW_HAVE_SSE_${FFTW_PKG}}" CACHE BOOL "If ${FFTW_PKG} was built with SSE support" FORCE)
99   set(CMAKE_REQUIRED_LIBRARIES)
100   set(FFTW_LIBRARY_PREVIOUS "${FFTW_LIBRARY}" CACHE INTERNAL "Value of FFTW_LIBRARY when executing the linking check that last time" FORCE)
101 endif (FFTW_FOUND AND HAVE_LIBM AND NOT "${FFTW_LIBRARY_PREVIOUS}" STREQUAL "${FFTW_LIBRARY}")
102
103 mark_as_advanced(FFTW_INCLUDE_DIR FFTW_LIBRARY FFTW_HAVE_SSE)