blob: 3f3a50d1f5bf31314bb1b9b849c8204560d6087e [file] [log] [blame]
Alex Stewart0b07d3e2013-10-04 16:17:06 +01001# Ceres Solver - A fast non-linear least squares minimizer
2# Copyright 2013 Google Inc. All rights reserved.
3# http://code.google.com/p/ceres-solver/
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are met:
7#
8# * Redistributions of source code must retain the above copyright notice,
9# this list of conditions and the following disclaimer.
10# * Redistributions in binary form must reproduce the above copyright notice,
11# this list of conditions and the following disclaimer in the documentation
12# and/or other materials provided with the distribution.
13# * Neither the name of Google Inc. nor the names of its contributors may be
14# used to endorse or promote products derived from this software without
15# specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29# Author: alexs.mac@gmail.com (Alex Stewart)
30#
31
32# FindSuiteSparse.cmake - Find SuiteSparse libraries & dependencies.
33#
34# This module defines the following variables:
35#
36# SUITESPARSE_FOUND: TRUE iff SuiteSparse and all dependencies have been found.
37# SUITESPARSE_INCLUDE_DIRS: Include directories for all SuiteSparse components.
38# SUITESPARSE_LIBRARIES: Libraries for all SuiteSparse component libraries and
39# dependencies.
40# SUITESPARSE_VERSION: Extracted from UFconfig.h (<= v3) or
41# SuiteSparse_config.h (>= v4).
42# SUITESPARSE_MAIN_VERSION: Equal to 4 if SUITESPARSE_VERSION = 4.2.1
43# SUITESPARSE_SUB_VERSION: Equal to 2 if SUITESPARSE_VERSION = 4.2.1
44# SUITESPARSE_SUBSUB_VERSION: Equal to 1 if SUITESPARSE_VERSION = 4.2.1
45#
46# SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION: TRUE iff running
47# on Ubuntu, SUITESPARSE_VERSION is 3.4.0 and found SuiteSparse is a system
48# install, in which case found version of SuiteSparse cannot be used to link
49# a shared library due to a bug (static linking is unaffected).
50#
Alex Stewart78cc2c42013-10-11 15:50:10 +010051# The following variables control the behaviour of this module:
52#
53# SUITESPARSE_INCLUDE_DIR_HINTS: List of additional directories in which to
54# search for SuiteSparse includes,
55# e.g: /timbuktu/include.
56# SUITESPARSE_LIBRARY_DIR_HINTS: List of additional directories in which to
57# search for SuiteSparse libraries,
58# e.g: /timbuktu/lib.
59#
Alex Stewart0b07d3e2013-10-04 16:17:06 +010060# The following variables define the presence / includes & libraries for the
61# SuiteSparse components searched for, the SUITESPARSE_XX variables are the
62# union of the variables for all components.
63#
64# == Symmetric Approximate Minimum Degree (AMD)
65# AMD_FOUND
66# AMD_INCLUDE_DIR
67# AMD_LIBRARY
68#
69# == Constrained Approximate Minimum Degree (CAMD)
70# CAMD_FOUND
71# CAMD_INCLUDE_DIR
72# CAMD_LIBRARY
73#
74# == Column Approximate Minimum Degree (COLAMD)
75# COLAMD_FOUND
76# COLAMD_INCLUDE_DIR
77# COLAMD_LIBRARY
78#
79# Constrained Column Approximate Minimum Degree (CCOLAMD)
80# CCOLAMD_FOUND
81# CCOLAMD_INCLUDE_DIR
82# CCOLAMD_LIBRARY
83#
84# == Sparse Supernodal Cholesky Factorization and Update/Downdate (CHOLMOD)
85# CHOLMOD_FOUND
86# CHOLMOD_INCLUDE_DIR
87# CHOLMOD_LIBRARY
88#
89# == Multifrontal Sparse QR (SuiteSparseQR)
90# SUITESPARSEQR_FOUND
91# SUITESPARSEQR_INCLUDE_DIR
92# SUITESPARSEQR_LIBRARY
93#
94# == Common configuration for all but CSparse (SuiteSparse version >= 4).
95# SUITESPARSE_CONFIG_FOUND
96# SUITESPARSE_CONFIG_INCLUDE_DIR
97# SUITESPARSE_CONFIG_LIBRARY
98#
99# == Common configuration for all but CSparse (SuiteSparse version < 4).
100# UFCONFIG_FOUND
101# UFCONFIG_INCLUDE_DIR
102#
103# Optional SuiteSparse Dependencies:
104#
105# == Serial Graph Partitioning and Fill-reducing Matrix Ordering (METIS)
106# METIS_FOUND
107# METIS_LIBRARY
108#
109# == Intel Thread Building Blocks (TBB)
110# TBB_FOUND
111# TBB_LIBRARIES
112
Alex Stewart78cc2c42013-10-11 15:50:10 +0100113# Called if we failed to find SuiteSparse or any of it's required dependencies,
114# unsets all public (designed to be used externally) variables and reports
115# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
116MACRO(SUITESPARSE_REPORT_NOT_FOUND REASON_MSG)
117 UNSET(SUITESPARSE_FOUND)
118 UNSET(SUITESPARSE_INCLUDE_DIRS)
119 UNSET(SUITESPARSE_LIBRARIES)
120 UNSET(SUITESPARSE_VERSION)
121 UNSET(SUITESPARSE_MAIN_VERSION)
122 UNSET(SUITESPARSE_SUB_VERSION)
123 UNSET(SUITESPARSE_SUBSUB_VERSION)
124 # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
125 # use the camelcase library name, not uppercase.
126 IF (SuiteSparse_FIND_QUIETLY)
127 MESSAGE(STATUS "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
Alex Stewart6fed9fe2013-11-04 18:33:05 +0000128 ELSEIF (SuiteSparse_FIND_REQUIRED)
Alex Stewart78cc2c42013-10-11 15:50:10 +0100129 MESSAGE(FATAL_ERROR "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
Alex Stewart6fed9fe2013-11-04 18:33:05 +0000130 ELSE()
Alex Stewart69bd65f2013-11-04 23:01:14 +0000131 # Neither QUIETLY nor REQUIRED, use no priority which emits a message
Alex Stewart6fed9fe2013-11-04 18:33:05 +0000132 # but continues configuration and allows generation.
Alex Stewart69bd65f2013-11-04 23:01:14 +0000133 MESSAGE("-- Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100134 ENDIF (SuiteSparse_FIND_QUIETLY)
135ENDMACRO(SUITESPARSE_REPORT_NOT_FOUND)
136
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100137# Specify search directories for include files and libraries (this is the union
Alex Stewart78cc2c42013-10-11 15:50:10 +0100138# of the search directories for all OSs). Search user-specified hint
Alex Stewart6fed9fe2013-11-04 18:33:05 +0000139# directories first if supplied, and search user-installed locations first
140# so that we prefer user installs to system installs where both exist.
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100141LIST(APPEND SUITESPARSE_CHECK_INCLUDE_DIRS
Alex Stewart78cc2c42013-10-11 15:50:10 +0100142 ${SUITESPARSE_INCLUDE_DIR_HINTS}
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100143 /opt/local/include
144 /opt/local/include/ufsparse # Mac OS X
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100145 /usr/local/homebrew/include # Mac OS X
146 /usr/local/include
Alex Stewart6fed9fe2013-11-04 18:33:05 +0000147 /usr/local/include/suitesparse
148 /usr/include/suitesparse # Ubuntu
149 /usr/include)
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100150LIST(APPEND SUITESPARSE_CHECK_LIBRARY_DIRS
Alex Stewart78cc2c42013-10-11 15:50:10 +0100151 ${SUITESPARSE_LIBRARY_DIR_HINTS}
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100152 /opt/local/lib
153 /opt/local/lib/ufsparse # Mac OS X
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100154 /usr/local/homebrew/lib # Mac OS X
155 /usr/local/lib
Alex Stewart6fed9fe2013-11-04 18:33:05 +0000156 /usr/local/lib/suitesparse
157 /usr/lib/suitesparse # Ubuntu
158 /usr/lib)
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100159
160# BLAS.
161FIND_PACKAGE(BLAS QUIET)
162IF (NOT BLAS_FOUND)
Alex Stewart78cc2c42013-10-11 15:50:10 +0100163 SUITESPARSE_REPORT_NOT_FOUND(
164 "Did not find BLAS library (required for SuiteSparse).")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100165ENDIF (NOT BLAS_FOUND)
166
167# LAPACK.
168FIND_PACKAGE(LAPACK QUIET)
169IF (NOT LAPACK_FOUND)
Alex Stewart78cc2c42013-10-11 15:50:10 +0100170 SUITESPARSE_REPORT_NOT_FOUND(
171 "Did not find LAPACK library (required for SuiteSparse).")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100172ENDIF (NOT LAPACK_FOUND)
173
174# AMD.
175SET(AMD_FOUND TRUE)
176FIND_LIBRARY(AMD_LIBRARY NAMES amd
177 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
178IF (EXISTS ${AMD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100179 MESSAGE(STATUS "Found AMD library: ${AMD_LIBRARY}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100180ELSE (EXISTS ${AMD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100181 SUITESPARSE_REPORT_NOT_FOUND("Did not find AMD library.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100182 SET(AMD_FOUND FALSE)
183ENDIF (EXISTS ${AMD_LIBRARY})
184MARK_AS_ADVANCED(AMD_LIBRARY)
185
186FIND_PATH(AMD_INCLUDE_DIR NAMES amd.h
187 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
188IF (EXISTS ${AMD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100189 MESSAGE(STATUS "Found AMD header in: ${AMD_INCLUDE_DIR}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100190ELSE (EXISTS ${AMD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100191 SUITESPARSE_REPORT_NOT_FOUND("Did not find AMD header.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100192 SET(AMD_FOUND FALSE)
193ENDIF (EXISTS ${AMD_INCLUDE_DIR})
194MARK_AS_ADVANCED(AMD_INCLUDE_DIR)
195
196# CAMD.
197SET(CAMD_FOUND TRUE)
198FIND_LIBRARY(CAMD_LIBRARY NAMES camd
199 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
200IF (EXISTS ${CAMD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100201 MESSAGE(STATUS "Found CAMD library: ${CAMD_LIBRARY}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100202ELSE (EXISTS ${CAMD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100203 SUITESPARSE_REPORT_NOT_FOUND("Did not find CAMD library.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100204 SET(CAMD_FOUND FALSE)
205ENDIF (EXISTS ${CAMD_LIBRARY})
206MARK_AS_ADVANCED(CAMD_LIBRARY)
207
208FIND_PATH(CAMD_INCLUDE_DIR NAMES camd.h
209 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
210IF (EXISTS ${CAMD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100211 MESSAGE(STATUS "Found CAMD header in: ${CAMD_INCLUDE_DIR}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100212ELSE (EXISTS ${CAMD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100213 SUITESPARSE_REPORT_NOT_FOUND("Did not find CAMD header.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100214 SET(CAMD_FOUND FALSE)
215ENDIF (EXISTS ${CAMD_INCLUDE_DIR})
216MARK_AS_ADVANCED(CAMD_INCLUDE_DIR)
217
218# COLAMD.
219SET(COLAMD_FOUND TRUE)
220FIND_LIBRARY(COLAMD_LIBRARY NAMES colamd
221 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
222IF (EXISTS ${COLAMD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100223 MESSAGE(STATUS "Found COLAMD library: ${COLAMD_LIBRARY}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100224ELSE (EXISTS ${COLAMD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100225 SUITESPARSE_REPORT_NOT_FOUND("Did not find COLAMD library.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100226 SET(COLAMD_FOUND FALSE)
227ENDIF (EXISTS ${COLAMD_LIBRARY})
228MARK_AS_ADVANCED(COLAMD_LIBRARY)
229
230FIND_PATH(COLAMD_INCLUDE_DIR NAMES colamd.h
231 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
232IF (EXISTS ${COLAMD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100233 MESSAGE(STATUS "Found COLAMD header in: ${COLAMD_INCLUDE_DIR}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100234ELSE (EXISTS ${COLAMD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100235 SUITESPARSE_REPORT_NOT_FOUND("Did not find COLAMD header.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100236 SET(COLAMD_FOUND FALSE)
237ENDIF (EXISTS ${COLAMD_INCLUDE_DIR})
238MARK_AS_ADVANCED(COLAMD_INCLUDE_DIR)
239
240# CCOLAMD.
241SET(CCOLAMD_FOUND TRUE)
242FIND_LIBRARY(CCOLAMD_LIBRARY NAMES ccolamd
243 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
244IF (EXISTS ${CCOLAMD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100245 MESSAGE(STATUS "Found CCOLAMD library: ${CCOLAMD_LIBRARY}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100246ELSE (EXISTS ${CCOLAMD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100247 SUITESPARSE_REPORT_NOT_FOUND("Did not find CCOLAMD library.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100248 SET(CCOLAMD_FOUND FALSE)
249ENDIF (EXISTS ${CCOLAMD_LIBRARY})
250MARK_AS_ADVANCED(CCOLAMD_LIBRARY)
251
252FIND_PATH(CCOLAMD_INCLUDE_DIR NAMES ccolamd.h
253 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
254IF (EXISTS ${CCOLAMD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100255 MESSAGE(STATUS "Found CCOLAMD header in: ${CCOLAMD_INCLUDE_DIR}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100256ELSE (EXISTS ${CCOLAMD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100257 SUITESPARSE_REPORT_NOT_FOUND("Did not find CCOLAMD header.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100258 SET(CCOLAMD_FOUND FALSE)
259ENDIF (EXISTS ${CCOLAMD_INCLUDE_DIR})
260MARK_AS_ADVANCED(CCOLAMD_INCLUDE_DIR)
261
262# CHOLMOD.
263SET(CHOLMOD_FOUND TRUE)
264FIND_LIBRARY(CHOLMOD_LIBRARY NAMES cholmod
265 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
266IF (EXISTS ${CHOLMOD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100267 MESSAGE(STATUS "Found CHOLMOD library: ${CHOLMOD_LIBRARY}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100268ELSE (EXISTS ${CHOLMOD_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100269 SUITESPARSE_REPORT_NOT_FOUND("Did not find CHOLMOD library.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100270 SET(CHOLMOD_FOUND FALSE)
271ENDIF (EXISTS ${CHOLMOD_LIBRARY})
272MARK_AS_ADVANCED(CHOLMOD_LIBRARY)
273
274FIND_PATH(CHOLMOD_INCLUDE_DIR NAMES cholmod.h
275 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
276IF (EXISTS ${CHOLMOD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100277 MESSAGE(STATUS "Found CHOLMOD header in: ${CHOLMOD_INCLUDE_DIR}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100278ELSE (EXISTS ${CHOLMOD_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100279 SUITESPARSE_REPORT_NOT_FOUND("Did not find CHOLMOD header.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100280 SET(CHOLMOD_FOUND FALSE)
281ENDIF (EXISTS ${CHOLMOD_INCLUDE_DIR})
282MARK_AS_ADVANCED(CHOLMOD_INCLUDE_DIR)
283
284# SuiteSparseQR.
285SET(SUITESPARSEQR_FOUND TRUE)
286FIND_LIBRARY(SUITESPARSEQR_LIBRARY NAMES spqr
287 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
288IF (EXISTS ${SUITESPARSEQR_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100289 MESSAGE(STATUS "Found SuiteSparseQR library: ${SUITESPARSEQR_LIBRARY}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100290ELSE (EXISTS ${SUITESPARSEQR_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100291 SUITESPARSE_REPORT_NOT_FOUND("Did not find SUITESPARSEQR library.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100292 SET(SUITESPARSEQR_FOUND FALSE)
293ENDIF (EXISTS ${SUITESPARSEQR_LIBRARY})
294MARK_AS_ADVANCED(SUITESPARSEQR_LIBRARY)
295
296FIND_PATH(SUITESPARSEQR_INCLUDE_DIR NAMES SuiteSparseQR.hpp
297 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
298IF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100299 MESSAGE(STATUS "Found SuiteSparseQR header in: ${SUITESPARSEQR_INCLUDE_DIR}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100300ELSE (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100301 SUITESPARSE_REPORT_NOT_FOUND("Did not find SUITESPARSEQR header.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100302 SET(SUITESPARSEQR_FOUND FALSE)
303ENDIF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR})
304MARK_AS_ADVANCED(SUITESPARSEQR_INCLUDE_DIR)
305
306IF (SUITESPARSEQR_FOUND)
307 # SuiteSparseQR may be compiled with Intel Threading Building Blocks,
308 # we assume that if TBB is installed, SuiteSparseQR was compiled with
309 # support for it, this will do no harm if it wasn't.
310 SET(TBB_FOUND TRUE)
311 FIND_LIBRARY(TBB_LIBRARIES NAMES tbb
312 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
313 IF (EXISTS ${TBB_LIBRARIES})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100314 MESSAGE(STATUS "Found Intel Thread Building Blocks (TBB) library: "
315 "${TBB_LIBRARIES}, assuming SuiteSparseQR was compiled with TBB.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100316 ELSE (EXISTS ${TBB_LIBRARIES})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100317 MESSAGE(STATUS "Did not find Intel TBB library, assuming SuiteSparseQR was "
318 "not compiled with TBB.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100319 SET(TBB_FOUND FALSE)
320 ENDIF (EXISTS ${TBB_LIBRARIES})
321 MARK_AS_ADVANCED(TBB_LIBRARIES)
322
323 IF (TBB_FOUND)
324 FIND_LIBRARY(TBB_MALLOC_LIB NAMES tbbmalloc
325 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
326 IF (EXISTS ${TBB_MALLOC_LIB})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100327 MESSAGE(STATUS "Found Intel Thread Building Blocks (TBB) Malloc library: "
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100328 "${TBB_MALLOC_LIB}")
329 # Append TBB malloc library to TBB libraries list whilst retaining
330 # any CMake generated help string (cache variable).
331 LIST(APPEND TBB_LIBRARIES ${TBB_MALLOC_LIB})
332 GET_PROPERTY(HELP_STRING CACHE TBB_LIBRARIES PROPERTY HELPSTRING)
333 SET(TBB_LIBRARIES "${TBB_LIBRARIES}" CACHE STRING ${HELP_STRING})
334
335 # Add the TBB libraries to the SuiteSparseQR libraries (the only
336 # libraries to optionally depend on TBB).
337 LIST(APPEND SUITESPARSEQR_LIBRARY ${TBB_LIBRARIES})
338
339 ELSE (EXISTS ${TBB_MALLOC_LIB})
340 # If we cannot find all required TBB components do not include it as
341 # a dependency.
Alex Stewart78cc2c42013-10-11 15:50:10 +0100342 MESSAGE(STATUS "Did not find Intel Thread Building Blocks (TBB) Malloc "
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100343 "Library, discarding TBB as a dependency.")
344 SET(TBB_FOUND FALSE)
345 ENDIF (EXISTS ${TBB_MALLOC_LIB})
346 MARK_AS_ADVANCED(TBB_MALLOC_LIB)
347 ENDIF (TBB_FOUND)
348ENDIF(SUITESPARSEQR_FOUND)
349
350# UFconfig / SuiteSparse_config.
351#
352# If SuiteSparse version is >= 4 then SuiteSparse_config is required.
353# For SuiteSparse 3, UFconfig.h is required.
354SET(SUITESPARSE_CONFIG_FOUND TRUE)
355SET(UFCONFIG_FOUND TRUE)
356
357FIND_LIBRARY(SUITESPARSE_CONFIG_LIBRARY NAMES suitesparseconfig
358 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
359IF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100360 MESSAGE(STATUS "Found SuiteSparse_config library: "
361 "${SUITESPARSE_CONFIG_LIBRARY}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100362ELSE (EXISTS ${SUITESPARSE_CONFIG_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100363 MESSAGE(STATUS "Did not find SuiteSparse_config library (should be present "
364 "in SuiteSparse >= v4 installs).")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100365ENDIF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY})
366MARK_AS_ADVANCED(SUITESPARSE_CONFIG_LIBRARY)
367
368FIND_PATH(SUITESPARSE_CONFIG_INCLUDE_DIR NAMES SuiteSparse_config.h
369 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
370IF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100371 MESSAGE(STATUS "Found SuiteSparse_config header in: "
372 "${SUITESPARSE_CONFIG_INCLUDE_DIR}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100373 SET(UFCONFIG_FOUND FALSE)
374ELSE (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100375 MESSAGE(STATUS "Did not find SuiteSparse_config header (should be present "
376 "in SuiteSparse >= v4 installs).")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100377ENDIF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
378MARK_AS_ADVANCED(SUITESPARSE_CONFIG_INCLUDE_DIR)
379
380IF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND
381 EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
382 # SuiteSparse_config (SuiteSparse version >= 4) requires librt library for
383 # timing by default when compiled on Linux or Unix, but not on OSX (which
384 # does not have librt).
385 IF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR UNIX AND NOT APPLE)
386 FIND_LIBRARY(LIBRT_LIBRARY NAMES rt
387 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
388 IF (LIBRT_LIBRARY)
Alex Stewart78cc2c42013-10-11 15:50:10 +0100389 MESSAGE(STATUS "Adding librt: ${LIBRT_LIBRARY} to "
390 "SuiteSparse_config libraries (required on Linux & Unix [not OSX] if "
391 "SuiteSparse is compiled with timing).")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100392 ELSE (LIBRT_LIBRARY)
Alex Stewart78cc2c42013-10-11 15:50:10 +0100393 MESSAGE(STATUS "Could not find librt, but found SuiteSparse_config, "
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100394 "assuming that SuiteSparse was compiled without timing.")
395 ENDIF (LIBRT_LIBRARY)
396 MARK_AS_ADVANCED(LIBRT_LIBRARY)
397 LIST(APPEND SUITESPARSE_CONFIG_LIBRARY ${LIBRT_LIBRARY})
398 ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR UNIX AND NOT APPLE)
399ELSE (EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND
400 EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
401 SET(SUITESPARSE_CONFIG_FOUND FALSE)
402 FIND_PATH(UFCONFIG_INCLUDE_DIR NAMES UFconfig.h
403 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS})
404 IF (EXISTS ${UFCONFIG_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100405 MESSAGE(STATUS "Found UFconfig header in: ${UFCONFIG_INCLUDE_DIR}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100406 ELSE (EXISTS ${UFCONFIG_INCLUDE_DIR})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100407 MESSAGE(STATUS "Did not find UFconfig header (should be present "
408 "in SuiteSparse < v4 installs)")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100409 SET(UFCONFIG_FOUND FALSE)
410 ENDIF (EXISTS ${UFCONFIG_INCLUDE_DIR})
411 MARK_AS_ADVANCED(UFCONFIG_INCLUDE_DIR)
412ENDIF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND
413 EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR})
414
415# Extract the SuiteSparse version from the appropriate header (UFconfig.h for
416# <= v3, SuiteSparse_config.h for >= v4).
417IF (UFCONFIG_FOUND)
418 # SuiteSparse version <= 3.
Alex Stewart78cc2c42013-10-11 15:50:10 +0100419 SET(SUITESPARSE_VERSION_FILE ${UFCONFIG_INCLUDE_DIR}/UFconfig.h)
420 IF (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
421 SUITESPARSE_REPORT_NOT_FOUND(
422 "Could not find file: ${SUITESPARSE_VERSION_FILE} containing version "
423 "information for <= v3 SuiteSparse installs, but UFconfig was found "
424 "(only present in <= v3 installs).")
425 ELSE (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
426 FILE(READ ${SUITESPARSE_VERSION_FILE} UFCONFIG_CONTENTS)
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100427
Alex Stewart78cc2c42013-10-11 15:50:10 +0100428 STRING(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
429 SUITESPARSE_MAIN_VERSION "${UFCONFIG_CONTENTS}")
430 STRING(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
431 SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100432
Alex Stewart78cc2c42013-10-11 15:50:10 +0100433 STRING(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
434 SUITESPARSE_SUB_VERSION "${UFCONFIG_CONTENTS}")
435 STRING(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
436 SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100437
Alex Stewart78cc2c42013-10-11 15:50:10 +0100438 STRING(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
439 SUITESPARSE_SUBSUB_VERSION "${UFCONFIG_CONTENTS}")
440 STRING(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
441 SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}")
442
443 # This is on a single line s/t CMake does not interpret it as a list of
444 # elements and insert ';' separators which would result in 4.;2.;1 nonsense.
445 SET(SUITESPARSE_VERSION
446 "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
447 ENDIF (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100448ENDIF (UFCONFIG_FOUND)
449
450IF (SUITESPARSE_CONFIG_FOUND)
451 # SuiteSparse version >= 4.
Alex Stewart78cc2c42013-10-11 15:50:10 +0100452 SET(SUITESPARSE_VERSION_FILE
453 ${SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h)
454 IF (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
455 SUITESPARSE_REPORT_NOT_FOUND(
456 "Could not find file: ${SUITESPARSE_VERSION_FILE} containing version "
457 "information for >= v4 SuiteSparse installs, but SuiteSparse_config was "
458 "found (only present in >= v4 installs).")
459 ELSE (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
460 FILE(READ ${SUITESPARSE_VERSION_FILE} SUITESPARSE_CONFIG_CONTENTS)
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100461
Alex Stewart78cc2c42013-10-11 15:50:10 +0100462 STRING(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
463 SUITESPARSE_MAIN_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
464 STRING(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
465 SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100466
Alex Stewart78cc2c42013-10-11 15:50:10 +0100467 STRING(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
468 SUITESPARSE_SUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
469 STRING(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
470 SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100471
Alex Stewart78cc2c42013-10-11 15:50:10 +0100472 STRING(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
473 SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
474 STRING(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
475 SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}")
476
477 # This is on a single line s/t CMake does not interpret it as a list of
478 # elements and insert ';' separators which would result in 4.;2.;1 nonsense.
479 SET(SUITESPARSE_VERSION
480 "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
481 ENDIF (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100482ENDIF (SUITESPARSE_CONFIG_FOUND)
483
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100484# METIS (Optional dependency).
485FIND_LIBRARY(METIS_LIBRARY NAMES metis
486 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS})
487IF (EXISTS ${METIS_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100488 MESSAGE(STATUS "Found METIS library: ${METIS_LIBRARY}.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100489ELSE (EXISTS ${METIS_LIBRARY})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100490 MESSAGE(STATUS "Did not find METIS library (optional SuiteSparse dependency)")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100491ENDIF (EXISTS ${METIS_LIBRARY})
492MARK_AS_ADVANCED(METIS_LIBRARY)
493
Alex Stewart78cc2c42013-10-11 15:50:10 +0100494# Only mark SuiteSparse as found if all required dependencies have been found.
495SET(SUITESPARSE_FOUND FALSE)
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100496IF (AMD_FOUND AND
497 CAMD_FOUND AND
498 COLAMD_FOUND AND
499 CCOLAMD_FOUND AND
500 CHOLMOD_FOUND AND
Alex Stewart003a1622013-10-09 19:33:33 +0100501 SUITESPARSEQR_FOUND AND
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100502 (SUITESPARSE_CONFIG_FOUND OR UFCONFIG_FOUND) AND
503 BLAS_FOUND AND
504 LAPACK_FOUND)
505 SET(SUITESPARSE_FOUND TRUE)
506 LIST(APPEND SUITESPARSE_INCLUDE_DIRS
507 ${AMD_INCLUDE_DIR}
508 ${CAMD_INCLUDE_DIR}
509 ${COLAMD_INCLUDE_DIR}
510 ${CCOLAMD_INCLUDE_DIR}
511 ${CHOLMOD_INCLUDE_DIR}
512 ${SUITESPARSEQR_INCLUDE_DIR})
513 # Handle config separately, as otherwise at least one of them will be set
514 # to NOTFOUND which would cause any check on SUITESPARSE_INCLUDE_DIRS to fail.
515 IF (SUITESPARSE_CONFIG_FOUND)
516 LIST(APPEND SUITESPARSE_INCLUDE_DIRS
517 ${SUITESPARSE_CONFIG_INCLUDE_DIR})
518 ENDIF (SUITESPARSE_CONFIG_FOUND)
519 IF (UFCONFIG_FOUND)
520 LIST(APPEND SUITESPARSE_INCLUDE_DIRS
521 ${UFCONFIG_INCLUDE_DIR})
522 ENDIF (UFCONFIG_FOUND)
Alex Stewartb0a87312013-11-04 20:32:40 +0000523 # As SuiteSparse includes are often all in the same directory, remove any
524 # repetitions.
525 LIST(REMOVE_DUPLICATES SUITESPARSE_INCLUDE_DIRS)
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100526
527 # Important: The ordering of these libraries is *NOT* arbitrary, as these
528 # could potentially be static libraries their link ordering is important.
529 LIST(APPEND SUITESPARSE_LIBRARIES
530 ${SUITESPARSEQR_LIBRARY}
531 ${CHOLMOD_LIBRARY}
532 ${CCOLAMD_LIBRARY}
533 ${CAMD_LIBRARY}
534 ${COLAMD_LIBRARY}
535 ${AMD_LIBRARY})
536 IF (SUITESPARSE_CONFIG_FOUND)
537 LIST(APPEND SUITESPARSE_LIBRARIES
538 ${SUITESPARSE_CONFIG_LIBRARY})
539 ENDIF (SUITESPARSE_CONFIG_FOUND)
540 IF (METIS_FOUND)
541 LIST(APPEND SUITESPARSE_LIBRARIES
542 ${METIS_LIBRARY})
543 ENDIF (METIS_FOUND)
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100544ELSE()
Alex Stewart78cc2c42013-10-11 15:50:10 +0100545 SUITESPARSE_REPORT_NOT_FOUND(
546 "Failed to find some/all required components of SuiteSparse.")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100547ENDIF()
548
549# Determine if we are running on Ubuntu with the package install of SuiteSparse
550# which is broken and does not support linking a shared library.
551SET(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION FALSE)
552IF (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
553 SUITESPARSE_VERSION VERSION_EQUAL 3.4.0)
554 FIND_PROGRAM(LSB_RELEASE_EXECUTABLE lsb_release)
555 IF (LSB_RELEASE_EXECUTABLE)
556 # Any even moderately recent Ubuntu release (likely to be affected by
557 # this bug) should have lsb_release, if it isn't present we are likely
558 # on a different Linux distribution (should be fine).
559
560 EXECUTE_PROCESS(COMMAND ${LSB_RELEASE_EXECUTABLE} -si
561 OUTPUT_VARIABLE LSB_DISTRIBUTOR_ID
562 OUTPUT_STRIP_TRAILING_WHITESPACE)
563
564 IF (LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND
565 SUITESPARSE_LIBRARIES MATCHES "/usr/lib/libamd")
566 # We are on Ubuntu, and the SuiteSparse version matches the broken
567 # system install version and is a system install.
568 SET(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION TRUE)
Alex Stewart78cc2c42013-10-11 15:50:10 +0100569 MESSAGE(STATUS "Found system install of SuiteSparse "
570 "${SUITESPARSE_VERSION} running on Ubuntu, which has a known bug "
571 "preventing linking of shared libraries (static linking unaffected).")
Alex Stewart0b07d3e2013-10-04 16:17:06 +0100572 ENDIF (LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND
573 SUITESPARSE_LIBRARIES MATCHES "/usr/lib/libamd")
574 ENDIF (LSB_RELEASE_EXECUTABLE)
575ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
576 SUITESPARSE_VERSION VERSION_EQUAL 3.4.0)
577
578# Handle REQUIRED and QUIET arguments to FIND_PACKAGE
579INCLUDE(FindPackageHandleStandardArgs)
Alex Stewart003a1622013-10-09 19:33:33 +0100580# A change to CMake after release 2.8.10.2 means that
581# FindPackageHandleStandardArgs() unsets <LibraryName>_FOUND without checking
582# if it is one of the variables passed whose existence & validity is verified
583# by FindPackageHandleStandardArgs() in conjunction with handling the REQUIRED
584# and QUIET optional arguments, as such we use an intermediary variable.
585SET(SUITESPARSE_FOUND_COPY ${SUITESPARSE_FOUND})
Alex Stewart78cc2c42013-10-11 15:50:10 +0100586FIND_PACKAGE_HANDLE_STANDARD_ARGS(SuiteSparse
Alex Stewartb0a87312013-11-04 20:32:40 +0000587 REQUIRED_VARS SUITESPARSE_INCLUDE_DIRS SUITESPARSE_LIBRARIES SUITESPARSE_FOUND_COPY
Alex Stewart78cc2c42013-10-11 15:50:10 +0100588 VERSION_VAR SUITESPARSE_VERSION)