1# Find LAPACK library
2#
3# This module finds an installed library that implements the LAPACK
4# linear-algebra interface (see http://www.netlib.org/lapack/).
5# The approach follows mostly that taken for the autoconf macro file, acx_lapack.m4
6# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
7#
8# This module sets the following variables:
9#  LAPACK_FOUND - set to true if a library implementing the LAPACK interface
10#    is found
11#  LAPACK_INCLUDE_DIR - Directories containing the LAPACK header files
12#  LAPACK_DEFINITIONS - Compilation options to use LAPACK
13#  LAPACK_LINKER_FLAGS - Linker flags to use LAPACK (excluding -l
14#    and -L).
15#  LAPACK_LIBRARIES_DIR - Directories containing the LAPACK libraries.
16#     May be null if LAPACK_LIBRARIES contains libraries name using full path.
17#  LAPACK_LIBRARIES - List of libraries to link against LAPACK interface.
18#     May be null if the compiler supports auto-link (e.g. VC++).
19#  LAPACK_USE_FILE - The name of the cmake module to include to compile
20#     applications or libraries using LAPACK.
21#
22# This module was modified by CGAL team:
23# - find libraries for a C++ compiler, instead of Fortran
24# - added LAPACK_INCLUDE_DIR, LAPACK_DEFINITIONS and LAPACK_LIBRARIES_DIR
25# - removed LAPACK95_LIBRARIES
26
27
28include(CheckFunctionExists)
29
30# This macro checks for the existence of the combination of fortran libraries
31# given by _list.  If the combination is found, this macro checks (using the
32# check_function_exists macro) whether can link against that library
33# combination using the name of a routine given by _name using the linker
34# flags given by _flags.  If the combination of libraries is found and passes
35# the link test, LIBRARIES is set to the list of complete library paths that
36# have been found and DEFINITIONS to the required definitions.
37# Otherwise, LIBRARIES is set to FALSE.
38# N.B. _prefix is the prefix applied to the names of all cached variables that
39# are generated internally and marked advanced by this macro.
40macro(check_lapack_libraries DEFINITIONS LIBRARIES _prefix _name _flags _list _blas _path)
41  #message("DEBUG: check_lapack_libraries(${_list} in ${_path} with ${_blas})")
42
43  # Check for the existence of the libraries given by _list
44  set(_libraries_found TRUE)
45  set(_libraries_work FALSE)
46  set(${DEFINITIONS} "")
47  set(${LIBRARIES} "")
48  set(_combined_name)
49  foreach(_library ${_list})
50    set(_combined_name ${_combined_name}_${_library})
51
52    if(_libraries_found)
53      # search first in ${_path}
54      find_library(${_prefix}_${_library}_LIBRARY
55                  NAMES ${_library}
56                  PATHS ${_path} NO_DEFAULT_PATH
57                  )
58      # if not found, search in environment variables and system
59      if ( WIN32 )
60        find_library(${_prefix}_${_library}_LIBRARY
61                    NAMES ${_library}
62                    PATHS ENV LIB
63                    )
64      elseif ( APPLE )
65        find_library(${_prefix}_${_library}_LIBRARY
66                    NAMES ${_library}
67                    PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH
68                    )
69      else ()
70        find_library(${_prefix}_${_library}_LIBRARY
71                    NAMES ${_library}
72                    PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH
73                    )
74      endif()
75      mark_as_advanced(${_prefix}_${_library}_LIBRARY)
76      set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
77      set(_libraries_found ${${_prefix}_${_library}_LIBRARY})
78    endif(_libraries_found)
79  endforeach(_library ${_list})
80  if(_libraries_found)
81    set(_libraries_found ${${LIBRARIES}})
82  endif()
83
84  # Test this combination of libraries with the Fortran/f2c interface.
85  # We test the Fortran interface first as it is well standardized.
86  if(_libraries_found AND NOT _libraries_work)
87    set(${DEFINITIONS}  "-D${_prefix}_USE_F2C")
88    set(${LIBRARIES}    ${_libraries_found})
89    # Some C++ linkers require the f2c library to link with Fortran libraries.
90    # I do not know which ones, thus I just add the f2c library if it is available.
91    find_package( F2C QUIET )
92    if ( F2C_FOUND )
93      set(${DEFINITIONS}  ${${DEFINITIONS}} ${F2C_DEFINITIONS})
94      set(${LIBRARIES}    ${${LIBRARIES}} ${F2C_LIBRARIES})
95    endif()
96    set(CMAKE_REQUIRED_DEFINITIONS  ${${DEFINITIONS}})
97    set(CMAKE_REQUIRED_LIBRARIES    ${_flags} ${${LIBRARIES}} ${_blas})
98    #message("DEBUG: CMAKE_REQUIRED_DEFINITIONS = ${CMAKE_REQUIRED_DEFINITIONS}")
99    #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
100    # Check if function exists with f2c calling convention (ie a trailing underscore)
101    check_function_exists(${_name}_ ${_prefix}_${_name}_${_combined_name}_f2c_WORKS)
102    set(CMAKE_REQUIRED_DEFINITIONS} "")
103    set(CMAKE_REQUIRED_LIBRARIES    "")
104    mark_as_advanced(${_prefix}_${_name}_${_combined_name}_f2c_WORKS)
105    set(_libraries_work ${${_prefix}_${_name}_${_combined_name}_f2c_WORKS})
106  endif(_libraries_found AND NOT _libraries_work)
107
108  # If not found, test this combination of libraries with a C interface.
109  # A few implementations (ie ACML) provide a C interface. Unfortunately, there is no standard.
110  if(_libraries_found AND NOT _libraries_work)
111    set(${DEFINITIONS} "")
112    set(${LIBRARIES}   ${_libraries_found})
113    set(CMAKE_REQUIRED_DEFINITIONS "")
114    set(CMAKE_REQUIRED_LIBRARIES   ${_flags} ${${LIBRARIES}} ${_blas})
115    #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
116    check_function_exists(${_name} ${_prefix}_${_name}${_combined_name}_WORKS)
117    set(CMAKE_REQUIRED_LIBRARIES "")
118    mark_as_advanced(${_prefix}_${_name}${_combined_name}_WORKS)
119    set(_libraries_work ${${_prefix}_${_name}${_combined_name}_WORKS})
120  endif(_libraries_found AND NOT _libraries_work)
121
122  # on failure
123  if(NOT _libraries_work)
124    set(${DEFINITIONS} "")
125    set(${LIBRARIES}   FALSE)
126  endif()
127  #message("DEBUG: ${DEFINITIONS} = ${${DEFINITIONS}}")
128  #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
129endmacro(check_lapack_libraries)
130
131
132#
133# main
134#
135
136# LAPACK requires BLAS
137if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
138  find_package(BLAS)
139else()
140  find_package(BLAS REQUIRED)
141endif()
142
143if (NOT BLAS_FOUND)
144
145  message(STATUS "LAPACK requires BLAS.")
146  set(LAPACK_FOUND FALSE)
147
148# Is it already configured?
149elseif (LAPACK_LIBRARIES_DIR OR LAPACK_LIBRARIES)
150
151  set(LAPACK_FOUND TRUE)
152
153else()
154
155  # reset variables
156  set( LAPACK_INCLUDE_DIR "" )
157  set( LAPACK_DEFINITIONS "" )
158  set( LAPACK_LINKER_FLAGS "" ) # unused (yet)
159  set( LAPACK_LIBRARIES "" )
160  set( LAPACK_LIBRARIES_DIR "" )
161
162    #
163    # If Unix, search for LAPACK function in possible libraries
164    #
165
166    #intel mkl lapack?
167    if(NOT LAPACK_LIBRARIES)
168      check_lapack_libraries(
169      LAPACK_DEFINITIONS
170      LAPACK_LIBRARIES
171      LAPACK
172      cheev
173      ""
174      "mkl_lapack"
175      "${BLAS_LIBRARIES}"
176      "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"
177      )
178    endif()
179
180    #acml lapack?
181    if(NOT LAPACK_LIBRARIES)
182      check_lapack_libraries(
183      LAPACK_DEFINITIONS
184      LAPACK_LIBRARIES
185      LAPACK
186      cheev
187      ""
188      "acml"
189      "${BLAS_LIBRARIES}"
190      "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"
191      )
192    endif()
193
194    # Apple LAPACK library?
195    if(NOT LAPACK_LIBRARIES)
196      check_lapack_libraries(
197      LAPACK_DEFINITIONS
198      LAPACK_LIBRARIES
199      LAPACK
200      cheev
201      ""
202      "Accelerate"
203      "${BLAS_LIBRARIES}"
204      "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"
205      )
206    endif()
207
208    if ( NOT LAPACK_LIBRARIES )
209      check_lapack_libraries(
210      LAPACK_DEFINITIONS
211      LAPACK_LIBRARIES
212      LAPACK
213      cheev
214      ""
215      "vecLib"
216      "${BLAS_LIBRARIES}"
217      "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"
218      )
219    endif ( NOT LAPACK_LIBRARIES )
220
221    # Generic LAPACK library?
222    # This configuration *must* be the last try as this library is notably slow.
223    if ( NOT LAPACK_LIBRARIES )
224      check_lapack_libraries(
225      LAPACK_DEFINITIONS
226      LAPACK_LIBRARIES
227      LAPACK
228      cheev
229      ""
230      "lapack"
231      "${BLAS_LIBRARIES}"
232      "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"
233      )
234    endif()
235
236  if(LAPACK_LIBRARIES_DIR OR LAPACK_LIBRARIES)
237    set(LAPACK_FOUND TRUE)
238  else()
239    set(LAPACK_FOUND FALSE)
240  endif()
241
242  if(NOT LAPACK_FIND_QUIETLY)
243    if(LAPACK_FOUND)
244      message(STATUS "A library with LAPACK API found.")
245    else(LAPACK_FOUND)
246      if(LAPACK_FIND_REQUIRED)
247        message(FATAL_ERROR "A required library with LAPACK API not found. Please specify library location.")
248      else()
249        message(STATUS "A library with LAPACK API not found. Please specify library location.")
250      endif()
251    endif(LAPACK_FOUND)
252  endif(NOT LAPACK_FIND_QUIETLY)
253
254  # Add variables to cache
255  set( LAPACK_INCLUDE_DIR   "${LAPACK_INCLUDE_DIR}"
256                            CACHE PATH "Directories containing the LAPACK header files" FORCE )
257  set( LAPACK_DEFINITIONS   "${LAPACK_DEFINITIONS}"
258                            CACHE STRING "Compilation options to use LAPACK" FORCE )
259  set( LAPACK_LINKER_FLAGS  "${LAPACK_LINKER_FLAGS}"
260                            CACHE STRING "Linker flags to use LAPACK" FORCE )
261  set( LAPACK_LIBRARIES     "${LAPACK_LIBRARIES}"
262                            CACHE FILEPATH "LAPACK libraries name" FORCE )
263  set( LAPACK_LIBRARIES_DIR "${LAPACK_LIBRARIES_DIR}"
264                            CACHE PATH "Directories containing the LAPACK libraries" FORCE )
265
266  #message("DEBUG: LAPACK_INCLUDE_DIR = ${LAPACK_INCLUDE_DIR}")
267  #message("DEBUG: LAPACK_DEFINITIONS = ${LAPACK_DEFINITIONS}")
268  #message("DEBUG: LAPACK_LINKER_FLAGS = ${LAPACK_LINKER_FLAGS}")
269  #message("DEBUG: LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}")
270  #message("DEBUG: LAPACK_LIBRARIES_DIR = ${LAPACK_LIBRARIES_DIR}")
271  #message("DEBUG: LAPACK_FOUND = ${LAPACK_FOUND}")
272
273endif(NOT BLAS_FOUND)
274