FindFFTW.cmake 27.6 KB
Newer Older
1
2
3
4
5
###
#
# @copyright (c) 2009-2014 The University of Tennessee and The University
#                          of Tennessee Research Foundation.
#                          All rights reserved.
6
# @copyright (c) 2012-2015 Inria. All rights reserved.
7
8
9
10
11
# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
#
###
#
# - Find FFTW Version 3 include dirs and libraries
12
13
# Default configuration will find the real double precision fftw library version
# without THREADS|OMP.
14
15
16
17
18
19
20
# Use this module by invoking find_package with the form:
#  find_package(FFTW
#               [REQUIRED] # Fail with error if fftw is not found
#               [COMPONENTS MKL]
#
#  COMPONENTS can be some of the following:
#   - MKL:     to detect the FFTW from Intel MKL
21
#   - ESSL:    to detect the FFTW from IBM ESSL
22
23
24
25
26
27
28
29
30
#   - THREADS: to detect the Threads version of FFTW
#   - OMP:     to detect the OpenMP version of FFTW
#   - SIMPLE:  to detect the FFTW simple precision fftw3f
#   - LONG:    to detect the FFTW long double precision fftw3l
#   - QUAD:    to detect the FFTW quadruple precision fftw3q
#
# This module finds headers and fftw library.
# Results are reported in variables:
#  FFTW_FOUND            - True if headers and requested libraries were found
31
32
#  FFTW_C_FLAGS          - list of required compilation flags (excluding -I)
#  FFTW_LINKER_FLAGS     - list of required linker flags (excluding -l and -L)
33
34
35
36
37
38
39
40
41
42
43
44
#  FFTW_INCLUDE_DIRS     - fftw include directories
#  FFTW_LIBRARY_DIRS     - Link directories for fftw libraries
#  FFTW_LIBRARIES        - fftw component libraries to be linked
#  FFTW_INCLUDE_DIRS_DEP - fftw + dependencies include directories
#  FFTW_LIBRARY_DIRS_DEP - fftw + dependencies link directories
#  FFTW_LIBRARIES_DEP    - fftw libraries + dependencies
#
# The user can give specific paths where to find the libraries adding cmake
# options at configure (ex: cmake path/to/project -DFFTW_DIR=path/to/fftw):
#  FFTW_DIR             - Where to find the base directory of fftw
#  FFTW_INCDIR          - Where to find the header files
#  FFTW_LIBDIR          - Where to find the library files
45
46
# The module can also look for the following environment variables if paths
# are not given as cmake variable: FFTW_DIR, FFTW_INCDIR, FFTW_LIBDIR
47
48
# For MKL case and if no paths are given as hints, we will try to use the MKLROOT
# environment variable
49
50
51
52
53
54

#=============================================================================
# Copyright 2012-2013 Inria
# Copyright 2012-2013 Emmanuel Agullo
# Copyright 2012-2013 Mathieu Faverge
# Copyright 2012      Cedric Castagnede
55
# Copyright 2013-2016 Florent Pruvost
56
57
58
59
60
61
62
63
64
65
66
67
68
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file MORSE-Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of Morse, substitute the full
#  License text for the above reference.)


if (NOT FFTW_FOUND)
69
70
71
72
  set(FFTW_DIR "" CACHE PATH "Installation directory of FFTW library given by user")
  if (NOT FFTW_FIND_QUIETLY)
    message(STATUS "A cache variable, namely FFTW_DIR, has been set to specify the install directory of FFTW")
  endif()
73
74
75
76
endif()

# Set the version to find
set(FFTW_LOOK_FOR_MKL OFF)
77
set(FFTW_LOOK_FOR_ESSL OFF)
78
79
80
81
82
83
84
set(FFTW_LOOK_FOR_THREADS OFF)
set(FFTW_LOOK_FOR_OMP OFF)
set(FFTW_LOOK_FOR_FFTW_SIMPLE OFF)
set(FFTW_LOOK_FOR_FFTW_LONG OFF)
set(FFTW_LOOK_FOR_FFTW_QUAD OFF)

if( FFTW_FIND_COMPONENTS )
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  foreach( component ${FFTW_FIND_COMPONENTS} )
    if (${component} STREQUAL "THREADS")
      # means we look for the Threads version of FFTW
      set(FFTW_LOOK_FOR_THREADS ON)
    endif()
    if (${component} STREQUAL "OMP")
      # means we look for the OpenMP version of FFTW
      set(FFTW_LOOK_FOR_OMP ON)
    endif()
    if (${component} STREQUAL "SIMPLE")
      # means we look for FFTW simple precision (fftw3f)
      set(FFTW_LOOK_FOR_FFTW_SIMPLE ON)
      set(FFTW_LOOK_FOR_FFTW_LONG OFF)
      set(FFTW_LOOK_FOR_FFTW_QUAD OFF)
    endif()
    if (${component} STREQUAL "LONG")
      # means we look for FFTW long double precision (fftw3l)
      set(FFTW_LOOK_FOR_FFTW_SIMPLE OFF)
      set(FFTW_LOOK_FOR_FFTW_LONG ON)
      set(FFTW_LOOK_FOR_FFTW_QUAD OFF)
    endif()
    if (${component} STREQUAL "QUAD")
      # means we look for FFTW quad precision (fftw3q)
      set(FFTW_LOOK_FOR_FFTW_SIMPLE OFF)
      set(FFTW_LOOK_FOR_FFTW_LONG OFF)
      set(FFTW_LOOK_FOR_FFTW_QUAD ON)
    endif()
    if (${component} STREQUAL "MKL")
      # means we look for the Intel MKL version of FFTW
      set(FFTW_LOOK_FOR_MKL ON)
      if (FFTW_LOOK_FOR_FFTW_LONG)
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
        if (NOT FFTW_FIND_QUIETLY)
          message(WARNING "Looking for FFTW -- long precision functions do not exist in MKL FFTW")
        endif()
        set(FFTW_LOOK_FOR_FFTW_LONG OFF)
      endif()
      if (FFTW_LOOK_FOR_FFTW_QUAD)
        if (NOT FFTW_FIND_QUIETLY)
          message(WARNING "Looking for FFTW -- quadruple functions do not exist in MKL FFTW")
        endif()
        set(FFTW_LOOK_FOR_FFTW_QUAD OFF)
      endif()
    endif()
    if (${component} STREQUAL "ESSL")
      # means we look for the Intel MKL version of FFTW
      set(FFTW_LOOK_FOR_ESSL ON)
      if (FFTW_LOOK_FOR_FFTW_LONG)
        if (NOT FFTW_FIND_QUIETLY)
          message(WARNING "Looking for FFTW -- long precision functions do not exist in FFTW_ESSL")
        endif()
        set(FFTW_LOOK_FOR_FFTW_LONG OFF)
136
137
      endif()
      if (FFTW_LOOK_FOR_FFTW_QUAD)
138
139
140
141
142
143
144
145
146
147
        if (NOT FFTW_FIND_QUIETLY)
          message(WARNING "Looking for FFTW -- quadruple functions do not exist in FFTW_ESSL")
        endif()
        set(FFTW_LOOK_FOR_FFTW_QUAD OFF)
      endif()
      if (FFTW_LOOK_FOR_OMP)
        if (NOT FFTW_FIND_QUIETLY)
          message(WARNING "Looking for FFTW -- FFTW_ESSL does not use OpenMP")
        endif()
        set(FFTW_LOOK_FOR_OMP OFF)
148
149
150
      endif()
    endif()
  endforeach()
151
152
153
endif()

if (FFTW_LOOK_FOR_THREADS)
154
155
156
  if (NOT FFTW_FIND_QUIETLY)
    message(STATUS "FFTW looks for threads")
  endif()
157
158
159
160
161
  if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_THREADS)
    find_package(Threads REQUIRED)
  else()
    find_package(Threads)
  endif()
162
163
endif()

164
165
166
167
168
169
170
171
172
173
174
if (FFTW_LOOK_FOR_OMP)
  if (NOT FFTW_FIND_QUIETLY)
    message(STATUS "FFTW looks for openmp")
  endif()
  if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_OMP)
    find_package(OpenMP REQUIRED)
  else()
    find_package(OpenMP)
  endif()
endif()

175
if (FFTW_LOOK_FOR_MKL)
176
177
178
179
180
181
182
183
  if (NOT FFTW_FIND_QUIETLY)
    message(STATUS "FFTW looks for threads and Intel MKL")
  endif()
  if (FFTW_LOOK_FOR_THREADS)
    set(BLA_VENDOR "Intel10_64lp")
  else()
    set(BLA_VENDOR "Intel10_64lp_seq")
  endif()
184
185
  if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL)
    find_package(Threads REQUIRED)
186
    find_package(BLASEXT REQUIRED)
187
188
  else()
    find_package(Threads)
189
    find_package(BLASEXT)
190
  endif()
191
192
endif()

193
194
195
196
197
198
if (FFTW_LOOK_FOR_ESSL)
  if (NOT FFTW_FIND_QUIETLY)
    message(STATUS "FFTW looks for IBM ESSL")
  endif()
  if (FFTW_LOOK_FOR_THREADS)
    set(BLA_VENDOR "IBMESSLMT")
199
  else()
200
201
202
203
204
205
    set(BLA_VENDOR "IBMESSL")
  endif()
  if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_ESSL)
    find_package(BLASEXT REQUIRED)
  else()
    find_package(BLASEXT)
206
  endif()
207
208
endif()

209
210
set(ENV_FFTW_DIR "$ENV{FFTW_DIR}")
set(ENV_FFTW_INCDIR "$ENV{FFTW_INCDIR}")
211
212
213
214
215
216
set(ENV_FFTW_LIBDIR "$ENV{FFTW_LIBDIR}")
set(FFTW_GIVEN_BY_USER "FALSE")
if ( FFTW_DIR OR ( FFTW_INCDIR AND FFTW_LIBDIR) OR ENV_FFTW_DIR OR (ENV_FFTW_INCDIR AND ENV_FFTW_LIBDIR) )
  set(FFTW_GIVEN_BY_USER "TRUE")
endif()

217

218
219
# Optionally use pkg-config to detect include/library dirs (if pkg-config is available)
# -------------------------------------------------------------------------------------
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
if (NOT FFTW_LOOK_FOR_MKL AND NOT FFTW_LOOK_FOR_ESSL)
  include(FindPkgConfig)
  find_package(PkgConfig QUIET)
  if( PKG_CONFIG_EXECUTABLE AND NOT FFTW_GIVEN_BY_USER )

    set(FFTW_INCLUDE_DIRS)
    set(FFTW_LIBRARY_DIRS)
    set(FFTW_LIBRARIES)

    if(FFTW_LOOK_FOR_FFTW_SIMPLE)
      pkg_search_module(FFTW3F fftw3f)
      pkg_search_module(FFTW3 fftw3)
      if (FFTW3F_FOUND)
        if (NOT FFTW_FIND_QUIETLY)
          message(STATUS "Looking for FFTW3F - found using PkgConfig")
        endif()
        if (FFTW3F_LIBRARIES)
          list(APPEND FFTW_LIBRARIES "${FFTW3F_LIBRARIES}")
        endif()
        if(FFTW3F_INCLUDE_DIRS)
          list(APPEND FFTW_INCLUDE_DIRS "${FFTW3F_INCLUDE_DIRS}")
        else()
          if (NOT FFTW_FIND_QUIETLY)
            message(WARNING "FFTW3F_INCLUDE_DIRS is empty using PkgConfig."
            "Perhaps the path to fftw3f headers is already present in your"
            "CPATH/C(PLUS)_INCLUDE_PATH environment variables.")
          endif()
        endif()
        if(FFTW3F_LIBRARY_DIRS)
          list(APPEND FFTW_LIBRARY_DIRS "${FFTW3F_LIBRARY_DIRS}")
        endif()
      else(FFTW3F_FOUND)
        if (NOT FFTW_FIND_QUIETLY)
          message(STATUS "Looking for FFTW3F - not found using PkgConfig."
          "Perhaps you should add the directory containing fftw3f.pc to"
          "the PKG_CONFIG_PATH environment variable.")
        endif()
      endif(FFTW3F_FOUND)
    elseif(FFTW_LOOK_FOR_FFTW_LONG)
      pkg_search_module(FFTW3L fftw3l)
      pkg_search_module(FFTW3 fftw3)
      if (FFTW3L_FOUND)
        if (NOT FFTW_FIND_QUIETLY)
          message(STATUS "Looking for FFTW3L - found using PkgConfig")
        endif()
        if (FFTW3L_LIBRARIES)
          list(APPEND FFTW_LIBRARIES "${FFTW3L_LIBRARIES}")
        endif()
        if(FFTW3L_INCLUDE_DIRS)
          list(APPEND FFTW_INCLUDE_DIRS "${FFTW3L_INCLUDE_DIRS}")
        else()
          if (NOT FFTW_FIND_QUIETLY)
            message(WARNING "FFTW3L_INCLUDE_DIRS is empty using PkgConfig."
            "Perhaps the path to fftw3l headers is already present in your"
            "CPATH/C(PLUS)_INCLUDE_PATH environment variables.")
          endif()
        endif()
        if(FFTW3L_LIBRARY_DIRS)
          list(APPEND FFTW_LIBRARY_DIRS "${FFTW3L_LIBRARY_DIRS}")
        endif()
      else(FFTW3L_FOUND)
        if (NOT FFTW_FIND_QUIETLY)
          message(STATUS "Looking for FFTW3L - not found using PkgConfig."
          "Perhaps you should add the directory containing fftw3l.pc to"
          "the PKG_CONFIG_PATH environment variable.")
        endif()
      endif(FFTW3L_FOUND)
    elseif(FFTW_LOOK_FOR_FFTW_QUAD)
      pkg_search_module(FFTW3Q fftw3q)
      pkg_search_module(FFTW3 fftw3)
      if (FFTW3Q_FOUND)
        if (NOT FFTW_FIND_QUIETLY)
          message(STATUS "Looking for FFTW3Q - found using PkgConfig")
        endif()
        if (FFTW3Q_LIBRARIES)
          list(APPEND FFTW_LIBRARIES "${FFTW3Q_LIBRARIES}")
        endif()
        if(FFTW3Q_INCLUDE_DIRS)
          list(APPEND FFTW_INCLUDE_DIRS "${FFTW3Q_INCLUDE_DIRS}")
        else()
          if (NOT FFTW_FIND_QUIETLY)
            message(WARNING "FFTW3Q_INCLUDE_DIRS is empty using PkgConfig."
            "Perhaps the path to fftw3q headers is already present in your"
            "CPATH/C(PLUS)_INCLUDE_PATH environment variables.")
          endif()
        endif()
        if(FFTW3Q_LIBRARY_DIRS)
          list(APPEND FFTW_LIBRARY_DIRS "${FFTW3Q_LIBRARY_DIRS}")
        endif()
      else(FFTW3Q_FOUND)
        if (NOT FFTW_FIND_QUIETLY)
          message(STATUS "Looking for FFTW3Q - not found using PkgConfig."
          "Perhaps you should add the directory containing fftw3q.pc to"
          "the PKG_CONFIG_PATH environment variable.")
        endif()
      endif(FFTW3Q_FOUND)
316
    else()
317
      pkg_search_module(FFTW3 fftw3)
318
    endif()
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
    if (FFTW3_FOUND)
      if (NOT FFTW_FIND_QUIETLY)
        message(STATUS "Looking for FFTW3 - found using PkgConfig")
      endif()
      if (FFTW3_LIBRARIES)
        list(APPEND FFTW_LIBRARIES "${FFTW3_LIBRARIES}")
      endif()
      if(FFTW3_INCLUDE_DIRS)
        list(APPEND FFTW_INCLUDE_DIRS "${FFTW3_INCLUDE_DIRS}")
      else()
        if (NOT FFTW_FIND_QUIETLY)
          message(WARNING "FFTW3_INCLUDE_DIRS is empty using PkgConfig."
          "Perhaps the path to fftw3 headers is already present in your"
          "CPATH/C(PLUS)_INCLUDE_PATH environment variables.")
        endif()
      endif()
      if(FFTW3_LIBRARY_DIRS)
        list(APPEND FFTW_LIBRARY_DIRS "${FFTW3_LIBRARY_DIRS}")
      endif()
    else(FFTW3_FOUND)
      if (NOT FFTW_FIND_QUIETLY)
        message(STATUS "Looking for FFTW3 - not found using PkgConfig."
        "Perhaps you should add the directory containing fftw3.pc to"
        "the PKG_CONFIG_PATH environment variable.")
      endif()
    endif(FFTW3_FOUND)
345

346
347
348
    set(FFTW_INCLUDE_DIRS_DEP "${FFTW_INCLUDE_DIRS}")
    set(FFTW_LIBRARY_DIRS_DEP "${FFTW_LIBRARY_DIRS}")
    set(FFTW_LIBRARIES_DEP    "${FFTW_LIBRARIES}"   )
349

350
351
352
    if (FFTW_LIBRARIES)
      set(FFTW_WORKS TRUE)
    endif()
353

354
  endif( PKG_CONFIG_EXECUTABLE AND NOT FFTW_GIVEN_BY_USER )
355

356
357
358
359
360
361
362
363
endif(NOT FFTW_LOOK_FOR_MKL AND NOT FFTW_LOOK_FOR_ESSL)

if( (NOT PKG_CONFIG_EXECUTABLE) OR
       (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR
       FFTW_GIVEN_BY_USER OR
       FFTW_LOOK_FOR_MKL  OR
       FFTW_LOOK_FOR_ESSL
  )
364
365
366
367
368
369
370
371
372
373
374

  # Looking for include
  # -------------------

  # Add system include paths to search include
  # ------------------------------------------
  unset(_inc_env)
  set(ENV_MKLROOT "$ENV{MKLROOT}")
  set(ENV_FFTW_DIR "$ENV{FFTW_DIR}")
  set(ENV_FFTW_INCDIR "$ENV{FFTW_INCDIR}")
  if(ENV_FFTW_INCDIR)
375
    list(APPEND _inc_env "${ENV_FFTW_INCDIR}")
376
  elseif(ENV_FFTW_DIR)
377
378
    list(APPEND _inc_env "${ENV_FFTW_DIR}")
    list(APPEND _inc_env "${ENV_FFTW_DIR}/include")
379
    list(APPEND _inc_env "${ENV_FFTW_DIR}/include/fftw")
380
  else()
381
    if (ENV_MKLROOT)
382
      list(APPEND _inc_env "${ENV_MKLROOT}/include/fftw")
383
384
385
    endif()
    # system variables
    if(WIN32)
386
387
      string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
      list(APPEND _inc_env "${_path_env}")
388
    else()
389
390
391
392
393
394
395
396
      string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
      list(APPEND _inc_env "${_path_env}")
      string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
      list(APPEND _inc_env "${_path_env}")
      string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
      list(APPEND _inc_env "${_path_env}")
      string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
      list(APPEND _inc_env "${_path_env}")
397
    endif()
398
399
400
401
402
403
404
405
  endif()
  list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
  list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
  list(REMOVE_DUPLICATES _inc_env)

  # set paths where to look for
  set(PATH_TO_LOOK_FOR "${_inc_env}")

406
407
408
409
410
411
  if (FFTW_LOOK_FOR_ESSL)
    set(FFTW3_HEADER_TO_FIND "fftw3_essl.h")
  else()
    set(FFTW3_HEADER_TO_FIND "fftw3.h")
  endif()

412
413
414
415
  # Try to find the fftw header in the given paths
  # -------------------------------------------------
  # call cmake macro to find the header path
  if(FFTW_INCDIR)
416
417
418
    set(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS "FFTW_${FFTW3_HEADER_TO_FIND}_DIRS-NOTFOUND")
    find_path(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS
      NAMES ${FFTW3_HEADER_TO_FIND}
419
      HINTS ${FFTW_INCDIR})
420
  else()
421
    if(FFTW_DIR)
422
423
424
      set(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS "FFTW_${FFTW3_HEADER_TO_FIND}_DIRS-NOTFOUND")
      find_path(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS
	NAMES ${FFTW3_HEADER_TO_FIND}
425
426
	HINTS ${FFTW_DIR}
	PATH_SUFFIXES "include" "include/fftw")
427
    else()
428
429
430
      set(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS "FFTW_${FFTW3_HEADER_TO_FIND}_DIRS-NOTFOUND")
      find_path(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS
	NAMES ${FFTW3_HEADER_TO_FIND}
431
432
	HINTS ${PATH_TO_LOOK_FOR}
	PATH_SUFFIXES "fftw")
433
    endif()
434
  endif()
435
  mark_as_advanced(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS)
436

437
438
  # Add path to cmake variable
  # ------------------------------------
439
440
  if (FFTW_${FFTW3_HEADER_TO_FIND}_DIRS)
    set(FFTW_INCLUDE_DIRS "${FFTW_${FFTW3_HEADER_TO_FIND}_DIRS}")
441
  else ()
442
443
    set(FFTW_INCLUDE_DIRS "FFTW_INCLUDE_DIRS-NOTFOUND")
    if(NOT FFTW_FIND_QUIETLY)
444
      message(STATUS "Looking for FFTW -- ${FFTW3_HEADER_TO_FIND} not found")
445
    endif()
446
  endif ()
447
448


449
450
  # Looking for lib
  # ---------------
451

452
453
454
455
456
  # Add system library paths to search lib
  # --------------------------------------
  unset(_lib_env)
  set(ENV_FFTW_LIBDIR "$ENV{FFTW_LIBDIR}")
  if(ENV_FFTW_LIBDIR)
457
    list(APPEND _lib_env "${ENV_FFTW_LIBDIR}")
458
  elseif(ENV_FFTW_DIR)
459
460
461
    list(APPEND _lib_env "${ENV_FFTW_DIR}")
    list(APPEND _lib_env "${ENV_FFTW_DIR}/lib")
    if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
462
463
      list(APPEND _lib_env "${ENV_FFTW_DIR}/lib64")
      list(APPEND _lib_env "${ENV_FFTW_DIR}/lib/intel64")
464
    else()
465
466
      list(APPEND _lib_env "${ENV_FFTW_DIR}/lib32")
      list(APPEND _lib_env "${ENV_FFTW_DIR}/lib/ia32")
467
    endif()
468
  else()
469
    if (ENV_MKLROOT)
470
471
472
473
474
475
476
477
      list(APPEND _lib_env "${ENV_MKLROOT}/lib")
      if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
	list(APPEND _lib_env "${ENV_MKLROOT}/lib64")
	list(APPEND _lib_env "${ENV_MKLROOT}/lib/intel64")
      else()
	list(APPEND _lib_env "${ENV_MKLROOT}/lib32")
	list(APPEND _lib_env "${ENV_MKLROOT}/lib/ia32")
      endif()
478
479
    endif()
    if(WIN32)
480
      string(REPLACE ":" ";" _lib_env2 "$ENV{LIB}")
481
    else()
482
483
484
485
486
487
488
489
      if(APPLE)
	string(REPLACE ":" ";" _lib_env2 "$ENV{DYLD_LIBRARY_PATH}")
      else()
	string(REPLACE ":" ";" _lib_env2 "$ENV{LD_LIBRARY_PATH}")
      endif()
      list(APPEND _lib_env "${_lib_env2}")
      list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
      list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
490
    endif()
491
492
  endif()
  list(REMOVE_DUPLICATES _lib_env)
493

494
495
  # set paths where to look for
  set(PATH_TO_LOOK_FOR "${_lib_env}")
496

497
  if(FFTW_LOOK_FOR_FFTW_SIMPLE)
498
499
    set(FFTW_PREC "f")
    set(FFTW_PREC_TESTFUNC "s")
500
  elseif(FFTW_LOOK_FOR_FFTW_LONG)
501
502
    set(FFTW_PREC "l")
    set(FFTW_PREC_TESTFUNC "l")
503
  elseif(FFTW_LOOK_FOR_FFTW_QUAD)
504
505
    set(FFTW_PREC "q")
    set(FFTW_PREC_TESTFUNC "q")
506
507
508
  else()
    set(FFTW_PREC "")
    set(FFTW_PREC_TESTFUNC "d")
509
  endif()
510

511
512
  set(FFTW_LIBRARIES "")
  set(FFTW_LIBRARY_DIRS "")
513

514
  if(NOT FFTW_LOOK_FOR_MKL)
515

516
    if (FFTW_LOOK_FOR_THREADS)
517
      set(FFTW_libs_to_find "fftw3${FFTW_PREC}_threads;fftw3${FFTW_PREC};fftw3")
518
    elseif (FFTW_LOOK_FOR_OMP)
519
      set(FFTW_libs_to_find "fftw3${FFTW_PREC}_omp;fftw3${FFTW_PREC};fftw3")
520
    else()
521
      set(FFTW_libs_to_find "fftw3${FFTW_PREC};fftw3")
522
    endif()
523
524
525
526
527
528
529
530
531
    if (FFTW_LOOK_FOR_FFTW_QUAD)
      if (NOT FFTW_LOOK_FOR_MKL AND NOT FFTW_LOOK_FOR_ESSL)
        list(APPEND FFTW_libs_to_find "quadmath")
      endif()
    endif()

    if (FFTW_LOOK_FOR_ESSL)
      set(FFTW_libs_to_find "fftw3_essl")
    endif()
532

533
534
    # Try to find the fftw lib in the given paths
    # ----------------------------------------------
535

536
537
    # call cmake macro to find the lib path
    if(FFTW_LIBDIR)
538
      foreach(fftw_lib ${FFTW_libs_to_find})
539
540
541
542
        set(FFTW_${fftw_lib}_LIBRARY "FFTW_${fftw_lib}_LIBRARY-NOTFOUND")
          find_library(FFTW_${fftw_lib}_LIBRARY
          NAMES ${fftw_lib}
          HINTS ${FFTW_LIBDIR})
543
      endforeach()
544
    else()
545
      if(FFTW_DIR)
546
547
548
549
550
551
552
        foreach(fftw_lib ${FFTW_libs_to_find})
          set(FFTW_${fftw_lib}_LIBRARY "FFTW_${fftw_lib}_LIBRARY-NOTFOUND")
          find_library(FFTW_${fftw_lib}_LIBRARY
          NAMES ${fftw_lib}
          HINTS ${FFTW_DIR}
          PATH_SUFFIXES lib lib32 lib64)
        endforeach()
553
      else()
554
555
556
557
558
559
        foreach(fftw_lib ${FFTW_libs_to_find})
          set(FFTW_${fftw_lib}_LIBRARY "FFTW_${fftw_lib}_LIBRARY-NOTFOUND")
          find_library(FFTW_${fftw_lib}_LIBRARY
          NAMES ${fftw_lib}
          HINTS ${PATH_TO_LOOK_FOR})
        endforeach()
560
      endif()
561
    endif()
562

563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
    # If found, add path to cmake variable
    # ------------------------------------
    foreach(fftw_lib ${FFTW_libs_to_find})

      if (FFTW_${fftw_lib}_LIBRARY)
        get_filename_component(${fftw_lib}_lib_path "${FFTW_${fftw_lib}_LIBRARY}" PATH)
        # set cmake variables
        list(APPEND FFTW_LIBRARIES "${FFTW_${fftw_lib}_LIBRARY}")
        list(APPEND FFTW_LIBRARY_DIRS "${${fftw_lib}_lib_path}")
      else ()
        list(APPEND FFTW_LIBRARIES "${FFTW_${fftw_lib}_LIBRARY}")
        if (NOT FFTW_FIND_QUIETLY)
          message(STATUS "Looking for FFTW -- lib ${fftw_lib} not found")
        endif()
      endif ()
      mark_as_advanced(FFTW_${fftw_lib}_LIBRARY)
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
    endforeach()

    # check if one lib is NOTFOUND
    foreach(lib ${FFTW_LIBRARIES})
        if (NOT lib)
            set(FFTW_LIBRARIES "FFTW_LIBRARIES-NOTFOUND")
        endif()
    endforeach()

  endif(NOT FFTW_LOOK_FOR_MKL)

  if (FFTW_LOOK_FOR_MKL OR FFTW_LOOK_FOR_ESSL)

    # FFTW relies on blas libs
    if (FFTW_LOOK_FOR_THREADS)
      if (FFTW_LOOK_FOR_MKL)
        if (BLAS_PAR_LIBRARIES)
          list(APPEND FFTW_LIBRARIES "${BLAS_PAR_LIBRARIES}")
          if (NOT FFTW_FIND_QUIETLY)
            message(STATUS "Multithreaded FFTW has been found: ${FFTW_LIBRARIES}")
          endif()
        else()
          if (NOT FFTW_FIND_QUIETLY)
            if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL)
              message(FATAL_ERROR "FFTW is required but not found.")
            else()
              message(STATUS "Multithreaded FFTW not found.")
            endif()
          endif()
        endif(BLAS_PAR_LIBRARIES)
      elseif (FFTW_LOOK_FOR_ESSL)
        if (FFTW_LIBRARIES AND BLAS_PAR_LIBRARIES)
          list(APPEND FFTW_LIBRARIES "${BLAS_PAR_LIBRARIES}")
          if (NOT FFTW_FIND_QUIETLY)
            message(STATUS "Multithreaded FFTW has been found: ${FFTW_LIBRARIES}")
          endif()
        else()
          if (NOT FFTW_FIND_QUIETLY)
            if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL)
              message(FATAL_ERROR "FFTW is required but not found.")
            else()
              message(STATUS "Multithreaded FFTW not found.")
            endif()
          endif()
        endif(FFTW_LIBRARIES AND BLAS_PAR_LIBRARIES)
      endif()
    else(FFTW_LOOK_FOR_THREADS)
      if (FFTW_LOOK_FOR_MKL)
        if (BLAS_SEQ_LIBRARIES)
          list(APPEND FFTW_LIBRARIES "${BLAS_SEQ_LIBRARIES}")
          if (NOT FFTW_FIND_QUIETLY)
            message(STATUS "FFTW has been found: ${FFTW_LIBRARIES}")
          endif()
        else()
          if (NOT FFTW_FIND_QUIETLY)
           if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL)
             message(FATAL_ERROR "FFTW is required but not found.")
           else()
             message(STATUS "FFTW not found.")
           endif()
          endif()
        endif(BLAS_SEQ_LIBRARIES)
      elseif (FFTW_LOOK_FOR_ESSL)
        if (FFTW_LIBRARIES AND BLAS_SEQ_LIBRARIES)
          list(APPEND FFTW_LIBRARIES "${BLAS_SEQ_LIBRARIES}")
          if (NOT FFTW_FIND_QUIETLY)
            message(STATUS "FFTW has been found: ${FFTW_LIBRARIES}")
          endif()
        else()
          if (NOT FFTW_FIND_QUIETLY)
           if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL)
             message(FATAL_ERROR "FFTW is required but not found.")
           else()
             message(STATUS "FFTW not found.")
           endif()
          endif()
        endif(FFTW_LIBRARIES AND BLAS_SEQ_LIBRARIES)
      endif()
    endif(FFTW_LOOK_FOR_THREADS)

    if (BLAS_LIBRARY_DIRS)
      list(APPEND FFTW_LIBRARY_DIRS "${BLAS_LIBRARY_DIRS}")
    else()
663
      if (NOT FFTW_FIND_QUIETLY)
664
        message(WARNING "FFTW_LIBRARY_DIRS may not be complete because BLAS_LIBRARY_DIRS is empty.")
665
      endif()
666
    endif()
667

668
  endif(FFTW_LOOK_FOR_MKL OR FFTW_LOOK_FOR_ESSL)
669

670
671
  list(REMOVE_DUPLICATES FFTW_INCLUDE_DIRS)
  list(REMOVE_DUPLICATES FFTW_LIBRARY_DIRS)
672

673
674
675
676
677
678
679
  # check if one lib is NOTFOUND
  foreach(lib ${FFTW_LIBRARIES})
      if (NOT lib)
          set(FFTW_LIBRARIES "FFTW_LIBRARIES-NOTFOUND")
      endif()
  endforeach()

680
681
  # check a function to validate the find
  if(FFTW_LIBRARIES)
682
683
684
685
686
687
688
689
690

    set(REQUIRED_FLAGS)
    set(REQUIRED_LDFLAGS)
    set(REQUIRED_INCDIRS)
    set(REQUIRED_LIBDIRS)
    set(REQUIRED_LIBS)

    # FFTW
    if (FFTW_INCLUDE_DIRS)
691
      set(REQUIRED_INCDIRS "${FFTW_INCLUDE_DIRS}")
692
693
    endif()
    if (FFTW_LIBRARY_DIRS)
694
      set(REQUIRED_LIBDIRS "${FFTW_LIBRARY_DIRS}")
695
696
697
698
    endif()
    set(REQUIRED_LIBS "${FFTW_LIBRARIES}")
    # THREADS
    if (FFTW_LOOK_FOR_THREADS)
699
      list(APPEND REQUIRED_LIBS "${CMAKE_THREAD_LIBS_INIT}")
700
701
702
    endif()
    # OMP
    if(FFTW_LOOK_FOR_OMP)
703
704
705
706
707
708
709
710
711
      set(REQUIRED_FLAGS "-fopenmp")
      #if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
      #  # either gomp ...
      #  list(APPEND REQUIRED_LIBS "-lgomp")
      #  # or iomp5
      #  list(APPEND REQUIRED_LIBS "-liomp5")
      #elseif (CMAKE_C_COMPILER_ID STREQUAL "Intel")
      #  list(APPEND REQUIRED_LIBS "-liomp5")
      #endif()
712
713
714
    endif()
    # MKL
    if(FFTW_LOOK_FOR_MKL)
715
716
      list(APPEND REQUIRED_LIBS "${CMAKE_THREAD_LIBS_INIT}")
      if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
717
        list(APPEND REQUIRED_LDFLAGS "-Wl,--no-as-needed")
718
      endif()
719
    endif()
Florent Pruvost's avatar
Florent Pruvost committed
720
721
722
    # m
    find_library(M_LIBRARY NAMES m)
    if(M_LIBRARY)
723
      list(APPEND REQUIRED_LIBS "-lm")
724
    endif()
725

726
727
728
729
730
    # set required libraries for link
    set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
    set(CMAKE_REQUIRED_LIBRARIES)
    list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}")
    foreach(lib_dir ${REQUIRED_LIBDIRS})
731
      list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
732
733
734
735
736
737
738
739
    endforeach()
    list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
    list(APPEND CMAKE_REQUIRED_FLAGS "${REQUIRED_FLAGS}")
    string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")

    # test link
    unset(FFTW_WORKS CACHE)
    include(CheckFunctionExists)
740
741
742
743
744
    if (FFTW_LOOK_FOR_ESSL)
      check_function_exists(${FFTW_PREC_TESTFUNC}fftw_execute FFTW_WORKS)
    else()
      check_function_exists(${FFTW_PREC_TESTFUNC}fftw_execute_ FFTW_WORKS)
    endif()
745
746
747
    mark_as_advanced(FFTW_WORKS)

    if(FFTW_WORKS)
748
749
750
751
752
753
754
755
756
      # save link with dependencies
      set(FFTW_LIBRARIES_DEP "${REQUIRED_LIBS}")
      set(FFTW_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}")
      set(FFTW_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}")
      set(FFTW_C_FLAGS "${REQUIRED_FLAGS}")
      set(FFTW_LINKER_FLAGS "${REQUIRED_LDFLAGS}")
      list(REMOVE_DUPLICATES FFTW_LIBRARY_DIRS_DEP)
      list(REMOVE_DUPLICATES FFTW_INCLUDE_DIRS_DEP)
      list(REMOVE_DUPLICATES FFTW_LINKER_FLAGS)
757
    else()
758
759
760
761
762
763
764
      if(NOT FFTW_FIND_QUIETLY)
	message(STATUS "Looking for FFTW : test of ${FFTW_PREC_TESTFUNC}fftw_execute_ with fftw library fails")
	message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
	message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
	message(STATUS "CMAKE_REQUIRED_FLAGS: ${CMAKE_REQUIRED_FLAGS}")
	message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
      endif()
765
    else()
766
      set(FFTW_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
767
768
769
770
    endif()
    set(CMAKE_REQUIRED_INCLUDES)
    set(CMAKE_REQUIRED_FLAGS)
    set(CMAKE_REQUIRED_LIBRARIES)
771
772
  endif(FFTW_LIBRARIES)

773
774
775
776
777
778
endif( (NOT PKG_CONFIG_EXECUTABLE) OR
       (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR
       FFTW_GIVEN_BY_USER OR
       FFTW_LOOK_FOR_MKL  OR
       FFTW_LOOK_FOR_ESSL
     )
779

780
if (FFTW_LIBRARIES)
781
782
783
784
785
786
787
788
  list(GET FFTW_LIBRARIES 0 first_lib)
  get_filename_component(first_lib_path "${first_lib}" PATH)
  if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)")
    string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}")
    set(FFTW_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of FFTW library" FORCE)
  else()
    set(FFTW_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of FFTW library" FORCE)
  endif()
789
endif()
790
791
792
793

# check that FFTW has been found
# -------------------------------
include(FindPackageHandleStandardArgs)
794
if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR (FFTW_GIVEN_BY_USER) )
795
find_package_handle_standard_args(FFTW DEFAULT_MSG
796
797
798
  FFTW_LIBRARIES
  FFTW_INCLUDE_DIRS
  FFTW_WORKS)
799
800
801
802
803
else()
find_package_handle_standard_args(FFTW DEFAULT_MSG
  FFTW_LIBRARIES
  FFTW_WORKS)
endif()