1 # 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 (a] 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 # 51 # 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 # 60 # 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 113 # 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. 116 MACRO(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 # Do NOT unset SUITESPARSE_FOUND_REQUIRED_VARS here, as it is used by 125 # FindPackageHandleStandardArgs() to generate the automatic error message on 126 # failure which highlights which components are missing. 127 128 # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage() 129 # use the camelcase library name, not uppercase. 130 IF (SuiteSparse_FIND_QUIETLY) 131 MESSAGE(STATUS "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN}) 132 ELSEIF (SuiteSparse_FIND_REQUIRED) 133 MESSAGE(FATAL_ERROR "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN}) 134 ELSE() 135 # Neither QUIETLY nor REQUIRED, use no priority which emits a message 136 # but continues configuration and allows generation. 137 MESSAGE("-- Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN}) 138 ENDIF (SuiteSparse_FIND_QUIETLY) 139 140 # Do not call RETURN(), s/t we keep processing if not called with REQUIRED. 141 ENDMACRO(SUITESPARSE_REPORT_NOT_FOUND) 142 143 # Specify search directories for include files and libraries (this is the union 144 # of the search directories for all OSs). Search user-specified hint 145 # directories first if supplied, and search user-installed locations first 146 # so that we prefer user installs to system installs where both exist. 147 LIST(APPEND SUITESPARSE_CHECK_INCLUDE_DIRS 148 ${SUITESPARSE_INCLUDE_DIR_HINTS} 149 /opt/local/include 150 /opt/local/include/ufsparse # Mac OS X 151 /usr/local/homebrew/include # Mac OS X 152 /usr/local/include 153 /usr/local/include/suitesparse 154 /usr/include/suitesparse # Ubuntu 155 /usr/include) 156 LIST(APPEND SUITESPARSE_CHECK_LIBRARY_DIRS 157 ${SUITESPARSE_LIBRARY_DIR_HINTS} 158 /opt/local/lib 159 /opt/local/lib/ufsparse # Mac OS X 160 /usr/local/homebrew/lib # Mac OS X 161 /usr/local/lib 162 /usr/local/lib/suitesparse 163 /usr/lib/suitesparse # Ubuntu 164 /usr/lib) 165 166 # Given the number of components of SuiteSparse, and to ensure that the 167 # automatic failure message generated by FindPackageHandleStandardArgs() 168 # when not all required components are found is helpful, we maintain a list 169 # of all variables that must be defined for SuiteSparse to be considered found. 170 UNSET(SUITESPARSE_FOUND_REQUIRED_VARS) 171 172 # BLAS. 173 FIND_PACKAGE(BLAS QUIET) 174 IF (NOT BLAS_FOUND) 175 SUITESPARSE_REPORT_NOT_FOUND( 176 "Did not find BLAS library (required for SuiteSparse).") 177 ENDIF (NOT BLAS_FOUND) 178 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS BLAS_FOUND) 179 180 # LAPACK. 181 FIND_PACKAGE(LAPACK QUIET) 182 IF (NOT LAPACK_FOUND) 183 SUITESPARSE_REPORT_NOT_FOUND( 184 "Did not find LAPACK library (required for SuiteSparse).") 185 ENDIF (NOT LAPACK_FOUND) 186 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS LAPACK_FOUND) 187 188 # AMD. 189 SET(AMD_FOUND TRUE) 190 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS AMD_FOUND) 191 FIND_LIBRARY(AMD_LIBRARY NAMES amd 192 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 193 IF (EXISTS ${AMD_LIBRARY}) 194 MESSAGE(STATUS "Found AMD library: ${AMD_LIBRARY}") 195 ELSE (EXISTS ${AMD_LIBRARY}) 196 SUITESPARSE_REPORT_NOT_FOUND( 197 "Did not find AMD library (required SuiteSparse component).") 198 SET(AMD_FOUND FALSE) 199 ENDIF (EXISTS ${AMD_LIBRARY}) 200 MARK_AS_ADVANCED(AMD_LIBRARY) 201 202 FIND_PATH(AMD_INCLUDE_DIR NAMES amd.h 203 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 204 IF (EXISTS ${AMD_INCLUDE_DIR}) 205 MESSAGE(STATUS "Found AMD header in: ${AMD_INCLUDE_DIR}") 206 ELSE (EXISTS ${AMD_INCLUDE_DIR}) 207 SUITESPARSE_REPORT_NOT_FOUND( 208 "Did not find AMD header (required SuiteSparse component).") 209 SET(AMD_FOUND FALSE) 210 ENDIF (EXISTS ${AMD_INCLUDE_DIR}) 211 MARK_AS_ADVANCED(AMD_INCLUDE_DIR) 212 213 # CAMD. 214 SET(CAMD_FOUND TRUE) 215 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS CAMD_FOUND) 216 FIND_LIBRARY(CAMD_LIBRARY NAMES camd 217 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 218 IF (EXISTS ${CAMD_LIBRARY}) 219 MESSAGE(STATUS "Found CAMD library: ${CAMD_LIBRARY}") 220 ELSE (EXISTS ${CAMD_LIBRARY}) 221 SUITESPARSE_REPORT_NOT_FOUND( 222 "Did not find CAMD library (required SuiteSparse component).") 223 SET(CAMD_FOUND FALSE) 224 ENDIF (EXISTS ${CAMD_LIBRARY}) 225 MARK_AS_ADVANCED(CAMD_LIBRARY) 226 227 FIND_PATH(CAMD_INCLUDE_DIR NAMES camd.h 228 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 229 IF (EXISTS ${CAMD_INCLUDE_DIR}) 230 MESSAGE(STATUS "Found CAMD header in: ${CAMD_INCLUDE_DIR}") 231 ELSE (EXISTS ${CAMD_INCLUDE_DIR}) 232 SUITESPARSE_REPORT_NOT_FOUND( 233 "Did not find CAMD header (required SuiteSparse component).") 234 SET(CAMD_FOUND FALSE) 235 ENDIF (EXISTS ${CAMD_INCLUDE_DIR}) 236 MARK_AS_ADVANCED(CAMD_INCLUDE_DIR) 237 238 # COLAMD. 239 SET(COLAMD_FOUND TRUE) 240 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS COLAMD_FOUND) 241 FIND_LIBRARY(COLAMD_LIBRARY NAMES colamd 242 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 243 IF (EXISTS ${COLAMD_LIBRARY}) 244 MESSAGE(STATUS "Found COLAMD library: ${COLAMD_LIBRARY}") 245 ELSE (EXISTS ${COLAMD_LIBRARY}) 246 SUITESPARSE_REPORT_NOT_FOUND( 247 "Did not find COLAMD library (required SuiteSparse component).") 248 SET(COLAMD_FOUND FALSE) 249 ENDIF (EXISTS ${COLAMD_LIBRARY}) 250 MARK_AS_ADVANCED(COLAMD_LIBRARY) 251 252 FIND_PATH(COLAMD_INCLUDE_DIR NAMES colamd.h 253 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 254 IF (EXISTS ${COLAMD_INCLUDE_DIR}) 255 MESSAGE(STATUS "Found COLAMD header in: ${COLAMD_INCLUDE_DIR}") 256 ELSE (EXISTS ${COLAMD_INCLUDE_DIR}) 257 SUITESPARSE_REPORT_NOT_FOUND( 258 "Did not find COLAMD header (required SuiteSparse component).") 259 SET(COLAMD_FOUND FALSE) 260 ENDIF (EXISTS ${COLAMD_INCLUDE_DIR}) 261 MARK_AS_ADVANCED(COLAMD_INCLUDE_DIR) 262 263 # CCOLAMD. 264 SET(CCOLAMD_FOUND TRUE) 265 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS CCOLAMD_FOUND) 266 FIND_LIBRARY(CCOLAMD_LIBRARY NAMES ccolamd 267 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 268 IF (EXISTS ${CCOLAMD_LIBRARY}) 269 MESSAGE(STATUS "Found CCOLAMD library: ${CCOLAMD_LIBRARY}") 270 ELSE (EXISTS ${CCOLAMD_LIBRARY}) 271 SUITESPARSE_REPORT_NOT_FOUND( 272 "Did not find CCOLAMD library (required SuiteSparse component).") 273 SET(CCOLAMD_FOUND FALSE) 274 ENDIF (EXISTS ${CCOLAMD_LIBRARY}) 275 MARK_AS_ADVANCED(CCOLAMD_LIBRARY) 276 277 FIND_PATH(CCOLAMD_INCLUDE_DIR NAMES ccolamd.h 278 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 279 IF (EXISTS ${CCOLAMD_INCLUDE_DIR}) 280 MESSAGE(STATUS "Found CCOLAMD header in: ${CCOLAMD_INCLUDE_DIR}") 281 ELSE (EXISTS ${CCOLAMD_INCLUDE_DIR}) 282 SUITESPARSE_REPORT_NOT_FOUND( 283 "Did not find CCOLAMD header (required SuiteSparse component).") 284 SET(CCOLAMD_FOUND FALSE) 285 ENDIF (EXISTS ${CCOLAMD_INCLUDE_DIR}) 286 MARK_AS_ADVANCED(CCOLAMD_INCLUDE_DIR) 287 288 # CHOLMOD. 289 SET(CHOLMOD_FOUND TRUE) 290 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS CHOLMOD_FOUND) 291 FIND_LIBRARY(CHOLMOD_LIBRARY NAMES cholmod 292 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 293 IF (EXISTS ${CHOLMOD_LIBRARY}) 294 MESSAGE(STATUS "Found CHOLMOD library: ${CHOLMOD_LIBRARY}") 295 ELSE (EXISTS ${CHOLMOD_LIBRARY}) 296 SUITESPARSE_REPORT_NOT_FOUND( 297 "Did not find CHOLMOD library (required SuiteSparse component).") 298 SET(CHOLMOD_FOUND FALSE) 299 ENDIF (EXISTS ${CHOLMOD_LIBRARY}) 300 MARK_AS_ADVANCED(CHOLMOD_LIBRARY) 301 302 FIND_PATH(CHOLMOD_INCLUDE_DIR NAMES cholmod.h 303 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 304 IF (EXISTS ${CHOLMOD_INCLUDE_DIR}) 305 MESSAGE(STATUS "Found CHOLMOD header in: ${CHOLMOD_INCLUDE_DIR}") 306 ELSE (EXISTS ${CHOLMOD_INCLUDE_DIR}) 307 SUITESPARSE_REPORT_NOT_FOUND( 308 "Did not find CHOLMOD header (required SuiteSparse component).") 309 SET(CHOLMOD_FOUND FALSE) 310 ENDIF (EXISTS ${CHOLMOD_INCLUDE_DIR}) 311 MARK_AS_ADVANCED(CHOLMOD_INCLUDE_DIR) 312 313 # SuiteSparseQR. 314 SET(SUITESPARSEQR_FOUND TRUE) 315 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS SUITESPARSEQR_FOUND) 316 FIND_LIBRARY(SUITESPARSEQR_LIBRARY NAMES spqr 317 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 318 IF (EXISTS ${SUITESPARSEQR_LIBRARY}) 319 MESSAGE(STATUS "Found SuiteSparseQR library: ${SUITESPARSEQR_LIBRARY}") 320 ELSE (EXISTS ${SUITESPARSEQR_LIBRARY}) 321 SUITESPARSE_REPORT_NOT_FOUND( 322 "Did not find SuiteSparseQR library (required SuiteSparse component).") 323 SET(SUITESPARSEQR_FOUND FALSE) 324 ENDIF (EXISTS ${SUITESPARSEQR_LIBRARY}) 325 MARK_AS_ADVANCED(SUITESPARSEQR_LIBRARY) 326 327 FIND_PATH(SUITESPARSEQR_INCLUDE_DIR NAMES SuiteSparseQR.hpp 328 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 329 IF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR}) 330 MESSAGE(STATUS "Found SuiteSparseQR header in: ${SUITESPARSEQR_INCLUDE_DIR}") 331 ELSE (EXISTS ${SUITESPARSEQR_INCLUDE_DIR}) 332 SUITESPARSE_REPORT_NOT_FOUND( 333 "Did not find SUITESPARSEQR header (required SuiteSparse component).") 334 SET(SUITESPARSEQR_FOUND FALSE) 335 ENDIF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR}) 336 MARK_AS_ADVANCED(SUITESPARSEQR_INCLUDE_DIR) 337 338 IF (SUITESPARSEQR_FOUND) 339 # SuiteSparseQR may be compiled with Intel Threading Building Blocks, 340 # we assume that if TBB is installed, SuiteSparseQR was compiled with 341 # support for it, this will do no harm if it wasn't. 342 SET(TBB_FOUND TRUE) 343 FIND_LIBRARY(TBB_LIBRARIES NAMES tbb 344 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 345 IF (EXISTS ${TBB_LIBRARIES}) 346 MESSAGE(STATUS "Found Intel Thread Building Blocks (TBB) library: " 347 "${TBB_LIBRARIES}, assuming SuiteSparseQR was compiled with TBB.") 348 ELSE (EXISTS ${TBB_LIBRARIES}) 349 MESSAGE(STATUS "Did not find Intel TBB library, assuming SuiteSparseQR was " 350 "not compiled with TBB.") 351 SET(TBB_FOUND FALSE) 352 ENDIF (EXISTS ${TBB_LIBRARIES}) 353 MARK_AS_ADVANCED(TBB_LIBRARIES) 354 355 IF (TBB_FOUND) 356 FIND_LIBRARY(TBB_MALLOC_LIB NAMES tbbmalloc 357 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 358 IF (EXISTS ${TBB_MALLOC_LIB}) 359 MESSAGE(STATUS "Found Intel Thread Building Blocks (TBB) Malloc library: " 360 "${TBB_MALLOC_LIB}") 361 # Append TBB malloc library to TBB libraries list whilst retaining 362 # any CMake generated help string (cache variable). 363 LIST(APPEND TBB_LIBRARIES ${TBB_MALLOC_LIB}) 364 GET_PROPERTY(HELP_STRING CACHE TBB_LIBRARIES PROPERTY HELPSTRING) 365 SET(TBB_LIBRARIES "${TBB_LIBRARIES}" CACHE STRING ${HELP_STRING}) 366 367 # Add the TBB libraries to the SuiteSparseQR libraries (the only 368 # libraries to optionally depend on TBB). 369 LIST(APPEND SUITESPARSEQR_LIBRARY ${TBB_LIBRARIES}) 370 371 ELSE (EXISTS ${TBB_MALLOC_LIB}) 372 # If we cannot find all required TBB components do not include it as 373 # a dependency. 374 MESSAGE(STATUS "Did not find Intel Thread Building Blocks (TBB) Malloc " 375 "Library, discarding TBB as a dependency.") 376 SET(TBB_FOUND FALSE) 377 ENDIF (EXISTS ${TBB_MALLOC_LIB}) 378 MARK_AS_ADVANCED(TBB_MALLOC_LIB) 379 ENDIF (TBB_FOUND) 380 ENDIF(SUITESPARSEQR_FOUND) 381 382 # UFconfig / SuiteSparse_config. 383 # 384 # If SuiteSparse version is >= 4 then SuiteSparse_config is required. 385 # For SuiteSparse 3, UFconfig.h is required. 386 FIND_LIBRARY(SUITESPARSE_CONFIG_LIBRARY NAMES suitesparseconfig 387 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 388 IF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY}) 389 MESSAGE(STATUS "Found SuiteSparse_config library: " 390 "${SUITESPARSE_CONFIG_LIBRARY}") 391 ENDIF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY}) 392 MARK_AS_ADVANCED(SUITESPARSE_CONFIG_LIBRARY) 393 394 FIND_PATH(SUITESPARSE_CONFIG_INCLUDE_DIR NAMES SuiteSparse_config.h 395 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 396 IF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 397 MESSAGE(STATUS "Found SuiteSparse_config header in: " 398 "${SUITESPARSE_CONFIG_INCLUDE_DIR}") 399 ENDIF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 400 MARK_AS_ADVANCED(SUITESPARSE_CONFIG_INCLUDE_DIR) 401 402 SET(SUITESPARSE_CONFIG_FOUND FALSE) 403 SET(UFCONFIG_FOUND FALSE) 404 405 IF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND 406 EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 407 SET(SUITESPARSE_CONFIG_FOUND TRUE) 408 # SuiteSparse_config (SuiteSparse version >= 4) requires librt library for 409 # timing by default when compiled on Linux or Unix, but not on OSX (which 410 # does not have librt). 411 IF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR UNIX AND NOT APPLE) 412 FIND_LIBRARY(LIBRT_LIBRARY NAMES rt 413 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 414 IF (LIBRT_LIBRARY) 415 MESSAGE(STATUS "Adding librt: ${LIBRT_LIBRARY} to " 416 "SuiteSparse_config libraries (required on Linux & Unix [not OSX] if " 417 "SuiteSparse is compiled with timing).") 418 ELSE (LIBRT_LIBRARY) 419 MESSAGE(STATUS "Could not find librt, but found SuiteSparse_config, " 420 "assuming that SuiteSparse was compiled without timing.") 421 ENDIF (LIBRT_LIBRARY) 422 MARK_AS_ADVANCED(LIBRT_LIBRARY) 423 LIST(APPEND SUITESPARSE_CONFIG_LIBRARY ${LIBRT_LIBRARY}) 424 ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR UNIX AND NOT APPLE) 425 426 ELSE (EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND 427 EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 428 # Failed to find SuiteSparse_config (>= v4 installs), instead look for 429 # UFconfig header which should be present in < v4 installs. 430 SET(SUITESPARSE_CONFIG_FOUND FALSE) 431 FIND_PATH(UFCONFIG_INCLUDE_DIR NAMES UFconfig.h 432 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 433 IF (EXISTS ${UFCONFIG_INCLUDE_DIR}) 434 MESSAGE(STATUS "Found UFconfig header in: ${UFCONFIG_INCLUDE_DIR}") 435 SET(UFCONFIG_FOUND TRUE) 436 ENDIF (EXISTS ${UFCONFIG_INCLUDE_DIR}) 437 MARK_AS_ADVANCED(UFCONFIG_INCLUDE_DIR) 438 ENDIF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND 439 EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 440 441 IF (NOT SUITESPARSE_CONFIG_FOUND AND 442 NOT UFCONFIG_FOUND) 443 SUITESPARSE_REPORT_NOT_FOUND( 444 "Failed to find either: SuiteSparse_config header & library (should be " 445 "present in all SuiteSparse >= v4 installs), or UFconfig header (should " 446 "be present in all SuiteSparse < v4 installs).") 447 ENDIF (NOT SUITESPARSE_CONFIG_FOUND AND 448 NOT UFCONFIG_FOUND) 449 450 # Extract the SuiteSparse version from the appropriate header (UFconfig.h for 451 # <= v3, SuiteSparse_config.h for >= v4). 452 LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS SUITESPARSE_VERSION) 453 454 IF (UFCONFIG_FOUND) 455 # SuiteSparse version <= 3. 456 SET(SUITESPARSE_VERSION_FILE ${UFCONFIG_INCLUDE_DIR}/UFconfig.h) 457 IF (NOT EXISTS ${SUITESPARSE_VERSION_FILE}) 458 SUITESPARSE_REPORT_NOT_FOUND( 459 "Could not find file: ${SUITESPARSE_VERSION_FILE} containing version " 460 "information for <= v3 SuiteSparse installs, but UFconfig was found " 461 "(only present in <= v3 installs).") 462 ELSE (NOT EXISTS ${SUITESPARSE_VERSION_FILE}) 463 FILE(READ ${SUITESPARSE_VERSION_FILE} UFCONFIG_CONTENTS) 464 465 STRING(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+" 466 SUITESPARSE_MAIN_VERSION "${UFCONFIG_CONTENTS}") 467 STRING(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1" 468 SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}") 469 470 STRING(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+" 471 SUITESPARSE_SUB_VERSION "${UFCONFIG_CONTENTS}") 472 STRING(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1" 473 SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}") 474 475 STRING(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+" 476 SUITESPARSE_SUBSUB_VERSION "${UFCONFIG_CONTENTS}") 477 STRING(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1" 478 SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}") 479 480 # This is on a single line s/t CMake does not interpret it as a list of 481 # elements and insert ';' separators which would result in 4.;2.;1 nonsense. 482 SET(SUITESPARSE_VERSION 483 "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}") 484 ENDIF (NOT EXISTS ${SUITESPARSE_VERSION_FILE}) 485 ENDIF (UFCONFIG_FOUND) 486 487 IF (SUITESPARSE_CONFIG_FOUND) 488 # SuiteSparse version >= 4. 489 SET(SUITESPARSE_VERSION_FILE 490 ${SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h) 491 IF (NOT EXISTS ${SUITESPARSE_VERSION_FILE}) 492 SUITESPARSE_REPORT_NOT_FOUND( 493 "Could not find file: ${SUITESPARSE_VERSION_FILE} containing version " 494 "information for >= v4 SuiteSparse installs, but SuiteSparse_config was " 495 "found (only present in >= v4 installs).") 496 ELSE (NOT EXISTS ${SUITESPARSE_VERSION_FILE}) 497 FILE(READ ${SUITESPARSE_VERSION_FILE} SUITESPARSE_CONFIG_CONTENTS) 498 499 STRING(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+" 500 SUITESPARSE_MAIN_VERSION "${SUITESPARSE_CONFIG_CONTENTS}") 501 STRING(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1" 502 SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}") 503 504 STRING(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+" 505 SUITESPARSE_SUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}") 506 STRING(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1" 507 SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}") 508 509 STRING(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+" 510 SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}") 511 STRING(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1" 512 SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}") 513 514 # This is on a single line s/t CMake does not interpret it as a list of 515 # elements and insert ';' separators which would result in 4.;2.;1 nonsense. 516 SET(SUITESPARSE_VERSION 517 "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}") 518 ENDIF (NOT EXISTS ${SUITESPARSE_VERSION_FILE}) 519 ENDIF (SUITESPARSE_CONFIG_FOUND) 520 521 # METIS (Optional dependency). 522 FIND_LIBRARY(METIS_LIBRARY NAMES metis 523 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 524 IF (EXISTS ${METIS_LIBRARY}) 525 MESSAGE(STATUS "Found METIS library: ${METIS_LIBRARY}.") 526 set(METIS_FOUND TRUE) 527 ELSE (EXISTS ${METIS_LIBRARY}) 528 MESSAGE(STATUS "Did not find METIS library (optional SuiteSparse dependency)") 529 set(METIS_FOUND FALSE) 530 ENDIF (EXISTS ${METIS_LIBRARY}) 531 MARK_AS_ADVANCED(METIS_LIBRARY) 532 533 # Only mark SuiteSparse as found if all required components and dependencies 534 # have been found. 535 SET(SUITESPARSE_FOUND TRUE) 536 FOREACH(REQUIRED_VAR ${SUITESPARSE_FOUND_REQUIRED_VARS}) 537 IF (NOT ${REQUIRED_VAR}) 538 SET(SUITESPARSE_FOUND FALSE) 539 ENDIF (NOT ${REQUIRED_VAR}) 540 ENDFOREACH(REQUIRED_VAR ${SUITESPARSE_FOUND_REQUIRED_VARS}) 541 542 IF (SUITESPARSE_FOUND) 543 LIST(APPEND SUITESPARSE_INCLUDE_DIRS 544 ${AMD_INCLUDE_DIR} 545 ${CAMD_INCLUDE_DIR} 546 ${COLAMD_INCLUDE_DIR} 547 ${CCOLAMD_INCLUDE_DIR} 548 ${CHOLMOD_INCLUDE_DIR} 549 ${SUITESPARSEQR_INCLUDE_DIR}) 550 # Handle config separately, as otherwise at least one of them will be set 551 # to NOTFOUND which would cause any check on SUITESPARSE_INCLUDE_DIRS to fail. 552 IF (SUITESPARSE_CONFIG_FOUND) 553 LIST(APPEND SUITESPARSE_INCLUDE_DIRS 554 ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 555 ENDIF (SUITESPARSE_CONFIG_FOUND) 556 IF (UFCONFIG_FOUND) 557 LIST(APPEND SUITESPARSE_INCLUDE_DIRS 558 ${UFCONFIG_INCLUDE_DIR}) 559 ENDIF (UFCONFIG_FOUND) 560 # As SuiteSparse includes are often all in the same directory, remove any 561 # repetitions. 562 LIST(REMOVE_DUPLICATES SUITESPARSE_INCLUDE_DIRS) 563 564 # Important: The ordering of these libraries is *NOT* arbitrary, as these 565 # could potentially be static libraries their link ordering is important. 566 LIST(APPEND SUITESPARSE_LIBRARIES 567 ${SUITESPARSEQR_LIBRARY} 568 ${CHOLMOD_LIBRARY} 569 ${CCOLAMD_LIBRARY} 570 ${CAMD_LIBRARY} 571 ${COLAMD_LIBRARY} 572 ${AMD_LIBRARY} 573 ${LAPACK_LIBRARIES} 574 ${BLAS_LIBRARIES}) 575 IF (SUITESPARSE_CONFIG_FOUND) 576 LIST(APPEND SUITESPARSE_LIBRARIES 577 ${SUITESPARSE_CONFIG_LIBRARY}) 578 ENDIF (SUITESPARSE_CONFIG_FOUND) 579 IF (METIS_FOUND) 580 LIST(APPEND SUITESPARSE_LIBRARIES 581 ${METIS_LIBRARY}) 582 ENDIF (METIS_FOUND) 583 ENDIF() 584 585 # Determine if we are running on Ubuntu with the package install of SuiteSparse 586 # which is broken and does not support linking a shared library. 587 SET(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION FALSE) 588 IF (CMAKE_SYSTEM_NAME MATCHES "Linux" AND 589 SUITESPARSE_VERSION VERSION_EQUAL 3.4.0) 590 FIND_PROGRAM(LSB_RELEASE_EXECUTABLE lsb_release) 591 IF (LSB_RELEASE_EXECUTABLE) 592 # Any even moderately recent Ubuntu release (likely to be affected by 593 # this bug) should have lsb_release, if it isn't present we are likely 594 # on a different Linux distribution (should be fine). 595 596 EXECUTE_PROCESS(COMMAND ${LSB_RELEASE_EXECUTABLE} -si 597 OUTPUT_VARIABLE LSB_DISTRIBUTOR_ID 598 OUTPUT_STRIP_TRAILING_WHITESPACE) 599 600 IF (LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND 601 SUITESPARSE_LIBRARIES MATCHES "/usr/lib/libamd") 602 # We are on Ubuntu, and the SuiteSparse version matches the broken 603 # system install version and is a system install. 604 SET(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION TRUE) 605 MESSAGE(STATUS "Found system install of SuiteSparse " 606 "${SUITESPARSE_VERSION} running on Ubuntu, which has a known bug " 607 "preventing linking of shared libraries (static linking unaffected).") 608 ENDIF (LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND 609 SUITESPARSE_LIBRARIES MATCHES "/usr/lib/libamd") 610 ENDIF (LSB_RELEASE_EXECUTABLE) 611 ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux" AND 612 SUITESPARSE_VERSION VERSION_EQUAL 3.4.0) 613 614 # Handle REQUIRED and QUIET arguments to FIND_PACKAGE 615 INCLUDE(FindPackageHandleStandardArgs) 616 IF (SUITESPARSE_FOUND) 617 FIND_PACKAGE_HANDLE_STANDARD_ARGS(SuiteSparse 618 REQUIRED_VARS ${SUITESPARSE_FOUND_REQUIRED_VARS} 619 VERSION_VAR SUITESPARSE_VERSION 620 FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse.") 621 ELSE (SUITESPARSE_FOUND) 622 # Do not pass VERSION_VAR to FindPackageHandleStandardArgs() if we failed to 623 # find SuiteSparse to avoid a confusing autogenerated failure message 624 # that states 'not found (missing: FOO) (found version: x.y.z)'. 625 FIND_PACKAGE_HANDLE_STANDARD_ARGS(SuiteSparse 626 REQUIRED_VARS ${SUITESPARSE_FOUND_REQUIRED_VARS} 627 FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse.") 628 ENDIF (SUITESPARSE_FOUND) 629