File: FindSuiteSparse.cmake

package info (click to toggle)
dune-common 2.10.0-4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 5,804 kB
  • sloc: cpp: 52,256; python: 3,979; sh: 1,658; makefile: 17
file content (301 lines) | stat: -rw-r--r-- 10,654 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
# SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception

#[=======================================================================[.rst:
FindSuiteSparse
---------------

Find the SuiteSparse libraries like UMFPACK or SPQR.

Use this module by invoking find_package with the form:

.. code-block:: cmake

    find_package(SuiteSparse
      [<version>] [EXACT]    # Minimum or EXACT version e.g. 5.1
      [REQUIRED]             # Fail with error if SuiteSparse is not found
      [COMPONENTS <libs>...] # SuiteSparse libraries by their canonical name
                             # e.g. "UMFPACK" or "SPQR"
      [OPTIONAL_COMPONENTS <libs>...]
                             # Optional SuiteSparse libraries by their canonical name
      )                      # e.g. "UMFPACK" or "SPQR"

Components
^^^^^^^^^^

The SuiteSparse module allows to search for the following components

``CHOLMOD``
  Supernodal Cholesky factorization.
``CSparse`` and ``CXSparse``
  A Concise Sparse Matrix package.
``GraphBLAS``
  Graph algorithms and primitives using semiring algebra. (SuiteSparse >= 5.6)
``KLU`` and ``BTF``
  Sparse LU factorization, well-suited for circuit simulation.
``LDL``
  A sparse LDL' factorization and solve package.
``Mongoose``
  A graph partitioning library. (SuiteSparse >= 5.5)
``SPQR``
  Multifrontal QR factorization.
``UMFPACK``
  Multifrontal LU factorization.

And ordering methods: ``AMD``, ``CAMD``, ``COLAMD``, and ``CCOLAMD``.

Imported Targets
^^^^^^^^^^^^^^^^

This module provides the following imported targets, if found:

``SuiteSparse::SuiteSparse``
  A meta library including all the requested optional or required components.
``SuiteSparse::<COMPONENT>``
  Library and include directories for the found ``<COMPONENT>``.

Result Variables
^^^^^^^^^^^^^^^^

This will define the following variables:

``SuiteSparse_FOUND``
  True if all the (required) components are found
``SuiteSparse_<COMPONENT>_FOUND``
  True if a searched ``<COMPONENT>`` is found

Input and Cache Variables
^^^^^^^^^^^^^^^^^^^^^^^^^

You may set the following variables to modify the behaviour of
this module:

``SuiteSparse_ROOT``
  The root directory of the SuiteSparse installation, containing
  subdirectories :code:`include/` and :code:`lib/` including the
  header files and libraries of SuiteSparse and its components,
  respectively.
``SUITESPARSE_INCLUDE_DIR``
  The directory containing ``SuiteSparse_config.h``.
``SUITESPARSE_CONFIG_LIB``
  The path to the suitesparseconfig library.

#]=======================================================================]

# text for feature summary
include(FeatureSummary)
set_package_properties("SuiteSparse" PROPERTIES
  DESCRIPTION "A suite of sparse matrix software"
  URL "http://faculty.cse.tamu.edu/davis/suitesparse.html"
)

# find package dependencies first
include(CMakeFindDependencyMacro)
find_package(LAPACK QUIET)
find_package(BLAS QUIET)

# list of possible component names
set(SUITESPARSE_COMPONENTS
  "AMD" "BTF" "CAMD" "CCOLAMD" "CHOLMOD" "COLAMD"
  "CSparse" "CXSparse" "KLU" "LDL" "SPQR" "UMFPACK")

# Define required and optional component dependencies
set(SUITESPARSE_CHOLDMOD_REQUIRED_DEPENDENCIES "AMD" "COLAMD" "CCOLAMD")
set(SUITESPARSE_CHOLDMOD_REQUIRES_BLAS TRUE)
set(SUITESPARSE_CHOLDMOD_REQUIRES_LAPACK TRUE)
set(SUITESPARSE_KLU_REQUIRED_DEPENDENCIES "AMD" "COLAMD" "BTF")
set(SUITESPARSE_KLU_OPTIONAL_DEPENDENCIES "CHOLMOD" "CAMD" "CCOLAMD")
set(SUITESPARSE_SPQR_REQUIRED_DEPENDENCIES "CHOLMOD" "AMD" "COLAMD")
set(SUITESPARSE_SPQR_REQUIRES_BLAS TRUE)
set(SUITESPARSE_SPQR_REQUIRES_LAPACK TRUE)
set(SUITESPARSE_UMFPACK_REQUIRED_DEPENDENCIES "AMD")
set(SUITESPARSE_UMFPACK_OPTIONAL_DEPENDENCIES "CHOLMOD" "CAMD" "CCOLAMD" "COLAMD")
set(SUITESPARSE_UMFPACK_REQUIRES_BLAS TRUE)

# look for library suitesparseconfig
find_library(SUITESPARSE_CONFIG_LIB "suitesparseconfig"
  PATH_SUFFIXES "SuiteSparse_config"
)
# look for header file SuiteSparse_config.h
find_path(SUITESPARSE_INCLUDE_DIR "SuiteSparse_config.h"
  PATH_SUFFIXES "suitesparse" "include" "SuiteSparse_config"
)

get_filename_component(SUITESPARSE_LIB_DIR ${SUITESPARSE_CONFIG_LIB} DIRECTORY)
mark_as_advanced(SUITESPARSE_INCLUDE_DIR SUITESPARSE_CONFIG_LIB)

foreach(_component ${SUITESPARSE_COMPONENTS})
  string(TOLOWER ${_component} _componentLower)

  # look for library of the component
  find_library(${_component}_LIBRARY "${_componentLower}"
    HINTS ${SUITESPARSE_LIB_DIR}
    PATH_SUFFIXES "${_component}/Lib"
  )
  # look for header file of the component
  find_path(${_component}_INCLUDE_DIR "${_componentLower}.h"
    HINTS ${SUITESPARSE_INCLUDE_DIR}
    PATH_SUFFIXES "suitesparse" "include" "${_component}/Include"
  )

  mark_as_advanced(${_component}_INCLUDE_DIR ${_component}_LIBRARY)
endforeach()

# Look for the header files that have different header file names
find_path(SPQR_INCLUDE_DIR "SuiteSparseQR.hpp"
  HINTS ${SUITESPARSE_INCLUDE_DIR}
  PATH_SUFFIXES "suitesparse" "include" "SPQR/Include"
)
find_path(Mongoose_INCLUDE_DIR "Mongoose.hpp"
  HINTS ${SUITESPARSE_INCLUDE_DIR}
  PATH_SUFFIXES "suitesparse" "include" "Mongoose/Include"
)
find_path(GraphBLAS_INCLUDE_DIR "GraphBLAS.h"
  HINTS ${SUITESPARSE_INCLUDE_DIR}
  PATH_SUFFIXES "suitesparse" "include" "GraphBLAS/Include"
)

# check version of SuiteSparse
find_file(SUITESPARSE_CONFIG_FILE "SuiteSparse_config.h"
  HINTS ${SUITESPARSE_INCLUDE_DIR}
  NO_DEFAULT_PATH)
if(SUITESPARSE_CONFIG_FILE)
  file(READ "${SUITESPARSE_CONFIG_FILE}" suitesparseconfig)
  string(REGEX REPLACE ".*#define SUITESPARSE_MAIN_VERSION[ ]+([0-9]+).*" "\\1"
    SUITESPARSE_MAJOR_VERSION  "${suitesparseconfig}")
  string(REGEX REPLACE ".*#define SUITESPARSE_SUB_VERSION[ ]+([0-9]+).*" "\\1"
    SUITESPARSE_MINOR_VERSION  "${suitesparseconfig}")
  string(REGEX REPLACE ".*#define SUITESPARSE_SUBSUB_VERSION[ ]+([0-9]+).*" "\\1"
    SUITESPARSE_PREFIX_VERSION "${suitesparseconfig}")
  if(SUITESPARSE_MAJOR_VERSION GREATER_EQUAL 0)
    set(SuiteSparse_VERSION "${SUITESPARSE_MAJOR_VERSION}")
  endif()
  if (SUITESPARSE_MINOR_VERSION GREATER_EQUAL 0)
    set(SuiteSparse_VERSION "${SuiteSparse_VERSION}.${SUITESPARSE_MINOR_VERSION}")
  endif()
  if (SUITESPARSE_PREFIX_VERSION GREATER_EQUAL 0)
    set(SuiteSparse_VERSION "${SuiteSparse_VERSION}.${SUITESPARSE_PREFIX_VERSION}")
  endif()
endif()
unset(SUITESPARSE_CONFIG_FILE CACHE)


# check whether everything was found
foreach(_component ${SUITESPARSE_COMPONENTS})
  if(${_component}_LIBRARY AND ${_component}_INCLUDE_DIR)
    set(SuiteSparse_${_component}_FOUND TRUE)
  else()
    set(SuiteSparse_${_component}_FOUND FALSE)
  endif()
endforeach(_component)

# test for required dependencies
foreach(_component ${SUITESPARSE_COMPONENTS})
  foreach(_dependency ${SUITESPARSE_${_component}_REQUIRED_DEPENDENCIES})
    if(NOT SuiteSparse_${_dependency}_FOUND)
      set(SuiteSparse_${_component}_FOUND FALSE)
    endif()
  endforeach(_dependency)
endforeach(_component)

# SPQR requires SuiteSparse >= 4.3
if(SPQR_LIBRARY)
  if(SuiteSparse_VERSION VERSION_LESS "4.3")
    set(SuiteSparse_SPQR_FOUND FALSE)
  endif()
endif()


# behave like a CMake module is supposed to behave
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("SuiteSparse"
  REQUIRED_VARS
    SUITESPARSE_CONFIG_LIB SUITESPARSE_INCLUDE_DIR BLAS_FOUND
  VERSION_VAR
    SuiteSparse_VERSION
  HANDLE_COMPONENTS
)

# list to indicate which components are found
set(SuiteSparse_FOUND_COMPONENTS)

# if both headers and library for all required components are found,
# then create imported targets for all components
if(SuiteSparse_FOUND)
  if(NOT TARGET SuiteSparse::SuiteSparse_config)
    add_library(SuiteSparse::SuiteSparse_config UNKNOWN IMPORTED)
    set_target_properties(SuiteSparse::SuiteSparse_config PROPERTIES
      IMPORTED_LOCATION ${SUITESPARSE_CONFIG_LIB}
      INTERFACE_INCLUDE_DIRECTORIES ${SUITESPARSE_INCLUDE_DIR}
    )
  endif()

  # Define component imported-targets
  foreach(_component ${SUITESPARSE_COMPONENTS})
    if(SuiteSparse_${_component}_FOUND AND NOT TARGET SuiteSparse::${_component})
      add_library(SuiteSparse::${_component} UNKNOWN IMPORTED)
      set_target_properties(SuiteSparse::${_component} PROPERTIES
        IMPORTED_LOCATION ${${_component}_LIBRARY}
        INTERFACE_INCLUDE_DIRECTORIES ${${_component}_INCLUDE_DIR}
        INTERFACE_LINK_LIBRARIES SuiteSparse::SuiteSparse_config
      )
    endif()
  endforeach(_component)

  foreach(_component ${SUITESPARSE_COMPONENTS})
    if(TARGET SuiteSparse::${_component})
      # add component in the list of found components
      list(APPEND SuiteSparse_FOUND_COMPONENTS ${_component})

      # Link required dependencies
      foreach(_dependency ${SUITESPARSE_${_component}_REQUIRED_DEPENDENCIES})
        target_link_libraries(SuiteSparse::${_component}
          INTERFACE SuiteSparse::${_dependency})
      endforeach(_dependency)

      # Link found optional dependencies
      foreach(_dependency ${SUITESPARSE_${_component}_OPTIONAL_DEPENDENCIES})
        if(SuiteSparse_${_dependency}_FOUND)
          target_link_libraries(SuiteSparse::${_component}
            INTERFACE SuiteSparse::${_dependency})
        endif()
      endforeach(_dependency)

      # Link BLAS library
      if(SUITESPARSE_${_component}_REQUIRES_BLAS)
        if(TARGET BLAS::BLAS)
          target_link_libraries(SuiteSparse::${_component}
            INTERFACE BLAS::BLAS)
        else()
          target_link_libraries(SuiteSparse::${_component}
            INTERFACE ${BLAS_LINKER_FLAGS} ${BLAS_LIBRARIES})
        endif()
      endif()

      # Link LAPACK library
      if(SUITESPARSE_${_component}_REQUIRES_LAPACK)
        if(TARGET LAPACK::LAPACK)
          target_link_libraries(SuiteSparse::${_component}
            INTERFACE LAPACK::LAPACK)
        else()
          target_link_libraries(SuiteSparse::${_component}
            INTERFACE ${LAPACK_LINKER_FLAGS} ${LAPACK_LIBRARIES})
        endif()
      endif()
    endif()
  endforeach(_component)

  # Combine all requested components to an imported target
  if(NOT TARGET SuiteSparse::SuiteSparse)
    add_library(SuiteSparse::SuiteSparse INTERFACE IMPORTED)
    target_link_libraries(SuiteSparse::SuiteSparse
      INTERFACE SuiteSparse::SuiteSparse_config)
  endif()
  foreach(_component ${SuiteSparse_FIND_COMPONENTS})
    if(SuiteSparse_${_component}_FOUND)
      set(HAVE_SUITESPARSE_${_component} TRUE)
      target_link_libraries(SuiteSparse::SuiteSparse
        INTERFACE SuiteSparse::${_component})
    endif()
  endforeach(_component)
endif()