1# Find BLAS library
2#
3# This module finds an installed library that implements the BLAS
4# linear-algebra interface (see http://www.netlib.org/blas/).
5# The list of libraries searched for is mainly taken
6# from the autoconf macro file, acx_blas.m4 (distributed at
7# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
8#
9# This module sets the following variables:
10#  BLAS_FOUND - set to true if a library implementing the BLAS interface
11#    is found
12#  BLAS_INCLUDE_DIR - Directories containing the BLAS header files
13#  BLAS_DEFINITIONS - Compilation options to use BLAS
14#  BLAS_LINKER_FLAGS - Linker flags to use BLAS (excluding -l
15#    and -L).
16#  BLAS_LIBRARIES_DIR - Directories containing the BLAS libraries.
17#     May be null if BLAS_LIBRARIES contains libraries name using full path.
18#  BLAS_LIBRARIES - List of libraries to link against BLAS interface.
19#     May be null if the compiler supports auto-link (e.g. VC++).
20#  BLAS_USE_FILE - The name of the cmake module to include to compile
21#     applications or libraries using BLAS.
22#
23# This module was modified by CGAL team:
24# - find libraries for a C++ compiler, instead of Fortran
25# - added BLAS_INCLUDE_DIR, BLAS_DEFINITIONS and BLAS_LIBRARIES_DIR
26# - removed BLAS95_LIBRARIES
27
28include(CheckFunctionExists)
29
30
31# This macro checks for the existence of the combination of fortran libraries
32# given by _list.  If the combination is found, this macro checks (using the
33# check_function_exists macro) whether can link against that library
34# combination using the name of a routine given by _name using the linker
35# flags given by _flags.  If the combination of libraries is found and passes
36# the link test, LIBRARIES is set to the list of complete library paths that
37# have been found and DEFINITIONS to the required definitions.
38# Otherwise, LIBRARIES is set to FALSE.
39# N.B. _prefix is the prefix applied to the names of all cached variables that
40# are generated internally and marked advanced by this macro.
41macro(check_fortran_libraries DEFINITIONS LIBRARIES _prefix _name _flags _list _path)
42  #message("DEBUG: check_fortran_libraries(${_list} in ${_path})")
43
44  # Check for the existence of the libraries given by _list
45  set(_libraries_found TRUE)
46  set(_libraries_work FALSE)
47  set(${DEFINITIONS} "")
48  set(${LIBRARIES} "")
49  set(_combined_name)
50  foreach(_library ${_list})
51    set(_combined_name ${_combined_name}_${_library})
52
53    if(_libraries_found)
54      # search first in ${_path}
55      find_library(${_prefix}_${_library}_LIBRARY
56                  NAMES ${_library}
57                  PATHS ${_path} NO_DEFAULT_PATH
58                  )
59      # if not found, search in environment variables and system
60      if ( WIN32 )
61        find_library(${_prefix}_${_library}_LIBRARY
62                    NAMES ${_library}
63                    PATHS ENV LIB
64                    )
65      elseif ( APPLE )
66        find_library(${_prefix}_${_library}_LIBRARY
67                    NAMES ${_library}
68                    PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH
69                    )
70      else ()
71        find_library(${_prefix}_${_library}_LIBRARY
72                    NAMES ${_library}
73                    PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH
74                    )
75      endif()
76      mark_as_advanced(${_prefix}_${_library}_LIBRARY)
77      set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
78      set(_libraries_found ${${_prefix}_${_library}_LIBRARY})
79    endif(_libraries_found)
80  endforeach(_library ${_list})
81  if(_libraries_found)
82    set(_libraries_found ${${LIBRARIES}})
83  endif()
84
85  # Test this combination of libraries with the Fortran/f2c interface.
86  # We test the Fortran interface first as it is well standardized.
87  if(_libraries_found AND NOT _libraries_work)
88    set(${DEFINITIONS}  "-D${_prefix}_USE_F2C")
89    set(${LIBRARIES}    ${_libraries_found})
90    # Some C++ linkers require the f2c library to link with Fortran libraries.
91    # I do not know which ones, thus I just add the f2c library if it is available.
92    find_package( F2C QUIET )
93    if ( F2C_FOUND )
94      set(${DEFINITIONS}  ${${DEFINITIONS}} ${F2C_DEFINITIONS})
95      set(${LIBRARIES}    ${${LIBRARIES}} ${F2C_LIBRARIES})
96    endif()
97    set(CMAKE_REQUIRED_DEFINITIONS  ${${DEFINITIONS}})
98    set(CMAKE_REQUIRED_LIBRARIES    ${_flags} ${${LIBRARIES}})
99    #message("DEBUG: CMAKE_REQUIRED_DEFINITIONS = ${CMAKE_REQUIRED_DEFINITIONS}")
100    #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
101    # Check if function exists with f2c calling convention (ie a trailing underscore)
102    check_function_exists(${_name}_ ${_prefix}_${_name}_${_combined_name}_f2c_WORKS)
103    set(CMAKE_REQUIRED_DEFINITIONS} "")
104    set(CMAKE_REQUIRED_LIBRARIES    "")
105    mark_as_advanced(${_prefix}_${_name}_${_combined_name}_f2c_WORKS)
106    set(_libraries_work ${${_prefix}_${_name}_${_combined_name}_f2c_WORKS})
107  endif(_libraries_found AND NOT _libraries_work)
108
109  # If not found, test this combination of libraries with a C interface.
110  # A few implementations (ie ACML) provide a C interface. Unfortunately, there is no standard.
111  if(_libraries_found AND NOT _libraries_work)
112    set(${DEFINITIONS} "")
113    set(${LIBRARIES}   ${_libraries_found})
114    set(CMAKE_REQUIRED_DEFINITIONS "")
115    set(CMAKE_REQUIRED_LIBRARIES   ${_flags} ${${LIBRARIES}})
116    #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
117    check_function_exists(${_name} ${_prefix}_${_name}${_combined_name}_WORKS)
118    set(CMAKE_REQUIRED_LIBRARIES "")
119    mark_as_advanced(${_prefix}_${_name}${_combined_name}_WORKS)
120    set(_libraries_work ${${_prefix}_${_name}${_combined_name}_WORKS})
121  endif(_libraries_found AND NOT _libraries_work)
122
123  # on failure
124  if(NOT _libraries_work)
125    set(${DEFINITIONS} "")
126    set(${LIBRARIES}   FALSE)
127  endif()
128  #message("DEBUG: ${DEFINITIONS} = ${${DEFINITIONS}}")
129  #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
130endmacro(check_fortran_libraries)
131
132
133#
134# main
135#
136
137# Is it already configured?
138if (BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)
139
140  set(BLAS_FOUND TRUE)
141
142else()
143
144  # reset variables
145  set( BLAS_INCLUDE_DIR "" )
146  set( BLAS_DEFINITIONS "" )
147  set( BLAS_LINKER_FLAGS "" )
148  set( BLAS_LIBRARIES "" )
149  set( BLAS_LIBRARIES_DIR "" )
150
151    #
152    # If Unix, search for BLAS function in possible libraries
153    #
154
155    # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
156    if(NOT BLAS_LIBRARIES)
157      check_fortran_libraries(
158      BLAS_DEFINITIONS
159      BLAS_LIBRARIES
160      BLAS
161      sgemm
162      ""
163      "cblas;f77blas;atlas"
164      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
165      )
166    endif()
167
168    # BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
169    if(NOT BLAS_LIBRARIES)
170      check_fortran_libraries(
171      BLAS_DEFINITIONS
172      BLAS_LIBRARIES
173      BLAS
174      sgemm
175      ""
176      "sgemm;dgemm;blas"
177      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
178      )
179    endif()
180
181    # BLAS in Alpha CXML library?
182    if(NOT BLAS_LIBRARIES)
183      check_fortran_libraries(
184      BLAS_DEFINITIONS
185      BLAS_LIBRARIES
186      BLAS
187      sgemm
188      ""
189      "cxml"
190      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
191      )
192    endif()
193
194    # BLAS in Alpha DXML library? (now called CXML, see above)
195    if(NOT BLAS_LIBRARIES)
196      check_fortran_libraries(
197      BLAS_DEFINITIONS
198      BLAS_LIBRARIES
199      BLAS
200      sgemm
201      ""
202      "dxml"
203      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
204      )
205    endif()
206
207    # BLAS in Sun Performance library?
208    if(NOT BLAS_LIBRARIES)
209      check_fortran_libraries(
210      BLAS_DEFINITIONS
211      BLAS_LIBRARIES
212      BLAS
213      sgemm
214      "-xlic_lib=sunperf"
215      "sunperf;sunmath"
216      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
217      )
218      if(BLAS_LIBRARIES)
219        # Extra linker flag
220        set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
221      endif()
222    endif()
223
224    # BLAS in SCSL library?  (SGI/Cray Scientific Library)
225    if(NOT BLAS_LIBRARIES)
226      check_fortran_libraries(
227      BLAS_DEFINITIONS
228      BLAS_LIBRARIES
229      BLAS
230      sgemm
231      ""
232      "scsl"
233      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
234      )
235    endif()
236
237    # BLAS in SGIMATH library?
238    if(NOT BLAS_LIBRARIES)
239      check_fortran_libraries(
240      BLAS_DEFINITIONS
241      BLAS_LIBRARIES
242      BLAS
243      sgemm
244      ""
245      "complib.sgimath"
246      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
247      )
248    endif()
249
250    # BLAS in IBM ESSL library? (requires generic BLAS lib, too)
251    if(NOT BLAS_LIBRARIES)
252      check_fortran_libraries(
253      BLAS_DEFINITIONS
254      BLAS_LIBRARIES
255      BLAS
256      sgemm
257      ""
258      "essl;blas"
259      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
260      )
261    endif()
262
263    #BLAS in intel mkl 10 library? (em64t 64bit)
264    if(NOT BLAS_LIBRARIES)
265      check_fortran_libraries(
266      BLAS_DEFINITIONS
267      BLAS_LIBRARIES
268      BLAS
269      sgemm
270      ""
271      "mkl_intel_lp64;mkl_intel_thread;mkl_core;guide;pthread"
272      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
273      )
274    endif()
275
276    ### windows version of intel mkl 10?
277    if(NOT BLAS_LIBRARIES)
278      check_fortran_libraries(
279      BLAS_DEFINITIONS
280      BLAS_LIBRARIES
281      BLAS
282      SGEMM
283      ""
284      "mkl_c_dll;mkl_intel_thread_dll;mkl_core_dll;libguide40"
285      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
286      )
287    endif()
288
289    #older versions of intel mkl libs
290
291    # BLAS in intel mkl library? (shared)
292    if(NOT BLAS_LIBRARIES)
293      check_fortran_libraries(
294      BLAS_DEFINITIONS
295      BLAS_LIBRARIES
296      BLAS
297      sgemm
298      ""
299      "mkl;guide;pthread"
300      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
301      )
302    endif()
303
304    #BLAS in intel mkl library? (static, 32bit)
305    if(NOT BLAS_LIBRARIES)
306      check_fortran_libraries(
307      BLAS_DEFINITIONS
308      BLAS_LIBRARIES
309      BLAS
310      sgemm
311      ""
312      "mkl_ia32;guide;pthread"
313      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
314      )
315    endif()
316
317    #BLAS in intel mkl library? (static, em64t 64bit)
318    if(NOT BLAS_LIBRARIES)
319      check_fortran_libraries(
320      BLAS_DEFINITIONS
321      BLAS_LIBRARIES
322      BLAS
323      sgemm
324      ""
325      "mkl_em64t;guide;pthread"
326      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
327      )
328    endif()
329
330    #BLAS in acml library?
331    if(NOT BLAS_LIBRARIES)
332      check_fortran_libraries(
333      BLAS_DEFINITIONS
334      BLAS_LIBRARIES
335      BLAS
336      sgemm
337      ""
338      "acml"
339      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
340      )
341    endif()
342
343    # Apple BLAS library?
344    if(NOT BLAS_LIBRARIES)
345      check_fortran_libraries(
346      BLAS_DEFINITIONS
347      BLAS_LIBRARIES
348      BLAS
349      sgemm
350      ""
351      "Accelerate"
352      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
353      )
354    endif()
355
356    if ( NOT BLAS_LIBRARIES )
357      check_fortran_libraries(
358      BLAS_DEFINITIONS
359      BLAS_LIBRARIES
360      BLAS
361      sgemm
362      ""
363      "vecLib"
364      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
365      )
366    endif ( NOT BLAS_LIBRARIES )
367
368    # Generic BLAS library?
369    # This configuration *must* be the last try as this library is notably slow.
370    if ( NOT BLAS_LIBRARIES )
371      check_fortran_libraries(
372      BLAS_DEFINITIONS
373      BLAS_LIBRARIES
374      BLAS
375      sgemm
376      ""
377      "blas"
378      "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"
379      )
380    endif()
381
382  if(BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)
383    set(BLAS_FOUND TRUE)
384  else()
385    set(BLAS_FOUND FALSE)
386  endif()
387
388  if(NOT BLAS_FIND_QUIETLY)
389    if(BLAS_FOUND)
390      message(STATUS "A library with BLAS API found.")
391    else(BLAS_FOUND)
392      if(BLAS_FIND_REQUIRED)
393        message(FATAL_ERROR "A required library with BLAS API not found. Please specify library location.")
394      else()
395        message(STATUS "A library with BLAS API not found. Please specify library location.")
396      endif()
397    endif(BLAS_FOUND)
398  endif(NOT BLAS_FIND_QUIETLY)
399
400  # Add variables to cache
401  set( BLAS_INCLUDE_DIR   "${BLAS_INCLUDE_DIR}"
402                          CACHE PATH "Directories containing the BLAS header files" FORCE )
403  set( BLAS_DEFINITIONS   "${BLAS_DEFINITIONS}"
404                          CACHE STRING "Compilation options to use BLAS" FORCE )
405  set( BLAS_LINKER_FLAGS  "${BLAS_LINKER_FLAGS}"
406                          CACHE STRING "Linker flags to use BLAS" FORCE )
407  set( BLAS_LIBRARIES     "${BLAS_LIBRARIES}"
408                          CACHE FILEPATH "BLAS libraries name" FORCE )
409  set( BLAS_LIBRARIES_DIR "${BLAS_LIBRARIES_DIR}"
410                          CACHE PATH "Directories containing the BLAS libraries" FORCE )
411
412  #message("DEBUG: BLAS_INCLUDE_DIR = ${BLAS_INCLUDE_DIR}")
413  #message("DEBUG: BLAS_DEFINITIONS = ${BLAS_DEFINITIONS}")
414  #message("DEBUG: BLAS_LINKER_FLAGS = ${BLAS_LINKER_FLAGS}")
415  #message("DEBUG: BLAS_LIBRARIES = ${BLAS_LIBRARIES}")
416  #message("DEBUG: BLAS_LIBRARIES_DIR = ${BLAS_LIBRARIES_DIR}")
417  #message("DEBUG: BLAS_FOUND = ${BLAS_FOUND}")
418
419endif(BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)
420