FindSuiteSparse.cmake 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. # Ceres Solver - A fast non-linear least squares minimizer
  2. # Copyright 2015 Google Inc. All rights reserved.
  3. # http://ceres-solver.org/
  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. # FindSuiteSparse.cmake - Find SuiteSparse libraries & dependencies.
  32. #
  33. # This module defines the following variables:
  34. #
  35. # SUITESPARSE_FOUND: TRUE iff SuiteSparse and all dependencies have been found.
  36. # SUITESPARSE_INCLUDE_DIRS: Include directories for all SuiteSparse components.
  37. # SUITESPARSE_LIBRARIES: Libraries for all SuiteSparse component libraries and
  38. # dependencies.
  39. # SUITESPARSE_VERSION: Extracted from UFconfig.h (<= v3) or
  40. # SuiteSparse_config.h (>= v4).
  41. # SUITESPARSE_MAIN_VERSION: Equal to 4 if SUITESPARSE_VERSION = 4.2.1
  42. # SUITESPARSE_SUB_VERSION: Equal to 2 if SUITESPARSE_VERSION = 4.2.1
  43. # SUITESPARSE_SUBSUB_VERSION: Equal to 1 if SUITESPARSE_VERSION = 4.2.1
  44. #
  45. # SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION: TRUE iff running
  46. # on Ubuntu, SUITESPARSE_VERSION is 3.4.0 and found SuiteSparse is a system
  47. # install, in which case found version of SuiteSparse cannot be used to link
  48. # a shared library due to a bug (static linking is unaffected).
  49. #
  50. # The following variables control the behaviour of this module:
  51. #
  52. # SUITESPARSE_INCLUDE_DIR_HINTS: List of additional directories in which to
  53. # search for SuiteSparse includes,
  54. # e.g: /timbuktu/include.
  55. # SUITESPARSE_LIBRARY_DIR_HINTS: List of additional directories in which to
  56. # search for SuiteSparse libraries,
  57. # e.g: /timbuktu/lib.
  58. #
  59. # The following variables define the presence / includes & libraries for the
  60. # SuiteSparse components searched for, the SUITESPARSE_XX variables are the
  61. # union of the variables for all components.
  62. #
  63. # == Symmetric Approximate Minimum Degree (AMD)
  64. # AMD_FOUND
  65. # AMD_INCLUDE_DIR
  66. # AMD_LIBRARY
  67. #
  68. # == Constrained Approximate Minimum Degree (CAMD)
  69. # CAMD_FOUND
  70. # CAMD_INCLUDE_DIR
  71. # CAMD_LIBRARY
  72. #
  73. # == Column Approximate Minimum Degree (COLAMD)
  74. # COLAMD_FOUND
  75. # COLAMD_INCLUDE_DIR
  76. # COLAMD_LIBRARY
  77. #
  78. # Constrained Column Approximate Minimum Degree (CCOLAMD)
  79. # CCOLAMD_FOUND
  80. # CCOLAMD_INCLUDE_DIR
  81. # CCOLAMD_LIBRARY
  82. #
  83. # == Sparse Supernodal Cholesky Factorization and Update/Downdate (CHOLMOD)
  84. # CHOLMOD_FOUND
  85. # CHOLMOD_INCLUDE_DIR
  86. # CHOLMOD_LIBRARY
  87. #
  88. # == Multifrontal Sparse QR (SuiteSparseQR)
  89. # SUITESPARSEQR_FOUND
  90. # SUITESPARSEQR_INCLUDE_DIR
  91. # SUITESPARSEQR_LIBRARY
  92. #
  93. # == Common configuration for all but CSparse (SuiteSparse version >= 4).
  94. # SUITESPARSE_CONFIG_FOUND
  95. # SUITESPARSE_CONFIG_INCLUDE_DIR
  96. # SUITESPARSE_CONFIG_LIBRARY
  97. #
  98. # == Common configuration for all but CSparse (SuiteSparse version < 4).
  99. # UFCONFIG_FOUND
  100. # UFCONFIG_INCLUDE_DIR
  101. #
  102. # Optional SuiteSparse Dependencies:
  103. #
  104. # == Serial Graph Partitioning and Fill-reducing Matrix Ordering (METIS)
  105. # METIS_FOUND
  106. # METIS_LIBRARY
  107. #
  108. # == Intel Thread Building Blocks (TBB)
  109. # TBB_FOUND
  110. # TBB_LIBRARY
  111. # TBB_MALLOC_FOUND
  112. # TBB_MALLOC_LIBRARY
  113. # Reset CALLERS_CMAKE_FIND_LIBRARY_PREFIXES to its value when
  114. # FindSuiteSparse was invoked.
  115. macro(SUITESPARSE_RESET_FIND_LIBRARY_PREFIX)
  116. if (MSVC)
  117. set(CMAKE_FIND_LIBRARY_PREFIXES "${CALLERS_CMAKE_FIND_LIBRARY_PREFIXES}")
  118. endif (MSVC)
  119. endmacro(SUITESPARSE_RESET_FIND_LIBRARY_PREFIX)
  120. # Called if we failed to find SuiteSparse or any of it's required dependencies,
  121. # unsets all public (designed to be used externally) variables and reports
  122. # error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
  123. macro(SUITESPARSE_REPORT_NOT_FOUND REASON_MSG)
  124. unset(SUITESPARSE_FOUND)
  125. unset(SUITESPARSE_INCLUDE_DIRS)
  126. unset(SUITESPARSE_LIBRARIES)
  127. unset(SUITESPARSE_VERSION)
  128. unset(SUITESPARSE_MAIN_VERSION)
  129. unset(SUITESPARSE_SUB_VERSION)
  130. unset(SUITESPARSE_SUBSUB_VERSION)
  131. # Do NOT unset SUITESPARSE_FOUND_REQUIRED_VARS here, as it is used by
  132. # FindPackageHandleStandardArgs() to generate the automatic error message on
  133. # failure which highlights which components are missing.
  134. suitesparse_reset_find_library_prefix()
  135. # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
  136. # use the camelcase library name, not uppercase.
  137. if (SuiteSparse_FIND_QUIETLY)
  138. message(STATUS "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  139. elseif (SuiteSparse_FIND_REQUIRED)
  140. message(FATAL_ERROR "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  141. else()
  142. # Neither QUIETLY nor REQUIRED, use no priority which emits a message
  143. # but continues configuration and allows generation.
  144. message("-- Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  145. endif (SuiteSparse_FIND_QUIETLY)
  146. # Do not call return(), s/t we keep processing if not called with REQUIRED
  147. # and report all missing components, rather than bailing after failing to find
  148. # the first.
  149. endmacro(SUITESPARSE_REPORT_NOT_FOUND)
  150. # Protect against any alternative find_package scripts for this library having
  151. # been called previously (in a client project) which set SUITESPARSE_FOUND, but
  152. # not the other variables we require / set here which could cause the search
  153. # logic here to fail.
  154. unset(SUITESPARSE_FOUND)
  155. # Handle possible presence of lib prefix for libraries on MSVC, see
  156. # also SUITESPARSE_RESET_FIND_LIBRARY_PREFIX().
  157. if (MSVC)
  158. # Preserve the caller's original values for CMAKE_FIND_LIBRARY_PREFIXES
  159. # s/t we can set it back before returning.
  160. set(CALLERS_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
  161. # The empty string in this list is important, it represents the case when
  162. # the libraries have no prefix (shared libraries / DLLs).
  163. set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "" "${CMAKE_FIND_LIBRARY_PREFIXES}")
  164. endif (MSVC)
  165. # Specify search directories for include files and libraries (this is the union
  166. # of the search directories for all OSs). Search user-specified hint
  167. # directories first if supplied, and search user-installed locations first
  168. # so that we prefer user installs to system installs where both exist.
  169. list(APPEND SUITESPARSE_CHECK_INCLUDE_DIRS
  170. /opt/local/include
  171. /opt/local/include/ufsparse # Mac OS X
  172. /usr/local/homebrew/include # Mac OS X
  173. /usr/local/include
  174. /usr/include)
  175. list(APPEND SUITESPARSE_CHECK_LIBRARY_DIRS
  176. /opt/local/lib
  177. /opt/local/lib/ufsparse # Mac OS X
  178. /usr/local/homebrew/lib # Mac OS X
  179. /usr/local/lib
  180. /usr/lib)
  181. # Additional suffixes to try appending to each search path.
  182. list(APPEND SUITESPARSE_CHECK_PATH_SUFFIXES
  183. suitesparse) # Windows/Ubuntu
  184. # Wrappers to find_path/library that pass the SuiteSparse search hints/paths.
  185. #
  186. # suitesparse_find_component(<component> [FILES name1 [name2 ...]]
  187. # [LIBRARIES name1 [name2 ...]]
  188. # [REQUIRED])
  189. macro(suitesparse_find_component COMPONENT)
  190. include(CMakeParseArguments)
  191. set(OPTIONS REQUIRED)
  192. set(MULTI_VALUE_ARGS FILES LIBRARIES)
  193. cmake_parse_arguments(SUITESPARSE_FIND_${COMPONENT}
  194. "${OPTIONS}" "" "${MULTI_VALUE_ARGS}" ${ARGN})
  195. if (SUITESPARSE_FIND_${COMPONENT}_REQUIRED)
  196. list(APPEND SUITESPARSE_FOUND_REQUIRED_VARS ${COMPONENT}_FOUND)
  197. endif()
  198. set(${COMPONENT}_FOUND TRUE)
  199. if (SUITESPARSE_FIND_${COMPONENT}_FILES)
  200. find_path(${COMPONENT}_INCLUDE_DIR
  201. NAMES ${SUITESPARSE_FIND_${COMPONENT}_FILES}
  202. HINTS ${SUITESPARSE_INCLUDE_DIR_HINTS}
  203. PATHS ${SUITESPARSE_CHECK_INCLUDE_DIRS}
  204. PATH_SUFFIXES ${SUITESPARSE_CHECK_PATH_SUFFIXES})
  205. if (${COMPONENT}_INCLUDE_DIR)
  206. message(STATUS "Found ${COMPONENT} headers in: "
  207. "${${COMPONENT}_INCLUDE_DIR}")
  208. mark_as_advanced(${COMPONENT}_INCLUDE_DIR)
  209. else()
  210. # Specified headers not found.
  211. set(${COMPONENT}_FOUND FALSE)
  212. if (SUITESPARSE_FIND_${COMPONENT}_REQUIRED)
  213. suitesparse_report_not_found(
  214. "Did not find ${COMPONENT} header (required SuiteSparse component).")
  215. else()
  216. message(STATUS "Did not find ${COMPONENT} header (optional "
  217. "SuiteSparse component).")
  218. # Hide optional vars from CMake GUI even if not found.
  219. mark_as_advanced(${COMPONENT}_INCLUDE_DIR)
  220. endif()
  221. endif()
  222. endif()
  223. if (SUITESPARSE_FIND_${COMPONENT}_LIBRARIES)
  224. find_library(${COMPONENT}_LIBRARY
  225. NAMES ${SUITESPARSE_FIND_${COMPONENT}_LIBRARIES}
  226. HINTS ${SUITESPARSE_LIBRARY_DIR_HINTS}
  227. PATHS ${SUITESPARSE_CHECK_LIBRARY_DIRS}
  228. PATH_SUFFIXES ${SUITESPARSE_CHECK_PATH_SUFFIXES})
  229. if (${COMPONENT}_LIBRARY)
  230. message(STATUS "Found ${COMPONENT} library: ${${COMPONENT}_LIBRARY}")
  231. mark_as_advanced(${COMPONENT}_LIBRARY)
  232. else ()
  233. # Specified libraries not found.
  234. set(${COMPONENT}_FOUND FALSE)
  235. if (SUITESPARSE_FIND_${COMPONENT}_REQUIRED)
  236. suitesparse_report_not_found(
  237. "Did not find ${COMPONENT} library (required SuiteSparse component).")
  238. else()
  239. message(STATUS "Did not find ${COMPONENT} library (optional SuiteSparse "
  240. "dependency)")
  241. # Hide optional vars from CMake GUI even if not found.
  242. mark_as_advanced(${COMPONENT}_LIBRARY)
  243. endif()
  244. endif()
  245. endif()
  246. endmacro()
  247. # Given the number of components of SuiteSparse, and to ensure that the
  248. # automatic failure message generated by FindPackageHandleStandardArgs()
  249. # when not all required components are found is helpful, we maintain a list
  250. # of all variables that must be defined for SuiteSparse to be considered found.
  251. unset(SUITESPARSE_FOUND_REQUIRED_VARS)
  252. # BLAS.
  253. find_package(BLAS QUIET)
  254. if (NOT BLAS_FOUND)
  255. suitesparse_report_not_found(
  256. "Did not find BLAS library (required for SuiteSparse).")
  257. endif (NOT BLAS_FOUND)
  258. list(APPEND SUITESPARSE_FOUND_REQUIRED_VARS BLAS_FOUND)
  259. # LAPACK.
  260. find_package(LAPACK QUIET)
  261. if (NOT LAPACK_FOUND)
  262. suitesparse_report_not_found(
  263. "Did not find LAPACK library (required for SuiteSparse).")
  264. endif (NOT LAPACK_FOUND)
  265. list(APPEND SUITESPARSE_FOUND_REQUIRED_VARS LAPACK_FOUND)
  266. suitesparse_find_component(AMD REQUIRED FILES amd.h LIBRARIES amd)
  267. suitesparse_find_component(CAMD REQUIRED FILES camd.h LIBRARIES camd)
  268. suitesparse_find_component(COLAMD REQUIRED FILES colamd.h LIBRARIES colamd)
  269. suitesparse_find_component(CCOLAMD REQUIRED FILES ccolamd.h LIBRARIES ccolamd)
  270. suitesparse_find_component(CHOLMOD REQUIRED FILES cholmod.h LIBRARIES cholmod)
  271. suitesparse_find_component(
  272. SUITESPARSEQR REQUIRED FILES SuiteSparseQR.hpp LIBRARIES spqr)
  273. if (SUITESPARSEQR_FOUND)
  274. # SuiteSparseQR may be compiled with Intel Threading Building Blocks,
  275. # we assume that if TBB is installed, SuiteSparseQR was compiled with
  276. # support for it, this will do no harm if it wasn't.
  277. find_package(TBB QUIET)
  278. if (TBB_FOUND)
  279. message(STATUS "Found Intel Thread Building Blocks (TBB) library "
  280. "(${TBB_VERSION}) assuming SuiteSparseQR was compiled "
  281. "with TBB.")
  282. # Add the TBB libraries to the SuiteSparseQR libraries (the only
  283. # libraries to optionally depend on TBB).
  284. list(APPEND SUITESPARSEQR_LIBRARY ${TBB_LIBRARIES})
  285. else()
  286. message(STATUS "Did not find Intel TBB library, assuming SuiteSparseQR was "
  287. "not compiled with TBB.")
  288. endif()
  289. endif(SUITESPARSEQR_FOUND)
  290. # UFconfig / SuiteSparse_config.
  291. #
  292. # If SuiteSparse version is >= 4 then SuiteSparse_config is required.
  293. # For SuiteSparse 3, UFconfig.h is required.
  294. suitesparse_find_component(
  295. SUITESPARSE_CONFIG FILES SuiteSparse_config.h LIBRARIES suitesparseconfig)
  296. if (SUITESPARSE_CONFIG_FOUND)
  297. # SuiteSparse_config (SuiteSparse version >= 4) requires librt library for
  298. # timing by default when compiled on Linux or Unix, but not on OSX (which
  299. # does not have librt).
  300. if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR UNIX AND NOT APPLE)
  301. suitesparse_find_component(LIBRT LIBRARIES rt)
  302. if (LIBRT_FOUND)
  303. message(STATUS "Adding librt: ${LIBRT_LIBRARY} to "
  304. "SuiteSparse_config libraries (required on Linux & Unix [not OSX] if "
  305. "SuiteSparse is compiled with timing).")
  306. list(APPEND SUITESPARSE_CONFIG_LIBRARY ${LIBRT_LIBRARY})
  307. else()
  308. message(STATUS "Could not find librt, but found SuiteSparse_config, "
  309. "assuming that SuiteSparse was compiled without timing.")
  310. endif ()
  311. endif (CMAKE_SYSTEM_NAME MATCHES "Linux" OR UNIX AND NOT APPLE)
  312. else()
  313. # Failed to find SuiteSparse_config (>= v4 installs), instead look for
  314. # UFconfig header which should be present in < v4 installs.
  315. suitesparse_find_component(UFCONFIG FILES UFconfig.h)
  316. endif ()
  317. if (NOT SUITESPARSE_CONFIG_FOUND AND
  318. NOT UFCONFIG_FOUND)
  319. suitesparse_report_not_found(
  320. "Failed to find either: SuiteSparse_config header & library (should be "
  321. "present in all SuiteSparse >= v4 installs), or UFconfig header (should "
  322. "be present in all SuiteSparse < v4 installs).")
  323. endif()
  324. # Extract the SuiteSparse version from the appropriate header (UFconfig.h for
  325. # <= v3, SuiteSparse_config.h for >= v4).
  326. list(APPEND SUITESPARSE_FOUND_REQUIRED_VARS SUITESPARSE_VERSION)
  327. if (UFCONFIG_FOUND)
  328. # SuiteSparse version <= 3.
  329. set(SUITESPARSE_VERSION_FILE ${UFCONFIG_INCLUDE_DIR}/UFconfig.h)
  330. if (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
  331. suitesparse_report_not_found(
  332. "Could not find file: ${SUITESPARSE_VERSION_FILE} containing version "
  333. "information for <= v3 SuiteSparse installs, but UFconfig was found "
  334. "(only present in <= v3 installs).")
  335. else (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
  336. file(READ ${SUITESPARSE_VERSION_FILE} UFCONFIG_CONTENTS)
  337. string(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
  338. SUITESPARSE_MAIN_VERSION "${UFCONFIG_CONTENTS}")
  339. string(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
  340. SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}")
  341. string(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
  342. SUITESPARSE_SUB_VERSION "${UFCONFIG_CONTENTS}")
  343. string(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
  344. SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}")
  345. string(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
  346. SUITESPARSE_SUBSUB_VERSION "${UFCONFIG_CONTENTS}")
  347. string(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
  348. SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}")
  349. # This is on a single line s/t CMake does not interpret it as a list of
  350. # elements and insert ';' separators which would result in 4.;2.;1 nonsense.
  351. set(SUITESPARSE_VERSION
  352. "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
  353. endif (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
  354. endif (UFCONFIG_FOUND)
  355. if (SUITESPARSE_CONFIG_FOUND)
  356. # SuiteSparse version >= 4.
  357. set(SUITESPARSE_VERSION_FILE
  358. ${SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h)
  359. if (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
  360. suitesparse_report_not_found(
  361. "Could not find file: ${SUITESPARSE_VERSION_FILE} containing version "
  362. "information for >= v4 SuiteSparse installs, but SuiteSparse_config was "
  363. "found (only present in >= v4 installs).")
  364. else (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
  365. file(READ ${SUITESPARSE_VERSION_FILE} SUITESPARSE_CONFIG_CONTENTS)
  366. string(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION [0-9]+"
  367. SUITESPARSE_MAIN_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
  368. string(REGEX REPLACE "#define SUITESPARSE_MAIN_VERSION ([0-9]+)" "\\1"
  369. SUITESPARSE_MAIN_VERSION "${SUITESPARSE_MAIN_VERSION}")
  370. string(REGEX MATCH "#define SUITESPARSE_SUB_VERSION [0-9]+"
  371. SUITESPARSE_SUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
  372. string(REGEX REPLACE "#define SUITESPARSE_SUB_VERSION ([0-9]+)" "\\1"
  373. SUITESPARSE_SUB_VERSION "${SUITESPARSE_SUB_VERSION}")
  374. string(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION [0-9]+"
  375. SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_CONFIG_CONTENTS}")
  376. string(REGEX REPLACE "#define SUITESPARSE_SUBSUB_VERSION ([0-9]+)" "\\1"
  377. SUITESPARSE_SUBSUB_VERSION "${SUITESPARSE_SUBSUB_VERSION}")
  378. # This is on a single line s/t CMake does not interpret it as a list of
  379. # elements and insert ';' separators which would result in 4.;2.;1 nonsense.
  380. set(SUITESPARSE_VERSION
  381. "${SUITESPARSE_MAIN_VERSION}.${SUITESPARSE_SUB_VERSION}.${SUITESPARSE_SUBSUB_VERSION}")
  382. endif (NOT EXISTS ${SUITESPARSE_VERSION_FILE})
  383. endif (SUITESPARSE_CONFIG_FOUND)
  384. # METIS (Optional dependency).
  385. suitesparse_find_component(METIS LIBRARIES metis)
  386. # Only mark SuiteSparse as found if all required components and dependencies
  387. # have been found.
  388. set(SUITESPARSE_FOUND TRUE)
  389. foreach(REQUIRED_VAR ${SUITESPARSE_FOUND_REQUIRED_VARS})
  390. if (NOT ${REQUIRED_VAR})
  391. set(SUITESPARSE_FOUND FALSE)
  392. endif (NOT ${REQUIRED_VAR})
  393. endforeach(REQUIRED_VAR ${SUITESPARSE_FOUND_REQUIRED_VARS})
  394. if (SUITESPARSE_FOUND)
  395. list(APPEND SUITESPARSE_INCLUDE_DIRS
  396. ${AMD_INCLUDE_DIR}
  397. ${CAMD_INCLUDE_DIR}
  398. ${COLAMD_INCLUDE_DIR}
  399. ${CCOLAMD_INCLUDE_DIR}
  400. ${CHOLMOD_INCLUDE_DIR}
  401. ${SUITESPARSEQR_INCLUDE_DIR})
  402. # Handle config separately, as otherwise at least one of them will be set
  403. # to NOTFOUND which would cause any check on SUITESPARSE_INCLUDE_DIRS to fail.
  404. if (SUITESPARSE_CONFIG_FOUND)
  405. list(APPEND SUITESPARSE_INCLUDE_DIRS
  406. ${SUITESPARSE_CONFIG_INCLUDE_DIR})
  407. endif (SUITESPARSE_CONFIG_FOUND)
  408. if (UFCONFIG_FOUND)
  409. list(APPEND SUITESPARSE_INCLUDE_DIRS
  410. ${UFCONFIG_INCLUDE_DIR})
  411. endif (UFCONFIG_FOUND)
  412. # As SuiteSparse includes are often all in the same directory, remove any
  413. # repetitions.
  414. list(REMOVE_DUPLICATES SUITESPARSE_INCLUDE_DIRS)
  415. # Important: The ordering of these libraries is *NOT* arbitrary, as these
  416. # could potentially be static libraries their link ordering is important.
  417. list(APPEND SUITESPARSE_LIBRARIES
  418. ${SUITESPARSEQR_LIBRARY}
  419. ${CHOLMOD_LIBRARY}
  420. ${CCOLAMD_LIBRARY}
  421. ${CAMD_LIBRARY}
  422. ${COLAMD_LIBRARY}
  423. ${AMD_LIBRARY}
  424. ${LAPACK_LIBRARIES}
  425. ${BLAS_LIBRARIES})
  426. if (SUITESPARSE_CONFIG_FOUND)
  427. list(APPEND SUITESPARSE_LIBRARIES
  428. ${SUITESPARSE_CONFIG_LIBRARY})
  429. endif (SUITESPARSE_CONFIG_FOUND)
  430. if (METIS_FOUND)
  431. list(APPEND SUITESPARSE_LIBRARIES
  432. ${METIS_LIBRARY})
  433. endif (METIS_FOUND)
  434. endif()
  435. # Determine if we are running on Ubuntu with the package install of SuiteSparse
  436. # which is broken and does not support linking a shared library.
  437. set(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION FALSE)
  438. if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
  439. SUITESPARSE_VERSION VERSION_EQUAL 3.4.0)
  440. find_program(LSB_RELEASE_EXECUTABLE lsb_release)
  441. if (LSB_RELEASE_EXECUTABLE)
  442. # Any even moderately recent Ubuntu release (likely to be affected by
  443. # this bug) should have lsb_release, if it isn't present we are likely
  444. # on a different Linux distribution (should be fine).
  445. execute_process(COMMAND ${LSB_RELEASE_EXECUTABLE} -si
  446. OUTPUT_VARIABLE LSB_DISTRIBUTOR_ID
  447. OUTPUT_STRIP_TRAILING_WHITESPACE)
  448. if (LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND
  449. SUITESPARSE_LIBRARIES MATCHES "/usr/lib/libamd")
  450. # We are on Ubuntu, and the SuiteSparse version matches the broken
  451. # system install version and is a system install.
  452. set(SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION TRUE)
  453. message(STATUS "Found system install of SuiteSparse "
  454. "${SUITESPARSE_VERSION} running on Ubuntu, which has a known bug "
  455. "preventing linking of shared libraries (static linking unaffected).")
  456. endif (LSB_DISTRIBUTOR_ID MATCHES "Ubuntu" AND
  457. SUITESPARSE_LIBRARIES MATCHES "/usr/lib/libamd")
  458. endif (LSB_RELEASE_EXECUTABLE)
  459. endif (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
  460. SUITESPARSE_VERSION VERSION_EQUAL 3.4.0)
  461. suitesparse_reset_find_library_prefix()
  462. # Handle REQUIRED and QUIET arguments to FIND_PACKAGE
  463. include(FindPackageHandleStandardArgs)
  464. if (SUITESPARSE_FOUND)
  465. find_package_handle_standard_args(SuiteSparse
  466. REQUIRED_VARS ${SUITESPARSE_FOUND_REQUIRED_VARS}
  467. VERSION_VAR SUITESPARSE_VERSION
  468. FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse.")
  469. else (SUITESPARSE_FOUND)
  470. # Do not pass VERSION_VAR to FindPackageHandleStandardArgs() if we failed to
  471. # find SuiteSparse to avoid a confusing autogenerated failure message
  472. # that states 'not found (missing: FOO) (found version: x.y.z)'.
  473. find_package_handle_standard_args(SuiteSparse
  474. REQUIRED_VARS ${SUITESPARSE_FOUND_REQUIRED_VARS}
  475. FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse.")
  476. endif (SUITESPARSE_FOUND)