FindSuiteSparse.cmake 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. # Ceres Solver - A fast non-linear least squares minimizer
  2. # Copyright 2022 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. #[=======================================================================[.rst:
  32. FindSuiteSparse
  33. ===============
  34. Module for locating SuiteSparse libraries and its dependencies.
  35. This module defines the following variables:
  36. ``SuiteSparse_FOUND``
  37. ``TRUE`` iff SuiteSparse and all dependencies have been found.
  38. ``SuiteSparse_VERSION``
  39. Extracted from ``SuiteSparse_config.h`` (>= v4).
  40. ``SuiteSparse_VERSION_MAJOR``
  41. Equal to 4 if ``SuiteSparse_VERSION`` = 4.2.1
  42. ``SuiteSparse_VERSION_MINOR``
  43. Equal to 2 if ``SuiteSparse_VERSION`` = 4.2.1
  44. ``SuiteSparse_VERSION_PATCH``
  45. Equal to 1 if ``SuiteSparse_VERSION`` = 4.2.1
  46. The following variables control the behaviour of this module:
  47. ``SuiteSparse_NO_CMAKE``
  48. Do not attempt to use the native SuiteSparse CMake package configuration.
  49. Targets
  50. -------
  51. The following targets define the SuiteSparse components searched for.
  52. ``SuiteSparse::AMD``
  53. Symmetric Approximate Minimum Degree (AMD)
  54. ``SuiteSparse::CAMD``
  55. Constrained Approximate Minimum Degree (CAMD)
  56. ``SuiteSparse::COLAMD``
  57. Column Approximate Minimum Degree (COLAMD)
  58. ``SuiteSparse::CCOLAMD``
  59. Constrained Column Approximate Minimum Degree (CCOLAMD)
  60. ``SuiteSparse::CHOLMOD``
  61. Sparse Supernodal Cholesky Factorization and Update/Downdate (CHOLMOD)
  62. ``SuiteSparse::Partition``
  63. CHOLMOD with METIS support
  64. ``SuiteSparse::SPQR``
  65. Multifrontal Sparse QR (SuiteSparseQR)
  66. ``SuiteSparse::Config``
  67. Common configuration for all but CSparse (SuiteSparse version >= 4).
  68. Optional SuiteSparse dependencies:
  69. ``METIS::METIS``
  70. Serial Graph Partitioning and Fill-reducing Matrix Ordering (METIS)
  71. ]=======================================================================]
  72. if (NOT SuiteSparse_NO_CMAKE)
  73. find_package (SuiteSparse NO_MODULE QUIET)
  74. endif (NOT SuiteSparse_NO_CMAKE)
  75. if (SuiteSparse_FOUND)
  76. return ()
  77. endif (SuiteSparse_FOUND)
  78. # Push CMP0057 to enable support for IN_LIST, when cmake_minimum_required is
  79. # set to <3.3.
  80. cmake_policy (PUSH)
  81. cmake_policy (SET CMP0057 NEW)
  82. if (NOT SuiteSparse_FIND_COMPONENTS)
  83. set (SuiteSparse_FIND_COMPONENTS
  84. AMD
  85. CAMD
  86. CCOLAMD
  87. CHOLMOD
  88. COLAMD
  89. SPQR
  90. )
  91. foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
  92. set (SuiteSparse_FIND_REQUIRED_${component} TRUE)
  93. endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
  94. endif (NOT SuiteSparse_FIND_COMPONENTS)
  95. # Assume SuiteSparse was found and set it to false only if third-party
  96. # dependencies could not be located. SuiteSparse components are handled by
  97. # FindPackageHandleStandardArgs HANDLE_COMPONENTS option.
  98. set (SuiteSparse_FOUND TRUE)
  99. include (CheckLibraryExists)
  100. include (CheckSymbolExists)
  101. include (CMakePushCheckState)
  102. # Config is a base component and thus always required
  103. set (SuiteSparse_IMPLICIT_COMPONENTS Config)
  104. # CHOLMOD depends on AMD, CAMD, CCOLAMD, and COLAMD.
  105. if (CHOLMOD IN_LIST SuiteSparse_FIND_COMPONENTS)
  106. list (APPEND SuiteSparse_IMPLICIT_COMPONENTS AMD CAMD CCOLAMD COLAMD)
  107. endif (CHOLMOD IN_LIST SuiteSparse_FIND_COMPONENTS)
  108. # SPQR depends on CHOLMOD.
  109. if (SPQR IN_LIST SuiteSparse_FIND_COMPONENTS)
  110. list (APPEND SuiteSparse_IMPLICIT_COMPONENTS CHOLMOD)
  111. endif (SPQR IN_LIST SuiteSparse_FIND_COMPONENTS)
  112. # Implicit components are always required
  113. foreach (component IN LISTS SuiteSparse_IMPLICIT_COMPONENTS)
  114. set (SuiteSparse_FIND_REQUIRED_${component} TRUE)
  115. endforeach (component IN LISTS SuiteSparse_IMPLICIT_COMPONENTS)
  116. list (APPEND SuiteSparse_FIND_COMPONENTS ${SuiteSparse_IMPLICIT_COMPONENTS})
  117. # Do not list components multiple times.
  118. list (REMOVE_DUPLICATES SuiteSparse_FIND_COMPONENTS)
  119. # Reset CALLERS_CMAKE_FIND_LIBRARY_PREFIXES to its value when
  120. # FindSuiteSparse was invoked.
  121. macro(SuiteSparse_RESET_FIND_LIBRARY_PREFIX)
  122. if (MSVC)
  123. set(CMAKE_FIND_LIBRARY_PREFIXES "${CALLERS_CMAKE_FIND_LIBRARY_PREFIXES}")
  124. endif (MSVC)
  125. endmacro(SuiteSparse_RESET_FIND_LIBRARY_PREFIX)
  126. # Called if we failed to find SuiteSparse or any of it's required dependencies,
  127. # unsets all public (designed to be used externally) variables and reports
  128. # error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
  129. macro(SuiteSparse_REPORT_NOT_FOUND REASON_MSG)
  130. # Will be set to FALSE by find_package_handle_standard_args
  131. unset (SuiteSparse_FOUND)
  132. # Do NOT unset SuiteSparse_REQUIRED_VARS here, as it is used by
  133. # FindPackageHandleStandardArgs() to generate the automatic error message on
  134. # failure which highlights which components are missing.
  135. suitesparse_reset_find_library_prefix()
  136. # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
  137. # use the camelcase library name, not uppercase.
  138. if (SuiteSparse_FIND_QUIETLY)
  139. message(STATUS "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  140. elseif (SuiteSparse_FIND_REQUIRED)
  141. message(FATAL_ERROR "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  142. else()
  143. # Neither QUIETLY nor REQUIRED, use no priority which emits a message
  144. # but continues configuration and allows generation.
  145. message("-- Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
  146. endif (SuiteSparse_FIND_QUIETLY)
  147. # Do not call return(), s/t we keep processing if not called with REQUIRED
  148. # and report all missing components, rather than bailing after failing to find
  149. # the first.
  150. endmacro(SuiteSparse_REPORT_NOT_FOUND)
  151. # Handle possible presence of lib prefix for libraries on MSVC, see
  152. # also SuiteSparse_RESET_FIND_LIBRARY_PREFIX().
  153. if (MSVC)
  154. # Preserve the caller's original values for CMAKE_FIND_LIBRARY_PREFIXES
  155. # s/t we can set it back before returning.
  156. set(CALLERS_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
  157. # The empty string in this list is important, it represents the case when
  158. # the libraries have no prefix (shared libraries / DLLs).
  159. set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "" "${CMAKE_FIND_LIBRARY_PREFIXES}")
  160. endif (MSVC)
  161. # Additional suffixes to try appending to each search path.
  162. list(APPEND SuiteSparse_CHECK_PATH_SUFFIXES
  163. suitesparse) # Windows/Ubuntu
  164. # Wrappers to find_path/library that pass the SuiteSparse search hints/paths.
  165. #
  166. # suitesparse_find_component(<component> [FILES name1 [name2 ...]]
  167. # [LIBRARIES name1 [name2 ...]])
  168. macro(suitesparse_find_component COMPONENT)
  169. include(CMakeParseArguments)
  170. set(MULTI_VALUE_ARGS FILES LIBRARIES)
  171. cmake_parse_arguments(SuiteSparse_FIND_COMPONENT_${COMPONENT}
  172. "" "" "${MULTI_VALUE_ARGS}" ${ARGN})
  173. set(SuiteSparse_${COMPONENT}_FOUND TRUE)
  174. if (SuiteSparse_FIND_COMPONENT_${COMPONENT}_FILES)
  175. find_path(SuiteSparse_${COMPONENT}_INCLUDE_DIR
  176. NAMES ${SuiteSparse_FIND_COMPONENT_${COMPONENT}_FILES}
  177. PATH_SUFFIXES ${SuiteSparse_CHECK_PATH_SUFFIXES})
  178. if (SuiteSparse_${COMPONENT}_INCLUDE_DIR)
  179. message(STATUS "Found ${COMPONENT} headers in: "
  180. "${SuiteSparse_${COMPONENT}_INCLUDE_DIR}")
  181. mark_as_advanced(SuiteSparse_${COMPONENT}_INCLUDE_DIR)
  182. else()
  183. # Specified headers not found.
  184. set(SuiteSparse_${COMPONENT}_FOUND FALSE)
  185. if (SuiteSparse_FIND_REQUIRED_${COMPONENT})
  186. suitesparse_report_not_found(
  187. "Did not find ${COMPONENT} header (required SuiteSparse component).")
  188. else()
  189. message(STATUS "Did not find ${COMPONENT} header (optional "
  190. "SuiteSparse component).")
  191. # Hide optional vars from CMake GUI even if not found.
  192. mark_as_advanced(SuiteSparse_${COMPONENT}_INCLUDE_DIR)
  193. endif()
  194. endif()
  195. endif()
  196. if (SuiteSparse_FIND_COMPONENT_${COMPONENT}_LIBRARIES)
  197. find_library(SuiteSparse_${COMPONENT}_LIBRARY
  198. NAMES ${SuiteSparse_FIND_COMPONENT_${COMPONENT}_LIBRARIES}
  199. PATH_SUFFIXES ${SuiteSparse_CHECK_PATH_SUFFIXES})
  200. if (SuiteSparse_${COMPONENT}_LIBRARY)
  201. message(STATUS "Found ${COMPONENT} library: ${SuiteSparse_${COMPONENT}_LIBRARY}")
  202. mark_as_advanced(SuiteSparse_${COMPONENT}_LIBRARY)
  203. else ()
  204. # Specified libraries not found.
  205. set(SuiteSparse_${COMPONENT}_FOUND FALSE)
  206. if (SuiteSparse_FIND_REQUIRED_${COMPONENT})
  207. suitesparse_report_not_found(
  208. "Did not find ${COMPONENT} library (required SuiteSparse component).")
  209. else()
  210. message(STATUS "Did not find ${COMPONENT} library (optional SuiteSparse "
  211. "dependency)")
  212. # Hide optional vars from CMake GUI even if not found.
  213. mark_as_advanced(SuiteSparse_${COMPONENT}_LIBRARY)
  214. endif()
  215. endif()
  216. endif()
  217. # A component can be optional (given to OPTIONAL_COMPONENTS). However, if the
  218. # component is implicit (must be always present, such as the Config component)
  219. # assume it be required as well.
  220. if (SuiteSparse_FIND_REQUIRED_${COMPONENT})
  221. list (APPEND SuiteSparse_REQUIRED_VARS SuiteSparse_${COMPONENT}_INCLUDE_DIR)
  222. list (APPEND SuiteSparse_REQUIRED_VARS SuiteSparse_${COMPONENT}_LIBRARY)
  223. endif (SuiteSparse_FIND_REQUIRED_${COMPONENT})
  224. # Define the target only if the include directory and the library were found
  225. if (SuiteSparse_${COMPONENT}_INCLUDE_DIR AND SuiteSparse_${COMPONENT}_LIBRARY)
  226. if (NOT TARGET SuiteSparse::${COMPONENT})
  227. add_library(SuiteSparse::${COMPONENT} IMPORTED UNKNOWN)
  228. endif (NOT TARGET SuiteSparse::${COMPONENT})
  229. set_property(TARGET SuiteSparse::${COMPONENT} PROPERTY
  230. INTERFACE_INCLUDE_DIRECTORIES ${SuiteSparse_${COMPONENT}_INCLUDE_DIR})
  231. set_property(TARGET SuiteSparse::${COMPONENT} PROPERTY
  232. IMPORTED_LOCATION ${SuiteSparse_${COMPONENT}_LIBRARY})
  233. endif (SuiteSparse_${COMPONENT}_INCLUDE_DIR AND SuiteSparse_${COMPONENT}_LIBRARY)
  234. endmacro()
  235. # Given the number of components of SuiteSparse, and to ensure that the
  236. # automatic failure message generated by FindPackageHandleStandardArgs()
  237. # when not all required components are found is helpful, we maintain a list
  238. # of all variables that must be defined for SuiteSparse to be considered found.
  239. unset(SuiteSparse_REQUIRED_VARS)
  240. # BLAS.
  241. find_package(BLAS QUIET)
  242. if (NOT BLAS_FOUND)
  243. suitesparse_report_not_found(
  244. "Did not find BLAS library (required for SuiteSparse).")
  245. endif (NOT BLAS_FOUND)
  246. # LAPACK.
  247. find_package(LAPACK QUIET)
  248. if (NOT LAPACK_FOUND)
  249. suitesparse_report_not_found(
  250. "Did not find LAPACK library (required for SuiteSparse).")
  251. endif (NOT LAPACK_FOUND)
  252. foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
  253. if (component STREQUAL Partition)
  254. # Partition is a meta component that neither provides additional headers nor
  255. # a separate library. It is strictly part of CHOLMOD.
  256. continue ()
  257. endif (component STREQUAL Partition)
  258. string (TOLOWER ${component} component_library)
  259. if (component STREQUAL "Config")
  260. set (component_header SuiteSparse_config.h)
  261. set (component_library suitesparseconfig)
  262. elseif (component STREQUAL "SPQR")
  263. set (component_header SuiteSparseQR.hpp)
  264. else (component STREQUAL "SPQR")
  265. set (component_header ${component_library}.h)
  266. endif (component STREQUAL "Config")
  267. suitesparse_find_component(${component}
  268. FILES ${component_header}
  269. LIBRARIES ${component_library})
  270. endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
  271. if (TARGET SuiteSparse::SPQR)
  272. # SuiteSparseQR may be compiled with Intel Threading Building Blocks,
  273. # we assume that if TBB is installed, SuiteSparseQR was compiled with
  274. # support for it, this will do no harm if it wasn't.
  275. find_package(TBB QUIET)
  276. if (TBB_FOUND)
  277. message(STATUS "Found Intel Thread Building Blocks (TBB) library "
  278. "(${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} / ${TBB_INTERFACE_VERSION}) "
  279. "include location: ${TBB_INCLUDE_DIRS}. Assuming SuiteSparseQR was "
  280. "compiled with TBB.")
  281. # Add the TBB libraries to the SuiteSparseQR libraries (the only
  282. # libraries to optionally depend on TBB).
  283. if (TARGET TBB::tbb)
  284. # Native TBB package configuration provides an imported target. Use it if
  285. # available.
  286. set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY
  287. INTERFACE_LINK_LIBRARIES TBB::tbb)
  288. else (TARGET TBB::tbb)
  289. set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY
  290. INTERFACE_INCLUDE_DIRECTORIES ${TBB_INCLUDE_DIRS})
  291. set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY
  292. INTERFACE_LINK_LIBRARIES ${TBB_LIBRARIES})
  293. endif (TARGET TBB::tbb)
  294. else (TBB_FOUND)
  295. message(STATUS "Did not find Intel TBB library, assuming SuiteSparseQR was "
  296. "not compiled with TBB.")
  297. endif (TBB_FOUND)
  298. endif (TARGET SuiteSparse::SPQR)
  299. check_library_exists(rt shm_open "" HAVE_LIBRT)
  300. if (TARGET SuiteSparse::Config)
  301. # SuiteSparse_config (SuiteSparse version >= 4) requires librt library for
  302. # timing by default when compiled on Linux or Unix, but not on OSX (which
  303. # does not have librt).
  304. if (HAVE_LIBRT)
  305. message(STATUS "Adding librt to "
  306. "SuiteSparse_config libraries (required on Linux & Unix [not OSX] if "
  307. "SuiteSparse is compiled with timing).")
  308. set_property (TARGET SuiteSparse::Config APPEND PROPERTY
  309. INTERFACE_LINK_LIBRARIES $<LINK_ONLY:rt>)
  310. else (HAVE_LIBRT)
  311. message(STATUS "Could not find librt, but found SuiteSparse_config, "
  312. "assuming that SuiteSparse was compiled without timing.")
  313. endif (HAVE_LIBRT)
  314. # Add BLAS and LAPACK as dependencies of SuiteSparse::Config for convenience
  315. # given that all components depend on it.
  316. if (BLAS_FOUND)
  317. if (TARGET BLAS::BLAS)
  318. set_property (TARGET SuiteSparse::Config APPEND PROPERTY
  319. INTERFACE_LINK_LIBRARIES $<LINK_ONLY:BLAS::BLAS>)
  320. else (TARGET BLAS::BLAS)
  321. set_property (TARGET SuiteSparse::Config APPEND PROPERTY
  322. INTERFACE_LINK_LIBRARIES ${BLAS_LIBRARIES})
  323. endif (TARGET BLAS::BLAS)
  324. endif (BLAS_FOUND)
  325. if (LAPACK_FOUND)
  326. if (TARGET LAPACK::LAPACK)
  327. set_property (TARGET SuiteSparse::Config APPEND PROPERTY
  328. INTERFACE_LINK_LIBRARIES $<LINK_ONLY:LAPACK::LAPACK>)
  329. else (TARGET LAPACK::LAPACK)
  330. set_property (TARGET SuiteSparse::Config APPEND PROPERTY
  331. INTERFACE_LINK_LIBRARIES ${LAPACK_LIBRARIES})
  332. endif (TARGET LAPACK::LAPACK)
  333. endif (LAPACK_FOUND)
  334. # SuiteSparse version >= 4.
  335. set(SuiteSparse_VERSION_FILE
  336. ${SuiteSparse_Config_INCLUDE_DIR}/SuiteSparse_config.h)
  337. if (NOT EXISTS ${SuiteSparse_VERSION_FILE})
  338. suitesparse_report_not_found(
  339. "Could not find file: ${SuiteSparse_VERSION_FILE} containing version "
  340. "information for >= v4 SuiteSparse installs, but SuiteSparse_config was "
  341. "found (only present in >= v4 installs).")
  342. else (NOT EXISTS ${SuiteSparse_VERSION_FILE})
  343. file(READ ${SuiteSparse_VERSION_FILE} Config_CONTENTS)
  344. string(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION[ \t]+([0-9]+)"
  345. SuiteSparse_VERSION_LINE "${Config_CONTENTS}")
  346. set (SuiteSparse_VERSION_MAJOR ${CMAKE_MATCH_1})
  347. string(REGEX MATCH "#define SUITESPARSE_SUB_VERSION[ \t]+([0-9]+)"
  348. SuiteSparse_VERSION_LINE "${Config_CONTENTS}")
  349. set (SuiteSparse_VERSION_MINOR ${CMAKE_MATCH_1})
  350. string(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION[ \t]+([0-9]+)"
  351. SuiteSparse_VERSION_LINE "${Config_CONTENTS}")
  352. set (SuiteSparse_VERSION_PATCH ${CMAKE_MATCH_1})
  353. unset (SuiteSparse_VERSION_LINE)
  354. # This is on a single line s/t CMake does not interpret it as a list of
  355. # elements and insert ';' separators which would result in 4.;2.;1 nonsense.
  356. set(SuiteSparse_VERSION
  357. "${SuiteSparse_VERSION_MAJOR}.${SuiteSparse_VERSION_MINOR}.${SuiteSparse_VERSION_PATCH}")
  358. if (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
  359. set(SuiteSparse_VERSION_COMPONENTS 3)
  360. else (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
  361. message (WARNING "Could not parse SuiteSparse_config.h: SuiteSparse "
  362. "version will not be available")
  363. unset (SuiteSparse_VERSION)
  364. unset (SuiteSparse_VERSION_MAJOR)
  365. unset (SuiteSparse_VERSION_MINOR)
  366. unset (SuiteSparse_VERSION_PATCH)
  367. endif (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
  368. endif (NOT EXISTS ${SuiteSparse_VERSION_FILE})
  369. endif (TARGET SuiteSparse::Config)
  370. # CHOLMOD requires AMD CAMD CCOLAMD COLAMD
  371. if (TARGET SuiteSparse::CHOLMOD)
  372. foreach (component IN ITEMS AMD CAMD CCOLAMD COLAMD)
  373. if (TARGET SuiteSparse::${component})
  374. set_property (TARGET SuiteSparse::CHOLMOD APPEND PROPERTY
  375. INTERFACE_LINK_LIBRARIES SuiteSparse::${component})
  376. else (TARGET SuiteSparse::${component})
  377. # Consider CHOLMOD not found if COLAMD cannot be found
  378. set (SuiteSparse_CHOLMOD_FOUND FALSE)
  379. endif (TARGET SuiteSparse::${component})
  380. endforeach (component IN ITEMS AMD CAMD CCOLAMD COLAMD)
  381. endif (TARGET SuiteSparse::CHOLMOD)
  382. # SPQR requires CHOLMOD
  383. if (TARGET SuiteSparse::SPQR)
  384. if (TARGET SuiteSparse::CHOLMOD)
  385. set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY
  386. INTERFACE_LINK_LIBRARIES SuiteSparse::CHOLMOD)
  387. else (TARGET SuiteSparse::CHOLMOD)
  388. # Consider SPQR not found if CHOLMOD cannot be found
  389. set (SuiteSparse_SQPR_FOUND FALSE)
  390. endif (TARGET SuiteSparse::CHOLMOD)
  391. endif (TARGET SuiteSparse::SPQR)
  392. # Add SuiteSparse::Config as dependency to all components
  393. if (TARGET SuiteSparse::Config)
  394. foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
  395. if (component STREQUAL Config)
  396. continue ()
  397. endif (component STREQUAL Config)
  398. if (TARGET SuiteSparse::${component})
  399. set_property (TARGET SuiteSparse::${component} APPEND PROPERTY
  400. INTERFACE_LINK_LIBRARIES SuiteSparse::Config)
  401. endif (TARGET SuiteSparse::${component})
  402. endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
  403. endif (TARGET SuiteSparse::Config)
  404. # Check whether CHOLMOD was compiled with METIS support. The check can be
  405. # performed only after the main components have been set up.
  406. if (TARGET SuiteSparse::CHOLMOD)
  407. # NOTE If SuiteSparse was compiled as a static library we'll need to link
  408. # against METIS already during the check. Otherwise, the check can fail due to
  409. # undefined references even though SuiteSparse was compiled with METIS.
  410. find_package (METIS)
  411. if (TARGET METIS::METIS)
  412. cmake_push_check_state (RESET)
  413. set (CMAKE_REQUIRED_LIBRARIES SuiteSparse::CHOLMOD METIS::METIS)
  414. check_symbol_exists (cholmod_metis cholmod.h SuiteSparse_CHOLMOD_USES_METIS)
  415. cmake_pop_check_state ()
  416. if (SuiteSparse_CHOLMOD_USES_METIS)
  417. set_property (TARGET SuiteSparse::CHOLMOD APPEND PROPERTY
  418. INTERFACE_LINK_LIBRARIES $<LINK_ONLY:METIS::METIS>)
  419. # Provide the SuiteSparse::Partition component whose availability indicates
  420. # that CHOLMOD was compiled with the Partition module.
  421. if (NOT TARGET SuiteSparse::Partition)
  422. add_library (SuiteSparse::Partition IMPORTED INTERFACE)
  423. endif (NOT TARGET SuiteSparse::Partition)
  424. set_property (TARGET SuiteSparse::Partition APPEND PROPERTY
  425. INTERFACE_LINK_LIBRARIES SuiteSparse::CHOLMOD)
  426. endif (SuiteSparse_CHOLMOD_USES_METIS)
  427. endif (TARGET METIS::METIS)
  428. endif (TARGET SuiteSparse::CHOLMOD)
  429. # We do not use suitesparse_find_component to find Partition and therefore must
  430. # handle the availability in an extra step.
  431. if (TARGET SuiteSparse::Partition)
  432. set (SuiteSparse_Partition_FOUND TRUE)
  433. else (TARGET SuiteSparse::Partition)
  434. set (SuiteSparse_Partition_FOUND FALSE)
  435. endif (TARGET SuiteSparse::Partition)
  436. suitesparse_reset_find_library_prefix()
  437. # Handle REQUIRED and QUIET arguments to FIND_PACKAGE
  438. include(FindPackageHandleStandardArgs)
  439. if (SuiteSparse_FOUND)
  440. find_package_handle_standard_args(SuiteSparse
  441. REQUIRED_VARS ${SuiteSparse_REQUIRED_VARS}
  442. VERSION_VAR SuiteSparse_VERSION
  443. FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse."
  444. HANDLE_COMPONENTS)
  445. else (SuiteSparse_FOUND)
  446. # Do not pass VERSION_VAR to FindPackageHandleStandardArgs() if we failed to
  447. # find SuiteSparse to avoid a confusing autogenerated failure message
  448. # that states 'not found (missing: FOO) (found version: x.y.z)'.
  449. find_package_handle_standard_args(SuiteSparse
  450. REQUIRED_VARS ${SuiteSparse_REQUIRED_VARS}
  451. FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse."
  452. HANDLE_COMPONENTS)
  453. endif (SuiteSparse_FOUND)
  454. # Pop CMP0057.
  455. cmake_policy (POP)