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@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. 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 # 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. 141ENDMACRO(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. 147LIST(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) 156LIST(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. 170UNSET(SUITESPARSE_FOUND_REQUIRED_VARS) 171 172# BLAS. 173FIND_PACKAGE(BLAS QUIET) 174IF (NOT BLAS_FOUND) 175 SUITESPARSE_REPORT_NOT_FOUND( 176 "Did not find BLAS library (required for SuiteSparse).") 177ENDIF (NOT BLAS_FOUND) 178LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS BLAS_FOUND) 179 180# LAPACK. 181FIND_PACKAGE(LAPACK QUIET) 182IF (NOT LAPACK_FOUND) 183 SUITESPARSE_REPORT_NOT_FOUND( 184 "Did not find LAPACK library (required for SuiteSparse).") 185ENDIF (NOT LAPACK_FOUND) 186LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS LAPACK_FOUND) 187 188# AMD. 189SET(AMD_FOUND TRUE) 190LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS AMD_FOUND) 191FIND_LIBRARY(AMD_LIBRARY NAMES amd 192 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 193IF (EXISTS ${AMD_LIBRARY}) 194 MESSAGE(STATUS "Found AMD library: ${AMD_LIBRARY}") 195ELSE (EXISTS ${AMD_LIBRARY}) 196 SUITESPARSE_REPORT_NOT_FOUND( 197 "Did not find AMD library (required SuiteSparse component).") 198 SET(AMD_FOUND FALSE) 199ENDIF (EXISTS ${AMD_LIBRARY}) 200MARK_AS_ADVANCED(AMD_LIBRARY) 201 202FIND_PATH(AMD_INCLUDE_DIR NAMES amd.h 203 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 204IF (EXISTS ${AMD_INCLUDE_DIR}) 205 MESSAGE(STATUS "Found AMD header in: ${AMD_INCLUDE_DIR}") 206ELSE (EXISTS ${AMD_INCLUDE_DIR}) 207 SUITESPARSE_REPORT_NOT_FOUND( 208 "Did not find AMD header (required SuiteSparse component).") 209 SET(AMD_FOUND FALSE) 210ENDIF (EXISTS ${AMD_INCLUDE_DIR}) 211MARK_AS_ADVANCED(AMD_INCLUDE_DIR) 212 213# CAMD. 214SET(CAMD_FOUND TRUE) 215LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS CAMD_FOUND) 216FIND_LIBRARY(CAMD_LIBRARY NAMES camd 217 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 218IF (EXISTS ${CAMD_LIBRARY}) 219 MESSAGE(STATUS "Found CAMD library: ${CAMD_LIBRARY}") 220ELSE (EXISTS ${CAMD_LIBRARY}) 221 SUITESPARSE_REPORT_NOT_FOUND( 222 "Did not find CAMD library (required SuiteSparse component).") 223 SET(CAMD_FOUND FALSE) 224ENDIF (EXISTS ${CAMD_LIBRARY}) 225MARK_AS_ADVANCED(CAMD_LIBRARY) 226 227FIND_PATH(CAMD_INCLUDE_DIR NAMES camd.h 228 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 229IF (EXISTS ${CAMD_INCLUDE_DIR}) 230 MESSAGE(STATUS "Found CAMD header in: ${CAMD_INCLUDE_DIR}") 231ELSE (EXISTS ${CAMD_INCLUDE_DIR}) 232 SUITESPARSE_REPORT_NOT_FOUND( 233 "Did not find CAMD header (required SuiteSparse component).") 234 SET(CAMD_FOUND FALSE) 235ENDIF (EXISTS ${CAMD_INCLUDE_DIR}) 236MARK_AS_ADVANCED(CAMD_INCLUDE_DIR) 237 238# COLAMD. 239SET(COLAMD_FOUND TRUE) 240LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS COLAMD_FOUND) 241FIND_LIBRARY(COLAMD_LIBRARY NAMES colamd 242 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 243IF (EXISTS ${COLAMD_LIBRARY}) 244 MESSAGE(STATUS "Found COLAMD library: ${COLAMD_LIBRARY}") 245ELSE (EXISTS ${COLAMD_LIBRARY}) 246 SUITESPARSE_REPORT_NOT_FOUND( 247 "Did not find COLAMD library (required SuiteSparse component).") 248 SET(COLAMD_FOUND FALSE) 249ENDIF (EXISTS ${COLAMD_LIBRARY}) 250MARK_AS_ADVANCED(COLAMD_LIBRARY) 251 252FIND_PATH(COLAMD_INCLUDE_DIR NAMES colamd.h 253 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 254IF (EXISTS ${COLAMD_INCLUDE_DIR}) 255 MESSAGE(STATUS "Found COLAMD header in: ${COLAMD_INCLUDE_DIR}") 256ELSE (EXISTS ${COLAMD_INCLUDE_DIR}) 257 SUITESPARSE_REPORT_NOT_FOUND( 258 "Did not find COLAMD header (required SuiteSparse component).") 259 SET(COLAMD_FOUND FALSE) 260ENDIF (EXISTS ${COLAMD_INCLUDE_DIR}) 261MARK_AS_ADVANCED(COLAMD_INCLUDE_DIR) 262 263# CCOLAMD. 264SET(CCOLAMD_FOUND TRUE) 265LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS CCOLAMD_FOUND) 266FIND_LIBRARY(CCOLAMD_LIBRARY NAMES ccolamd 267 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 268IF (EXISTS ${CCOLAMD_LIBRARY}) 269 MESSAGE(STATUS "Found CCOLAMD library: ${CCOLAMD_LIBRARY}") 270ELSE (EXISTS ${CCOLAMD_LIBRARY}) 271 SUITESPARSE_REPORT_NOT_FOUND( 272 "Did not find CCOLAMD library (required SuiteSparse component).") 273 SET(CCOLAMD_FOUND FALSE) 274ENDIF (EXISTS ${CCOLAMD_LIBRARY}) 275MARK_AS_ADVANCED(CCOLAMD_LIBRARY) 276 277FIND_PATH(CCOLAMD_INCLUDE_DIR NAMES ccolamd.h 278 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 279IF (EXISTS ${CCOLAMD_INCLUDE_DIR}) 280 MESSAGE(STATUS "Found CCOLAMD header in: ${CCOLAMD_INCLUDE_DIR}") 281ELSE (EXISTS ${CCOLAMD_INCLUDE_DIR}) 282 SUITESPARSE_REPORT_NOT_FOUND( 283 "Did not find CCOLAMD header (required SuiteSparse component).") 284 SET(CCOLAMD_FOUND FALSE) 285ENDIF (EXISTS ${CCOLAMD_INCLUDE_DIR}) 286MARK_AS_ADVANCED(CCOLAMD_INCLUDE_DIR) 287 288# CHOLMOD. 289SET(CHOLMOD_FOUND TRUE) 290LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS CHOLMOD_FOUND) 291FIND_LIBRARY(CHOLMOD_LIBRARY NAMES cholmod 292 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 293IF (EXISTS ${CHOLMOD_LIBRARY}) 294 MESSAGE(STATUS "Found CHOLMOD library: ${CHOLMOD_LIBRARY}") 295ELSE (EXISTS ${CHOLMOD_LIBRARY}) 296 SUITESPARSE_REPORT_NOT_FOUND( 297 "Did not find CHOLMOD library (required SuiteSparse component).") 298 SET(CHOLMOD_FOUND FALSE) 299ENDIF (EXISTS ${CHOLMOD_LIBRARY}) 300MARK_AS_ADVANCED(CHOLMOD_LIBRARY) 301 302FIND_PATH(CHOLMOD_INCLUDE_DIR NAMES cholmod.h 303 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 304IF (EXISTS ${CHOLMOD_INCLUDE_DIR}) 305 MESSAGE(STATUS "Found CHOLMOD header in: ${CHOLMOD_INCLUDE_DIR}") 306ELSE (EXISTS ${CHOLMOD_INCLUDE_DIR}) 307 SUITESPARSE_REPORT_NOT_FOUND( 308 "Did not find CHOLMOD header (required SuiteSparse component).") 309 SET(CHOLMOD_FOUND FALSE) 310ENDIF (EXISTS ${CHOLMOD_INCLUDE_DIR}) 311MARK_AS_ADVANCED(CHOLMOD_INCLUDE_DIR) 312 313# SuiteSparseQR. 314SET(SUITESPARSEQR_FOUND TRUE) 315LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS SUITESPARSEQR_FOUND) 316FIND_LIBRARY(SUITESPARSEQR_LIBRARY NAMES spqr 317 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 318IF (EXISTS ${SUITESPARSEQR_LIBRARY}) 319 MESSAGE(STATUS "Found SuiteSparseQR library: ${SUITESPARSEQR_LIBRARY}") 320ELSE (EXISTS ${SUITESPARSEQR_LIBRARY}) 321 SUITESPARSE_REPORT_NOT_FOUND( 322 "Did not find SuiteSparseQR library (required SuiteSparse component).") 323 SET(SUITESPARSEQR_FOUND FALSE) 324ENDIF (EXISTS ${SUITESPARSEQR_LIBRARY}) 325MARK_AS_ADVANCED(SUITESPARSEQR_LIBRARY) 326 327FIND_PATH(SUITESPARSEQR_INCLUDE_DIR NAMES SuiteSparseQR.hpp 328 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 329IF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR}) 330 MESSAGE(STATUS "Found SuiteSparseQR header in: ${SUITESPARSEQR_INCLUDE_DIR}") 331ELSE (EXISTS ${SUITESPARSEQR_INCLUDE_DIR}) 332 SUITESPARSE_REPORT_NOT_FOUND( 333 "Did not find SUITESPARSEQR header (required SuiteSparse component).") 334 SET(SUITESPARSEQR_FOUND FALSE) 335ENDIF (EXISTS ${SUITESPARSEQR_INCLUDE_DIR}) 336MARK_AS_ADVANCED(SUITESPARSEQR_INCLUDE_DIR) 337 338IF (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) 380ENDIF(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. 386FIND_LIBRARY(SUITESPARSE_CONFIG_LIBRARY NAMES suitesparseconfig 387 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 388IF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY}) 389 MESSAGE(STATUS "Found SuiteSparse_config library: " 390 "${SUITESPARSE_CONFIG_LIBRARY}") 391ENDIF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY}) 392MARK_AS_ADVANCED(SUITESPARSE_CONFIG_LIBRARY) 393 394FIND_PATH(SUITESPARSE_CONFIG_INCLUDE_DIR NAMES SuiteSparse_config.h 395 PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}) 396IF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 397 MESSAGE(STATUS "Found SuiteSparse_config header in: " 398 "${SUITESPARSE_CONFIG_INCLUDE_DIR}") 399ENDIF (EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 400MARK_AS_ADVANCED(SUITESPARSE_CONFIG_INCLUDE_DIR) 401 402SET(SUITESPARSE_CONFIG_FOUND FALSE) 403SET(UFCONFIG_FOUND FALSE) 404 405IF (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 426ELSE (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) 438ENDIF (EXISTS ${SUITESPARSE_CONFIG_LIBRARY} AND 439 EXISTS ${SUITESPARSE_CONFIG_INCLUDE_DIR}) 440 441IF (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).") 447ENDIF (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). 452LIST(APPEND SUITESPARSE_FOUND_REQUIRED_VARS SUITESPARSE_VERSION) 453 454IF (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}) 485ENDIF (UFCONFIG_FOUND) 486 487IF (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}) 519ENDIF (SUITESPARSE_CONFIG_FOUND) 520 521# METIS (Optional dependency). 522FIND_LIBRARY(METIS_LIBRARY NAMES metis 523 PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}) 524IF (EXISTS ${METIS_LIBRARY}) 525 MESSAGE(STATUS "Found METIS library: ${METIS_LIBRARY}.") 526 set(METIS_FOUND TRUE) 527ELSE (EXISTS ${METIS_LIBRARY}) 528 MESSAGE(STATUS "Did not find METIS library (optional SuiteSparse dependency)") 529 set(METIS_FOUND FALSE) 530ENDIF (EXISTS ${METIS_LIBRARY}) 531MARK_AS_ADVANCED(METIS_LIBRARY) 532 533# Only mark SuiteSparse as found if all required components and dependencies 534# have been found. 535SET(SUITESPARSE_FOUND TRUE) 536FOREACH(REQUIRED_VAR ${SUITESPARSE_FOUND_REQUIRED_VARS}) 537 IF (NOT ${REQUIRED_VAR}) 538 SET(SUITESPARSE_FOUND FALSE) 539 ENDIF (NOT ${REQUIRED_VAR}) 540ENDFOREACH(REQUIRED_VAR ${SUITESPARSE_FOUND_REQUIRED_VARS}) 541 542IF (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) 583ENDIF() 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. 587SET(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION FALSE) 588IF (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) 611ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux" AND 612 SUITESPARSE_VERSION VERSION_EQUAL 3.4.0) 613 614# Handle REQUIRED and QUIET arguments to FIND_PACKAGE 615INCLUDE(FindPackageHandleStandardArgs) 616IF (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.") 621ELSE (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.") 628ENDIF (SUITESPARSE_FOUND) 629