1# $Id: ConfigureLapack.cmake 217 2013-11-25 21:59:49Z tplante $
2# $URL: https://software.sandia.gov/svn/hopspack/trunk/ConfigureLapack.cmake $
3#
4# ************************************************************************
5#         HOPSPACK: Hybrid Optimization Parallel Search Package
6#                 Copyright 2009-2013 Sandia Corporation
7#
8#   Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9#   the U.S. Government retains certain rights in this software.
10# ************************************************************************
11
12
13#---- Define a boolean user option "lapack" that can be set from the
14#---- command line ("-Dlapack=true" or "=on" or "=yes"),
15#---- or from the CMake cache.
16
17OPTION (lapack "TRUE means link with LAPACK/BLAS" TRUE)
18
19#---- If FALSE then do not link LAPACK, with the consequence that HOPSPACK
20#---- cannot accept problems with linear constraints.
21#----
22#---- If TRUE then find an LAPACK/BLAS library for linking.
23#---- To link a preferred library, set using command line options or edit
24#---- this file as described below in the comments after "ELSE (NOT lapack)".
25#----
26#---- Command line options:
27#----   -DLAPACK_LIBS=
28#----   -DLAPACK_ADD_LIBS=
29#---- The second option is for any additional libraries required to resolve
30#---- missing symbols in the LAPACK libraries.
31#---- Remember that arguments are usually enclosed in double quotes, and
32#---- multiple libraries are separated by a semicolon; eg:
33#----   -DLAPACK_LIBS="c:\Temp\lapack.a;c:\Temp\blas.a"
34#----
35#---- If TRUE, then on return sets the variables:
36#----   LAPACK_LIBS            - for linking
37#----   LAPACK_ADD_LIBS        - for linking
38#----   HAVE_LAPACK            - for header files
39#----   HAVE_BLAS_F2C_WRAPPERS - for header files
40
41#---- Set HOPSPACK_TEST_LAPACK_FUNCS=FALSE before including this file
42#---- to bypass the calls to check_for_lapack_function below.  This
43#---- macro fails to detect the presence of LAPACK functions within
44#---- Fortran libraries on Windows.
45IF (NOT DEFINED HOPSPACK_TEST_LAPACK_FUNCS)
46    SET(HOPSPACK_TEST_LAPACK_FUNCS TRUE)
47ENDIF ()
48
49
50##########################################################################
51#---- Macro to check for an LAPACK/BLAS function in each of the libraries
52#---- specified by variable LAPACK_LIBS.  The macro tries appending
53#---- an underscore and prefixing with "f2c_".
54#---- On return sets the variables:
55#----   HAVE_BLAS_F2C_WRAPPERS - TRUE or undefined
56#----   LAPACK_ADD_LIBS        - may append another library
57#----   HAVE_FN_${FNNAME}      - TRUE or FALSE
58
59MACRO (check_for_lapack_function FNNAME)
60
61    IF (NOT DEFINED LAPACK_LIBS)
62        MESSAGE (FATAL_ERROR "HOPSPACK: Need to define an LAPACK/BLAS library.")
63    ENDIF (NOT DEFINED LAPACK_LIBS)
64
65    #---- First, try with the built-in utility CHECK_FUNCTION_EXISTS.
66    #---- Unfortunately, this seems able to test only one library in isolation.
67    INCLUDE (CheckFunctionExists)
68
69    #---- Try appending an underscore.
70    FOREACH (loopVar  ${LAPACK_LIBS})
71        IF (NOT HAVEFN_${FNNAME})
72            SET (CMAKE_REQUIRED_LIBRARIES ${loopVar})
73            CHECK_FUNCTION_EXISTS (${FNNAME}_ HAVEFN_${FNNAME})
74        ENDIF (NOT HAVEFN_${FNNAME})
75    ENDFOREACH (loopVar)
76
77    #---- Try prefixing f2c_ in case the library uses F2C wrappers.
78    IF (NOT HAVEFN_${FNNAME})
79        FOREACH (loopVar  ${LAPACK_LIBS})
80            IF (NOT HAVEFN_${FNNAME})
81                CHECK_FUNCTION_EXISTS (f2c_${FNNAME} HAVEFN_f2c_${FNNAME})
82
83                IF (HAVEFN_f2c_${FNNAME})
84                    SET (HAVEFN_${FNNAME} TRUE)
85                    #---- The HOPSPACK header file needs to know about wrappers.
86                    SET (HAVE_BLAS_F2C_WRAPPERS TRUE)
87                ENDIF (HAVEFN_f2c_${FNNAME})
88            ENDIF (NOT HAVEFN_${FNNAME})
89        ENDFOREACH (loopVar)
90    ENDIF (NOT HAVEFN_${FNNAME})
91
92    #---- The CHECK_FUNCTION_EXISTS utility failed to find the function.
93
94    #---- Try compiling directly, with all the libraries at once.
95    #---- (Note that if LAPACK_LIBS is not a full path, then need to add
96    #----    CMAKE_FLAGS -DLINK_DIRECTORIES:STRING=path )
97    IF (NOT HAVEFN_${FNNAME})
98        SET (ALL_LIB_LIST ${LAPACK_LIBS} ${LAPACK_ADD_LIBS})
99        TRY_COMPILE (HAVEFN_${FNNAME}
100                     ${HOPSPACK_BINARY_DIR}/test
101                     ${HOPSPACK_SOURCE_DIR}/test/cmake_test_link_lapack.cpp
102                     COMPILE_DEFINITIONS "-DTEST_${FNNAME}"
103                     CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${ALL_LIB_LIST}"
104                     OUTPUT_VARIABLE OUTPUT
105                    )
106        #---- To see output from the compiler, uncomment the following line:
107        #MESSAGE (STATUS "Compiler Output " ${OUTPUT})
108
109        IF (HAVEFN_${FNNAME})
110            SET (detected_lapack_fortran TRUE)
111            MESSAGE (STATUS "Looking for " ${FNNAME}_
112                            " - found with try_compile")
113        ENDIF (HAVEFN_${FNNAME})
114    ENDIF (NOT HAVEFN_${FNNAME})
115
116    #---- Try compiling directly, guessing LAPACK was built from Fortran
117    #---- and needs Fortran symbols.
118    IF (NOT HAVEFN_${FNNAME})
119        SET (ALL_LIB_LIST ${LAPACK_LIBS} ${LAPACK_ADD_LIBS} g2c)
120        TRY_COMPILE (HAVEFN_${FNNAME}
121                     ${HOPSPACK_BINARY_DIR}/test
122                     ${HOPSPACK_SOURCE_DIR}/test/cmake_test_link_lapack.cpp
123                     COMPILE_DEFINITIONS "-DTEST_${FNNAME}"
124                     CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${ALL_LIB_LIST}"
125                     OUTPUT_VARIABLE OUTPUT
126                    )
127        #---- To see output from the compiler, uncomment the following line:
128        #MESSAGE (STATUS "Compiler Output " ${OUTPUT})
129
130        IF (HAVEFN_${FNNAME})
131            SET (detected_lapack_fortran TRUE)
132            MESSAGE (STATUS "Looking for " ${FNNAME}_
133                            " - found with try_compile and g2c")
134            SET (LAPACK_ADD_LIBS ${LAPACK_ADD_LIBS} g2c)
135        ENDIF (HAVEFN_${FNNAME})
136    ENDIF (NOT HAVEFN_${FNNAME})
137
138    IF (NOT HAVEFN_${FNNAME})
139        MESSAGE (STATUS "HOPSPACK: Cannot find '" ${FNNAME} "', looked in")
140        FOREACH (loopVar ${LAPACK_LIBS})
141            MESSAGE (STATUS "          " ${loopVar})
142        ENDFOREACH (loopVar)
143        FOREACH (loopVar ${LAPACK_ADD_LIBS})
144            MESSAGE (STATUS "    using " ${loopVar})
145        ENDFOREACH (loopVar)
146        MESSAGE (FATAL_ERROR "HOPSPACK: Need an LAPACK/BLAS library.")
147    ENDIF (NOT HAVEFN_${FNNAME})
148
149ENDMACRO (check_for_lapack_function)
150##########################################################################
151
152
153#-------------------------------------------------------------------------
154IF (NOT lapack)
155#-------------------------------------------------------------------------
156    MESSAGE (STATUS "HOPSPACK: No LAPACK, linear constraints disabled.")
157
158#-------------------------------------------------------------------------
159ELSE (NOT lapack)
160#-------------------------------------------------------------------------
161    MESSAGE (STATUS "HOPSPACK: LAPACK requested, linear constraints allowed.")
162
163    #---- Enable EXACTLY ONE of the following options to link LAPACK/BLAS
164    #---- libraries.  Enable by uncommenting, or passing on the command line.
165    #---- See the HOPSPACK User Manual for details.
166
167    #---- 1. Search the system library paths for an LAPACK library:
168    FIND_LIBRARY (LAPACK_LIBS NAMES lapack
169                  DOC "Location of LAPACK library")
170
171    #---- 2. Let CMake search for a standard Fortran-based LAPACK library:
172#    FIND_PACKAGE (LAPACK)
173
174    #---- 3. Provide a specific location and name of LAPACK and/or BLAS:
175    #----    The example below locates libraries installed and built in /tmp
176    #----    with gcc on a Linux system.  The actual library files built
177    #----    by the LAPACK distribution are named "libblas_LINUX.a"
178    #----    and "liblapack_LINUX.a"
179#    FIND_LIBRARY (LIB1 NAMES lapack_LINUX
180#                  DOC "Location of LAPACK library"
181#                  PATHS /tmp/lapack-3.1.1)
182#    FIND_LIBRARY (LIB2 NAMES blas_LINUX
183#                  DOC "Location of BLAS library"
184#                  PATHS /tmp/lapack-3.1.1)
185#    SET (LAPACK_LIBS ${LIB1} ${LIB2})
186
187    #---- 4. Provide a specific location of a CLAPACK library on Windows.
188    #----    The example below locates the library installed in c:\Temp.
189#    FIND_LIBRARY (LAPACK_LIBS NAMES clapack
190#                  DOC "Location of MSVC CLAPACK library"
191#                  PATHS c:\\Temp\\CLAPACK3-Windows\\CLAPACK\\Release)
192
193
194    #---- Now test for the presence of LAPACK functions used by HOPSPACK.
195    IF (HOPSPACK_TEST_LAPACK_FUNCS)
196        check_for_lapack_function (ddot)
197        check_for_lapack_function (dgemv)
198        check_for_lapack_function (dgemm)
199#        THESE ARE SOMETIMES PROBLEMATIC; ASSUME BLAS CHECK IS GOOD ENOUGH.
200#        check_for_lapack_function (dgesvd)
201#        check_for_lapack_function (dgglse)
202#        check_for_lapack_function (dgelss)
203#        check_for_lapack_function (dgelqf)
204    ENDIF ()
205
206    MESSAGE (STATUS "HOPSPACK: Using LAPACK libraries:")
207    FOREACH (loopVar ${LAPACK_LIBS})
208        MESSAGE (STATUS "  " ${loopVar})
209    ENDFOREACH (loopVar)
210    FOREACH (loopVar ${LAPACK_ADD_LIBS})
211        MESSAGE (STATUS "  " ${loopVar})
212    ENDFOREACH (loopVar)
213
214    SET (HAVE_LAPACK TRUE)
215
216#-------------------------------------------------------------------------
217ENDIF (NOT lapack)
218#-------------------------------------------------------------------------
219