blob: 49c089c0a371564163455beec6e087800cf2b664 [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001# Ceres Solver - A fast non-linear least squares minimizer
Austin Schuh3de38b02024-06-25 18:25:10 -07002# Copyright 2023 Google Inc. All rights reserved.
Austin Schuh70cc9552019-01-21 19:46:48 -08003# 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
Austin Schuh3de38b02024-06-25 18:25:10 -070032#[=======================================================================[.rst:
33FindSuiteSparse
34===============
35
36Module for locating SuiteSparse libraries and its dependencies.
37
38This module defines the following variables:
39
40``SuiteSparse_FOUND``
41 ``TRUE`` iff SuiteSparse and all dependencies have been found.
42
43``SuiteSparse_VERSION``
44 Extracted from ``SuiteSparse_config.h`` (>= v4).
45
46``SuiteSparse_VERSION_MAJOR``
47 Equal to 4 if ``SuiteSparse_VERSION`` = 4.2.1
48
49``SuiteSparse_VERSION_MINOR``
50 Equal to 2 if ``SuiteSparse_VERSION`` = 4.2.1
51
52``SuiteSparse_VERSION_PATCH``
53 Equal to 1 if ``SuiteSparse_VERSION`` = 4.2.1
54
55The following variables control the behaviour of this module:
56
57``SuiteSparse_NO_CMAKE``
58 Do not attempt to use the native SuiteSparse CMake package configuration.
59
60
61Targets
62-------
63
64The following targets define the SuiteSparse components searched for.
65
66``SuiteSparse::AMD``
67 Symmetric Approximate Minimum Degree (AMD)
68
69``SuiteSparse::CAMD``
70 Constrained Approximate Minimum Degree (CAMD)
71
72``SuiteSparse::COLAMD``
73 Column Approximate Minimum Degree (COLAMD)
74
75``SuiteSparse::CCOLAMD``
76 Constrained Column Approximate Minimum Degree (CCOLAMD)
77
78``SuiteSparse::CHOLMOD``
79 Sparse Supernodal Cholesky Factorization and Update/Downdate (CHOLMOD)
80
81``SuiteSparse::Partition``
82 CHOLMOD with METIS support
83
84``SuiteSparse::SPQR``
85 Multifrontal Sparse QR (SuiteSparseQR)
86
87``SuiteSparse::Config``
88 Common configuration for all but CSparse (SuiteSparse version >= 4).
89
90Optional SuiteSparse dependencies:
91
92``METIS::METIS``
93 Serial Graph Partitioning and Fill-reducing Matrix Ordering (METIS)
94]=======================================================================]
95
96if (NOT SuiteSparse_NO_CMAKE)
97 find_package (SuiteSparse NO_MODULE QUIET)
98endif (NOT SuiteSparse_NO_CMAKE)
99
100if (SuiteSparse_FOUND)
101 return ()
102endif (SuiteSparse_FOUND)
103
104# Push CMP0057 to enable support for IN_LIST, when cmake_minimum_required is
105# set to <3.3.
106cmake_policy (PUSH)
107cmake_policy (SET CMP0057 NEW)
108
109if (NOT SuiteSparse_FIND_COMPONENTS)
110 set (SuiteSparse_FIND_COMPONENTS
111 AMD
112 CAMD
113 CCOLAMD
114 CHOLMOD
115 COLAMD
116 SPQR
117 )
118
119 foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
120 set (SuiteSparse_FIND_REQUIRED_${component} TRUE)
121 endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
122endif (NOT SuiteSparse_FIND_COMPONENTS)
123
124# Assume SuiteSparse was found and set it to false only if third-party
125# dependencies could not be located. SuiteSparse components are handled by
126# FindPackageHandleStandardArgs HANDLE_COMPONENTS option.
127set (SuiteSparse_FOUND TRUE)
128
129include (CheckLibraryExists)
130include (CheckSymbolExists)
131include (CMakePushCheckState)
132
133# Config is a base component and thus always required
134set (SuiteSparse_IMPLICIT_COMPONENTS Config)
135
136# CHOLMOD depends on AMD, CAMD, CCOLAMD, and COLAMD.
137if (CHOLMOD IN_LIST SuiteSparse_FIND_COMPONENTS)
138 list (APPEND SuiteSparse_IMPLICIT_COMPONENTS AMD CAMD CCOLAMD COLAMD)
139endif (CHOLMOD IN_LIST SuiteSparse_FIND_COMPONENTS)
140
141# SPQR depends on CHOLMOD.
142if (SPQR IN_LIST SuiteSparse_FIND_COMPONENTS)
143 list (APPEND SuiteSparse_IMPLICIT_COMPONENTS CHOLMOD)
144endif (SPQR IN_LIST SuiteSparse_FIND_COMPONENTS)
145
146# Implicit components are always required
147foreach (component IN LISTS SuiteSparse_IMPLICIT_COMPONENTS)
148 set (SuiteSparse_FIND_REQUIRED_${component} TRUE)
149endforeach (component IN LISTS SuiteSparse_IMPLICIT_COMPONENTS)
150
151list (APPEND SuiteSparse_FIND_COMPONENTS ${SuiteSparse_IMPLICIT_COMPONENTS})
152
153# Do not list components multiple times.
154list (REMOVE_DUPLICATES SuiteSparse_FIND_COMPONENTS)
Austin Schuh70cc9552019-01-21 19:46:48 -0800155
156# Reset CALLERS_CMAKE_FIND_LIBRARY_PREFIXES to its value when
157# FindSuiteSparse was invoked.
Austin Schuh3de38b02024-06-25 18:25:10 -0700158macro(SuiteSparse_RESET_FIND_LIBRARY_PREFIX)
Austin Schuh70cc9552019-01-21 19:46:48 -0800159 if (MSVC)
160 set(CMAKE_FIND_LIBRARY_PREFIXES "${CALLERS_CMAKE_FIND_LIBRARY_PREFIXES}")
161 endif (MSVC)
Austin Schuh3de38b02024-06-25 18:25:10 -0700162endmacro(SuiteSparse_RESET_FIND_LIBRARY_PREFIX)
Austin Schuh70cc9552019-01-21 19:46:48 -0800163
164# Called if we failed to find SuiteSparse or any of it's required dependencies,
165# unsets all public (designed to be used externally) variables and reports
166# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
Austin Schuh3de38b02024-06-25 18:25:10 -0700167macro(SuiteSparse_REPORT_NOT_FOUND REASON_MSG)
168 # Will be set to FALSE by find_package_handle_standard_args
169 unset (SuiteSparse_FOUND)
170
171 # Do NOT unset SuiteSparse_REQUIRED_VARS here, as it is used by
Austin Schuh70cc9552019-01-21 19:46:48 -0800172 # FindPackageHandleStandardArgs() to generate the automatic error message on
173 # failure which highlights which components are missing.
174
175 suitesparse_reset_find_library_prefix()
176
177 # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
178 # use the camelcase library name, not uppercase.
179 if (SuiteSparse_FIND_QUIETLY)
180 message(STATUS "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
181 elseif (SuiteSparse_FIND_REQUIRED)
182 message(FATAL_ERROR "Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
183 else()
184 # Neither QUIETLY nor REQUIRED, use no priority which emits a message
185 # but continues configuration and allows generation.
186 message("-- Failed to find SuiteSparse - " ${REASON_MSG} ${ARGN})
187 endif (SuiteSparse_FIND_QUIETLY)
188
189 # Do not call return(), s/t we keep processing if not called with REQUIRED
190 # and report all missing components, rather than bailing after failing to find
191 # the first.
Austin Schuh3de38b02024-06-25 18:25:10 -0700192endmacro(SuiteSparse_REPORT_NOT_FOUND)
Austin Schuh70cc9552019-01-21 19:46:48 -0800193
194# Handle possible presence of lib prefix for libraries on MSVC, see
Austin Schuh3de38b02024-06-25 18:25:10 -0700195# also SuiteSparse_RESET_FIND_LIBRARY_PREFIX().
Austin Schuh70cc9552019-01-21 19:46:48 -0800196if (MSVC)
197 # Preserve the caller's original values for CMAKE_FIND_LIBRARY_PREFIXES
198 # s/t we can set it back before returning.
199 set(CALLERS_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
200 # The empty string in this list is important, it represents the case when
201 # the libraries have no prefix (shared libraries / DLLs).
202 set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "" "${CMAKE_FIND_LIBRARY_PREFIXES}")
203endif (MSVC)
204
Austin Schuh70cc9552019-01-21 19:46:48 -0800205# Additional suffixes to try appending to each search path.
Austin Schuh3de38b02024-06-25 18:25:10 -0700206list(APPEND SuiteSparse_CHECK_PATH_SUFFIXES
Austin Schuh70cc9552019-01-21 19:46:48 -0800207 suitesparse) # Windows/Ubuntu
208
209# Wrappers to find_path/library that pass the SuiteSparse search hints/paths.
210#
211# suitesparse_find_component(<component> [FILES name1 [name2 ...]]
Austin Schuh3de38b02024-06-25 18:25:10 -0700212# [LIBRARIES name1 [name2 ...]])
Austin Schuh70cc9552019-01-21 19:46:48 -0800213macro(suitesparse_find_component COMPONENT)
214 include(CMakeParseArguments)
Austin Schuh70cc9552019-01-21 19:46:48 -0800215 set(MULTI_VALUE_ARGS FILES LIBRARIES)
Austin Schuh3de38b02024-06-25 18:25:10 -0700216 cmake_parse_arguments(SuiteSparse_FIND_COMPONENT_${COMPONENT}
217 "" "" "${MULTI_VALUE_ARGS}" ${ARGN})
Austin Schuh70cc9552019-01-21 19:46:48 -0800218
Austin Schuh3de38b02024-06-25 18:25:10 -0700219 set(SuiteSparse_${COMPONENT}_FOUND TRUE)
220 if (SuiteSparse_FIND_COMPONENT_${COMPONENT}_FILES)
221 find_path(SuiteSparse_${COMPONENT}_INCLUDE_DIR
222 NAMES ${SuiteSparse_FIND_COMPONENT_${COMPONENT}_FILES}
223 PATH_SUFFIXES ${SuiteSparse_CHECK_PATH_SUFFIXES})
224 if (SuiteSparse_${COMPONENT}_INCLUDE_DIR)
Austin Schuh70cc9552019-01-21 19:46:48 -0800225 message(STATUS "Found ${COMPONENT} headers in: "
Austin Schuh3de38b02024-06-25 18:25:10 -0700226 "${SuiteSparse_${COMPONENT}_INCLUDE_DIR}")
227 mark_as_advanced(SuiteSparse_${COMPONENT}_INCLUDE_DIR)
Austin Schuh70cc9552019-01-21 19:46:48 -0800228 else()
229 # Specified headers not found.
Austin Schuh3de38b02024-06-25 18:25:10 -0700230 set(SuiteSparse_${COMPONENT}_FOUND FALSE)
231 if (SuiteSparse_FIND_REQUIRED_${COMPONENT})
Austin Schuh70cc9552019-01-21 19:46:48 -0800232 suitesparse_report_not_found(
233 "Did not find ${COMPONENT} header (required SuiteSparse component).")
234 else()
235 message(STATUS "Did not find ${COMPONENT} header (optional "
236 "SuiteSparse component).")
237 # Hide optional vars from CMake GUI even if not found.
Austin Schuh3de38b02024-06-25 18:25:10 -0700238 mark_as_advanced(SuiteSparse_${COMPONENT}_INCLUDE_DIR)
Austin Schuh70cc9552019-01-21 19:46:48 -0800239 endif()
240 endif()
241 endif()
242
Austin Schuh3de38b02024-06-25 18:25:10 -0700243 if (SuiteSparse_FIND_COMPONENT_${COMPONENT}_LIBRARIES)
244 find_library(SuiteSparse_${COMPONENT}_LIBRARY
245 NAMES ${SuiteSparse_FIND_COMPONENT_${COMPONENT}_LIBRARIES}
246 PATH_SUFFIXES ${SuiteSparse_CHECK_PATH_SUFFIXES})
247 if (SuiteSparse_${COMPONENT}_LIBRARY)
248 message(STATUS "Found ${COMPONENT} library: ${SuiteSparse_${COMPONENT}_LIBRARY}")
249 mark_as_advanced(SuiteSparse_${COMPONENT}_LIBRARY)
Austin Schuh70cc9552019-01-21 19:46:48 -0800250 else ()
251 # Specified libraries not found.
Austin Schuh3de38b02024-06-25 18:25:10 -0700252 set(SuiteSparse_${COMPONENT}_FOUND FALSE)
253 if (SuiteSparse_FIND_REQUIRED_${COMPONENT})
Austin Schuh70cc9552019-01-21 19:46:48 -0800254 suitesparse_report_not_found(
255 "Did not find ${COMPONENT} library (required SuiteSparse component).")
256 else()
257 message(STATUS "Did not find ${COMPONENT} library (optional SuiteSparse "
258 "dependency)")
259 # Hide optional vars from CMake GUI even if not found.
Austin Schuh3de38b02024-06-25 18:25:10 -0700260 mark_as_advanced(SuiteSparse_${COMPONENT}_LIBRARY)
Austin Schuh70cc9552019-01-21 19:46:48 -0800261 endif()
262 endif()
263 endif()
Austin Schuh3de38b02024-06-25 18:25:10 -0700264
265 # A component can be optional (given to OPTIONAL_COMPONENTS). However, if the
266 # component is implicit (must be always present, such as the Config component)
267 # assume it be required as well.
268 if (SuiteSparse_FIND_REQUIRED_${COMPONENT})
269 list (APPEND SuiteSparse_REQUIRED_VARS SuiteSparse_${COMPONENT}_INCLUDE_DIR)
270 list (APPEND SuiteSparse_REQUIRED_VARS SuiteSparse_${COMPONENT}_LIBRARY)
271 endif (SuiteSparse_FIND_REQUIRED_${COMPONENT})
272
273 # Define the target only if the include directory and the library were found
274 if (SuiteSparse_${COMPONENT}_INCLUDE_DIR AND SuiteSparse_${COMPONENT}_LIBRARY)
275 if (NOT TARGET SuiteSparse::${COMPONENT})
276 add_library(SuiteSparse::${COMPONENT} IMPORTED UNKNOWN)
277 endif (NOT TARGET SuiteSparse::${COMPONENT})
278
279 set_property(TARGET SuiteSparse::${COMPONENT} PROPERTY
280 INTERFACE_INCLUDE_DIRECTORIES ${SuiteSparse_${COMPONENT}_INCLUDE_DIR})
281 set_property(TARGET SuiteSparse::${COMPONENT} PROPERTY
282 IMPORTED_LOCATION ${SuiteSparse_${COMPONENT}_LIBRARY})
283 endif (SuiteSparse_${COMPONENT}_INCLUDE_DIR AND SuiteSparse_${COMPONENT}_LIBRARY)
Austin Schuh70cc9552019-01-21 19:46:48 -0800284endmacro()
285
286# Given the number of components of SuiteSparse, and to ensure that the
287# automatic failure message generated by FindPackageHandleStandardArgs()
288# when not all required components are found is helpful, we maintain a list
289# of all variables that must be defined for SuiteSparse to be considered found.
Austin Schuh3de38b02024-06-25 18:25:10 -0700290unset(SuiteSparse_REQUIRED_VARS)
Austin Schuh70cc9552019-01-21 19:46:48 -0800291
292# BLAS.
293find_package(BLAS QUIET)
294if (NOT BLAS_FOUND)
295 suitesparse_report_not_found(
296 "Did not find BLAS library (required for SuiteSparse).")
297endif (NOT BLAS_FOUND)
Austin Schuh70cc9552019-01-21 19:46:48 -0800298
299# LAPACK.
300find_package(LAPACK QUIET)
301if (NOT LAPACK_FOUND)
302 suitesparse_report_not_found(
303 "Did not find LAPACK library (required for SuiteSparse).")
304endif (NOT LAPACK_FOUND)
Austin Schuh70cc9552019-01-21 19:46:48 -0800305
Austin Schuh3de38b02024-06-25 18:25:10 -0700306foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
307 if (component STREQUAL Partition)
308 # Partition is a meta component that neither provides additional headers nor
309 # a separate library. It is strictly part of CHOLMOD.
310 continue ()
311 endif (component STREQUAL Partition)
312 string (TOLOWER ${component} component_library)
313
314 if (component STREQUAL "Config")
315 set (component_header SuiteSparse_config.h)
316 set (component_library suitesparseconfig)
317 elseif (component STREQUAL "SPQR")
318 set (component_header SuiteSparseQR.hpp)
319 else (component STREQUAL "SPQR")
320 set (component_header ${component_library}.h)
321 endif (component STREQUAL "Config")
322
323 suitesparse_find_component(${component}
324 FILES ${component_header}
325 LIBRARIES ${component_library})
326endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
327
328if (TARGET SuiteSparse::SPQR)
Austin Schuh70cc9552019-01-21 19:46:48 -0800329 # SuiteSparseQR may be compiled with Intel Threading Building Blocks,
330 # we assume that if TBB is installed, SuiteSparseQR was compiled with
331 # support for it, this will do no harm if it wasn't.
Austin Schuh3de38b02024-06-25 18:25:10 -0700332 find_package(TBB QUIET NO_MODULE)
Austin Schuh70cc9552019-01-21 19:46:48 -0800333 if (TBB_FOUND)
334 message(STATUS "Found Intel Thread Building Blocks (TBB) library "
Austin Schuh3de38b02024-06-25 18:25:10 -0700335 "(${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} / ${TBB_INTERFACE_VERSION}). "
336 "Assuming SuiteSparseQR was compiled with TBB.")
Austin Schuh70cc9552019-01-21 19:46:48 -0800337 # Add the TBB libraries to the SuiteSparseQR libraries (the only
338 # libraries to optionally depend on TBB).
Austin Schuh3de38b02024-06-25 18:25:10 -0700339 set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY
340 INTERFACE_LINK_LIBRARIES TBB::tbb)
341 else (TBB_FOUND)
Austin Schuh70cc9552019-01-21 19:46:48 -0800342 message(STATUS "Did not find Intel TBB library, assuming SuiteSparseQR was "
343 "not compiled with TBB.")
Austin Schuh3de38b02024-06-25 18:25:10 -0700344 endif (TBB_FOUND)
345endif (TARGET SuiteSparse::SPQR)
Austin Schuh70cc9552019-01-21 19:46:48 -0800346
Austin Schuh3de38b02024-06-25 18:25:10 -0700347check_library_exists(rt shm_open "" HAVE_LIBRT)
Austin Schuh70cc9552019-01-21 19:46:48 -0800348
Austin Schuh3de38b02024-06-25 18:25:10 -0700349if (TARGET SuiteSparse::Config)
Austin Schuh70cc9552019-01-21 19:46:48 -0800350 # SuiteSparse_config (SuiteSparse version >= 4) requires librt library for
351 # timing by default when compiled on Linux or Unix, but not on OSX (which
352 # does not have librt).
Austin Schuh3de38b02024-06-25 18:25:10 -0700353 if (HAVE_LIBRT)
354 message(STATUS "Adding librt to "
355 "SuiteSparse_config libraries (required on Linux & Unix [not OSX] if "
356 "SuiteSparse is compiled with timing).")
357 set_property (TARGET SuiteSparse::Config APPEND PROPERTY
358 INTERFACE_LINK_LIBRARIES $<LINK_ONLY:rt>)
359 else (HAVE_LIBRT)
360 message(STATUS "Could not find librt, but found SuiteSparse_config, "
361 "assuming that SuiteSparse was compiled without timing.")
362 endif (HAVE_LIBRT)
Austin Schuh70cc9552019-01-21 19:46:48 -0800363
Austin Schuh3de38b02024-06-25 18:25:10 -0700364 # Add BLAS and LAPACK as dependencies of SuiteSparse::Config for convenience
365 # given that all components depend on it.
366 if (BLAS_FOUND)
367 if (TARGET BLAS::BLAS)
368 set_property (TARGET SuiteSparse::Config APPEND PROPERTY
369 INTERFACE_LINK_LIBRARIES $<LINK_ONLY:BLAS::BLAS>)
370 else (TARGET BLAS::BLAS)
371 set_property (TARGET SuiteSparse::Config APPEND PROPERTY
372 INTERFACE_LINK_LIBRARIES ${BLAS_LIBRARIES})
373 endif (TARGET BLAS::BLAS)
374 endif (BLAS_FOUND)
Austin Schuh70cc9552019-01-21 19:46:48 -0800375
Austin Schuh3de38b02024-06-25 18:25:10 -0700376 if (LAPACK_FOUND)
377 if (TARGET LAPACK::LAPACK)
378 set_property (TARGET SuiteSparse::Config APPEND PROPERTY
379 INTERFACE_LINK_LIBRARIES $<LINK_ONLY:LAPACK::LAPACK>)
380 else (TARGET LAPACK::LAPACK)
381 set_property (TARGET SuiteSparse::Config APPEND PROPERTY
382 INTERFACE_LINK_LIBRARIES ${LAPACK_LIBRARIES})
383 endif (TARGET LAPACK::LAPACK)
384 endif (LAPACK_FOUND)
Austin Schuh70cc9552019-01-21 19:46:48 -0800385
Austin Schuh70cc9552019-01-21 19:46:48 -0800386 # SuiteSparse version >= 4.
Austin Schuh3de38b02024-06-25 18:25:10 -0700387 set(SuiteSparse_VERSION_FILE
388 ${SuiteSparse_Config_INCLUDE_DIR}/SuiteSparse_config.h)
389 if (NOT EXISTS ${SuiteSparse_VERSION_FILE})
Austin Schuh70cc9552019-01-21 19:46:48 -0800390 suitesparse_report_not_found(
Austin Schuh3de38b02024-06-25 18:25:10 -0700391 "Could not find file: ${SuiteSparse_VERSION_FILE} containing version "
Austin Schuh70cc9552019-01-21 19:46:48 -0800392 "information for >= v4 SuiteSparse installs, but SuiteSparse_config was "
393 "found (only present in >= v4 installs).")
Austin Schuh3de38b02024-06-25 18:25:10 -0700394 else (NOT EXISTS ${SuiteSparse_VERSION_FILE})
395 file(READ ${SuiteSparse_VERSION_FILE} Config_CONTENTS)
Austin Schuh70cc9552019-01-21 19:46:48 -0800396
Austin Schuh3de38b02024-06-25 18:25:10 -0700397 string(REGEX MATCH "#define SUITESPARSE_MAIN_VERSION[ \t]+([0-9]+)"
398 SuiteSparse_VERSION_LINE "${Config_CONTENTS}")
399 set (SuiteSparse_VERSION_MAJOR ${CMAKE_MATCH_1})
Austin Schuh70cc9552019-01-21 19:46:48 -0800400
Austin Schuh3de38b02024-06-25 18:25:10 -0700401 string(REGEX MATCH "#define SUITESPARSE_SUB_VERSION[ \t]+([0-9]+)"
402 SuiteSparse_VERSION_LINE "${Config_CONTENTS}")
403 set (SuiteSparse_VERSION_MINOR ${CMAKE_MATCH_1})
Austin Schuh70cc9552019-01-21 19:46:48 -0800404
Austin Schuh3de38b02024-06-25 18:25:10 -0700405 string(REGEX MATCH "#define SUITESPARSE_SUBSUB_VERSION[ \t]+([0-9]+)"
406 SuiteSparse_VERSION_LINE "${Config_CONTENTS}")
407 set (SuiteSparse_VERSION_PATCH ${CMAKE_MATCH_1})
408
409 unset (SuiteSparse_VERSION_LINE)
Austin Schuh70cc9552019-01-21 19:46:48 -0800410
411 # This is on a single line s/t CMake does not interpret it as a list of
412 # elements and insert ';' separators which would result in 4.;2.;1 nonsense.
Austin Schuh3de38b02024-06-25 18:25:10 -0700413 set(SuiteSparse_VERSION
414 "${SuiteSparse_VERSION_MAJOR}.${SuiteSparse_VERSION_MINOR}.${SuiteSparse_VERSION_PATCH}")
Austin Schuh70cc9552019-01-21 19:46:48 -0800415
Austin Schuh3de38b02024-06-25 18:25:10 -0700416 if (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
417 set(SuiteSparse_VERSION_COMPONENTS 3)
418 else (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
419 message (WARNING "Could not parse SuiteSparse_config.h: SuiteSparse "
420 "version will not be available")
Austin Schuh70cc9552019-01-21 19:46:48 -0800421
Austin Schuh3de38b02024-06-25 18:25:10 -0700422 unset (SuiteSparse_VERSION)
423 unset (SuiteSparse_VERSION_MAJOR)
424 unset (SuiteSparse_VERSION_MINOR)
425 unset (SuiteSparse_VERSION_PATCH)
426 endif (SuiteSparse_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
427 endif (NOT EXISTS ${SuiteSparse_VERSION_FILE})
428endif (TARGET SuiteSparse::Config)
Austin Schuh70cc9552019-01-21 19:46:48 -0800429
Austin Schuh3de38b02024-06-25 18:25:10 -0700430# CHOLMOD requires AMD CAMD CCOLAMD COLAMD
431if (TARGET SuiteSparse::CHOLMOD)
432 foreach (component IN ITEMS AMD CAMD CCOLAMD COLAMD)
433 if (TARGET SuiteSparse::${component})
434 set_property (TARGET SuiteSparse::CHOLMOD APPEND PROPERTY
435 INTERFACE_LINK_LIBRARIES SuiteSparse::${component})
436 else (TARGET SuiteSparse::${component})
437 # Consider CHOLMOD not found if COLAMD cannot be found
438 set (SuiteSparse_CHOLMOD_FOUND FALSE)
439 endif (TARGET SuiteSparse::${component})
440 endforeach (component IN ITEMS AMD CAMD CCOLAMD COLAMD)
441endif (TARGET SuiteSparse::CHOLMOD)
Austin Schuh70cc9552019-01-21 19:46:48 -0800442
Austin Schuh3de38b02024-06-25 18:25:10 -0700443# SPQR requires CHOLMOD
444if (TARGET SuiteSparse::SPQR)
445 if (TARGET SuiteSparse::CHOLMOD)
446 set_property (TARGET SuiteSparse::SPQR APPEND PROPERTY
447 INTERFACE_LINK_LIBRARIES SuiteSparse::CHOLMOD)
448 else (TARGET SuiteSparse::CHOLMOD)
449 # Consider SPQR not found if CHOLMOD cannot be found
450 set (SuiteSparse_SQPR_FOUND FALSE)
451 endif (TARGET SuiteSparse::CHOLMOD)
452endif (TARGET SuiteSparse::SPQR)
Austin Schuh70cc9552019-01-21 19:46:48 -0800453
Austin Schuh3de38b02024-06-25 18:25:10 -0700454# Add SuiteSparse::Config as dependency to all components
455if (TARGET SuiteSparse::Config)
456 foreach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
457 if (component STREQUAL Config)
458 continue ()
459 endif (component STREQUAL Config)
Austin Schuh70cc9552019-01-21 19:46:48 -0800460
Austin Schuh3de38b02024-06-25 18:25:10 -0700461 if (TARGET SuiteSparse::${component})
462 set_property (TARGET SuiteSparse::${component} APPEND PROPERTY
463 INTERFACE_LINK_LIBRARIES SuiteSparse::Config)
464 endif (TARGET SuiteSparse::${component})
465 endforeach (component IN LISTS SuiteSparse_FIND_COMPONENTS)
466endif (TARGET SuiteSparse::Config)
467
468# Check whether CHOLMOD was compiled with METIS support. The check can be
469# performed only after the main components have been set up.
470if (TARGET SuiteSparse::CHOLMOD)
471 # NOTE If SuiteSparse was compiled as a static library we'll need to link
472 # against METIS already during the check. Otherwise, the check can fail due to
473 # undefined references even though SuiteSparse was compiled with METIS.
474 find_package (METIS)
475
476 if (TARGET METIS::METIS)
477 cmake_push_check_state (RESET)
478 set (CMAKE_REQUIRED_LIBRARIES SuiteSparse::CHOLMOD METIS::METIS)
479 check_symbol_exists (cholmod_metis cholmod.h SuiteSparse_CHOLMOD_USES_METIS)
480 cmake_pop_check_state ()
481
482 if (SuiteSparse_CHOLMOD_USES_METIS)
483 set_property (TARGET SuiteSparse::CHOLMOD APPEND PROPERTY
484 INTERFACE_LINK_LIBRARIES $<LINK_ONLY:METIS::METIS>)
485
486 # Provide the SuiteSparse::Partition component whose availability indicates
487 # that CHOLMOD was compiled with the Partition module.
488 if (NOT TARGET SuiteSparse::Partition)
489 add_library (SuiteSparse::Partition IMPORTED INTERFACE)
490 endif (NOT TARGET SuiteSparse::Partition)
491
492 set_property (TARGET SuiteSparse::Partition APPEND PROPERTY
493 INTERFACE_LINK_LIBRARIES SuiteSparse::CHOLMOD)
494 endif (SuiteSparse_CHOLMOD_USES_METIS)
495 endif (TARGET METIS::METIS)
496endif (TARGET SuiteSparse::CHOLMOD)
497
498# We do not use suitesparse_find_component to find Partition and therefore must
499# handle the availability in an extra step.
500if (TARGET SuiteSparse::Partition)
501 set (SuiteSparse_Partition_FOUND TRUE)
502else (TARGET SuiteSparse::Partition)
503 set (SuiteSparse_Partition_FOUND FALSE)
504endif (TARGET SuiteSparse::Partition)
Austin Schuh70cc9552019-01-21 19:46:48 -0800505
506suitesparse_reset_find_library_prefix()
507
508# Handle REQUIRED and QUIET arguments to FIND_PACKAGE
509include(FindPackageHandleStandardArgs)
Austin Schuh3de38b02024-06-25 18:25:10 -0700510if (SuiteSparse_FOUND)
Austin Schuh70cc9552019-01-21 19:46:48 -0800511 find_package_handle_standard_args(SuiteSparse
Austin Schuh3de38b02024-06-25 18:25:10 -0700512 REQUIRED_VARS ${SuiteSparse_REQUIRED_VARS}
513 VERSION_VAR SuiteSparse_VERSION
514 FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse."
515 HANDLE_COMPONENTS)
516else (SuiteSparse_FOUND)
Austin Schuh70cc9552019-01-21 19:46:48 -0800517 # Do not pass VERSION_VAR to FindPackageHandleStandardArgs() if we failed to
518 # find SuiteSparse to avoid a confusing autogenerated failure message
519 # that states 'not found (missing: FOO) (found version: x.y.z)'.
520 find_package_handle_standard_args(SuiteSparse
Austin Schuh3de38b02024-06-25 18:25:10 -0700521 REQUIRED_VARS ${SuiteSparse_REQUIRED_VARS}
522 FAIL_MESSAGE "Failed to find some/all required components of SuiteSparse."
523 HANDLE_COMPONENTS)
524endif (SuiteSparse_FOUND)
525
526# Pop CMP0057.
527cmake_policy (POP)