File: OpmFind.cmake

package info (click to toggle)
opm-common 2022.10%2Bds-7
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 78,468 kB
  • sloc: cpp: 164,554; python: 2,872; sh: 216; xml: 174; ansic: 149; pascal: 136; makefile: 12
file content (249 lines) | stat: -rw-r--r-- 10,213 bytes parent folder | download | duplicates (4)
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
# - Generic inclusion of packages
#
# Synopsis:
#
#	find_and_append_package (name args)
#
# where
#
#	name          Name of the package, e.g. Boost
#   args          Other arguments, e.g. COMPONENTS, REQUIRED, QUIET etc.
#
# This macro will append the list of standard variables found by the
# package to this project's standard variables
#
########################################################################
#
# - Generic inclusion of a list of packages
#
# Synopsis:
#
#	find_and_append_package_list (args)
#
# where
#
#	args          List of package strings. Each string must be quoted if
#	              it contains more than one word.
#
# Example:
#
#	find_and_append_package_list (
#		"Boost COMPONENTS filesystem REQUIRED"
#		SUPERLU
#	)

include (Duplicates)
include (OpmSiblingSearch)

# list of suffixes for all the project variables
set (_opm_proj_vars
  SOURCES
  LINKER_FLAGS
  LIBRARIES
  DEFINITIONS
  INCLUDE_DIRS
  LIBRARY_DIRS
  CONFIG_VARS
  CONFIG_IMPL_VARS
  )

# ensure that they are at least the empty list after we're done
foreach (name IN LISTS _opm_proj_vars)
  if (NOT DEFINED ${CMAKE_PROJECT_NAME}_${name})
	set (${CMAKE_PROJECT_NAME}_${name} "")
  endif (NOT DEFINED ${CMAKE_PROJECT_NAME}_${name})
endforeach (name)


# insert this boilerplate whenever we are going to find a new package
macro (find_and_append_package_to prefix name)
  # special handling for Boost to avoid inadvertedly picking up system
  # libraries when we want our own version. this is done here because
  # having a custom Boost is common, but the logic to search only there
  # does not follow any particular convention.
  if (BOOST_ROOT AND NOT DEFINED Boost_NO_SYSTEM_PATHS)
	set (Boost_NO_SYSTEM_PATHS TRUE)
  endif (BOOST_ROOT AND NOT DEFINED Boost_NO_SYSTEM_PATHS)

  # if we have specified a directory, don't revert to searching the
  # system default paths afterwards
  string (TOUPPER "${name}" NAME)
  string (REPLACE "-" "_" NAME "${NAME}")

  # only use suite if module-specific variable is not set. this allows
  # us to override one dir in a suite
  if (NOT (${name}_DIR OR ${name}_ROOT OR ${NAME}_ROOT))
	# module is part of a suite if it has name with the pattern xxx-yyy
	if (("${name}" MATCHES "[^-]+-.+") OR ${name}_SUITE)
	  # allow to override if the module doesn't quite fit the convention
	  # e.g. dune-cornerpoint (since renamed to opm-grid)
	  if (NOT DEFINED ${name}_SUITE)
		# extract suite name from module
		string (REGEX REPLACE "([^-]+)-.+" "\\1" ${name}_SUITE "${name}")
	  endif (NOT DEFINED ${name}_SUITE)
	  # assume that each module has its own subdir directly under suite dir
	  string (TOUPPER "${${name}_SUITE}" ${name}_SUITE_UPPER)
	  if (DEFINED ${${name}_SUITE_UPPER}_ROOT)
		set (${NAME}_ROOT ${${${name}_SUITE_UPPER}_ROOT}/${name})
	  endif (DEFINED ${${name}_SUITE_UPPER}_ROOT)
	endif (("${name}" MATCHES "[^-]+-.+") OR ${name}_SUITE)
  endif (NOT (${name}_DIR OR ${name}_ROOT OR ${NAME}_ROOT))

  # the documentation says that if *-config.cmake files are not found,
  # find_package will revert to doing a full search, but that is not
  # true, so unconditionally setting ${name}_DIR is not safe. however,
  # if the directory given to us contains a config file, then copy the
  # value over to this variable to switch to config mode (CMake will
  # always use config mode if *_DIR is defined)
  if (NOT DEFINED ${name}_DIR AND (DEFINED ${name}_ROOT OR DEFINED ${NAME}_ROOT))
	if (EXISTS ${${name}_ROOT}/${name}-config.cmake OR EXISTS ${${name}_ROOT}/${name}Config.cmake)
	  set (${name}_DIR "${${name}_ROOT}")
	endif (EXISTS ${${name}_ROOT}/${name}-config.cmake OR EXISTS ${${name}_ROOT}/${name}Config.cmake)
	if (EXISTS ${${NAME}_ROOT}/${name}-config.cmake OR EXISTS ${${NAME}_ROOT}/${name}Config.cmake)
	  set (${name}_DIR "${${NAME}_ROOT}")
	endif (EXISTS ${${NAME}_ROOT}/${name}-config.cmake OR EXISTS ${${NAME}_ROOT}/${name}Config.cmake)
  endif (NOT DEFINED ${name}_DIR AND (DEFINED ${name}_ROOT OR DEFINED ${NAME}_ROOT))

  # if we're told not to look for the package, pretend it was never found
  if (CMAKE_DISABLE_FIND_PACKAGE_${name})
    # If required send an error
    cmake_parse_arguments(FIND "REQUIRED" "" "" ${ARGN} )
    set (${name}_FOUND FALSE)
    set (${NAME}_FOUND FALSE)
    if (FIND_REQUIRED)
        message(SEND_ERROR "package ${name} but disable with CMAKE_DISABLE_FIND_PACKAGE_${name}")
    endif ()
  else ()
    # List of components might differ for every module. Therefore we will
    # need to research for a library multiple times. _search_components
    # will hold the index of the string COMPONENTS in the list
    set(_ARGN_LIST ${ARGN}) # Create a real list to use with list commands
    list(FIND _ARGN_LIST "COMPONENTS" _search_components)

    # using config mode is better than using module (aka. find) mode
    # because then the package has already done all its probes and
    # stored them in the config file for us
    # For dune and opm modules and exempted packages we force module mode.
    # For dune and opm it will use config mode underneath.
    # We even need to repeat the search for opm-common once as this is done
    # in the top most CMakeLists.txt without querying defines, setting dependencies
    # and the likes which is only done via opm_find_package
    string(REGEX MATCH "(opm)-.*" _is_opm ${name})
    if(NOT _is_opm)
      # When using Boost >= 1.70 and e.g. CMake 3.18 we need to make sure that
      # subsequent searches are using config mode too. Otherwise the library
      # list will be completely messed up. We use a set Boost_Dir to detect that
      # previous searches were done using config mode.
      if("${name}" STREQUAL "Boost" AND Boost_DIR)
        set(_CONFIG_MODE CONFIG)
      else()
        set(_CONFIG_MODE "")
      endif()
      find_package (${name} ${ARGN} ${_CONFIG_MODE})
    else()
      if(${name}_DIR)
        find_package (${name} ${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR} ${ARGN} NO_MODULE PATHS ${${name}_DIR} NO_DEFAULT_PATH)
      else()
        find_package (${name} ${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR} ${ARGN} NO_MODULE)
      endif()
      include(FindPackageHandleStandardArgs)
      if( CMAKE_VERSION VERSION_GREATER_EQUAL "3.17")
	# For some reason we will e.g. call
	# find_package_handle_standard_args(opm-common)
	# in a find_package(opm-material) call and this will
	# usuallly print an annoying warnig. Prevent this at least
	# for cmake >=3.17
	# \todo Check why/whether these calls are even needed.
	set(_NAME_MISMATCHED "NAME_MISMATCHED")
      endif()
      if(${name}_FOUND AND ${name}_LIBRARY STREQUAL "")
        find_package_handle_standard_args(${name}
          REQUIRED_VARS ${name}_INCLUDE_DIRS ${_NAME_MISMATCHED})
      else()
        find_package_handle_standard_args(${name}
          REQUIRED_VARS ${name}_LIBRARY ${_NAME_MISMATCHED})
      endif()
    endif ()
    if (NOT DEFINED ${name}_FOUND)
      set (${name}_FOUND "${${NAME}_FOUND}")
    endif ()
    if (NOT DEFINED ${NAME}_FOUND)
      set (${NAME}_FOUND "${${name}_FOUND}")
    endif ()
  endif ()

  # the variable "NAME" may be replaced during find_package (as this is
  # now a macro, and not a function anymore), so we must reinitialize
  string (TOUPPER "${name}" NAME)
  string (REPLACE "-" "_" NAME "${NAME}")

  if (${name}_FOUND OR ${NAME}_FOUND)
      foreach (var IN LISTS _opm_proj_vars)
          if("${var}" STREQUAL "DEFINITIONS"
            AND CMAKE_VERSION VERSION_LESS "3.12")
            # For old Cmake versions we use add_definitions which
            # requires -D qualifier add that
            set(_defs)
            foreach(_def IN LISTS ${name}_${var})
              if(_def MATCHES "^[a-zA-Z].*")
                list(APPEND _defs "-D${_def}")
              else()
                list(APPEND _defs "${_def}")
              endif()
            endforeach()
            set(${name}_${var} "${_defs}")
          endif()
	  if (DEFINED ${name}_${var})
		list (APPEND ${prefix}_${var} ${${name}_${var}})
	  # some packages define an uppercase version of their own name
	  elseif (DEFINED ${NAME}_${var})
		list (APPEND ${prefix}_${var} ${${NAME}_${var}})
	  endif (DEFINED ${name}_${var})
	  # some packages define _PATH instead of _DIRS (Hi, MPI!)
	  if ("${var}" STREQUAL "INCLUDE_DIRS")
		if (DEFINED ${name}_INCLUDE_PATH)
		  list (APPEND ${prefix}_INCLUDE_DIRS ${${name}_INCLUDE_PATH})
		elseif (DEFINED ${NAME}_INCLUDE_PATH)
		  list (APPEND ${prefix}_INCLUDE_DIRS ${${NAME}_INCLUDE_PATH})
		endif (DEFINED ${name}_INCLUDE_PATH)
		# some packages define only _DIR and not _DIRS (Hi, Eigen3!)
		if (DEFINED ${name}_INCLUDE_DIR)
		  list (APPEND ${prefix}_INCLUDE_DIRS ${${name}_INCLUDE_DIR})
		elseif (DEFINED ${NAME}_INCLUDE_DIR)
		  list (APPEND ${prefix}_INCLUDE_DIRS ${${NAME}_INCLUDE_DIR})
		endif (DEFINED ${name}_INCLUDE_DIR)
	  endif ("${var}" STREQUAL "INCLUDE_DIRS")
	  # cleanup lists
	  if ("${var}" STREQUAL "LIBRARIES")
		remove_duplicate_libraries (${prefix})
	  else ("${var}" STREQUAL "LIBRARIES")
		remove_duplicate_var (${prefix} ${var})
	  endif ("${var}" STREQUAL "LIBRARIES")
	endforeach (var)
	# some libraries only define xxx_FOUND and not a corresponding HAVE_xxx
	if (NOT DEFINED HAVE_${NAME})
	  set (HAVE_${NAME} 1)
	endif (NOT DEFINED HAVE_${NAME})
  endif (${name}_FOUND OR ${NAME}_FOUND)
endmacro (find_and_append_package_to prefix name)

# append to the list of variables associated with the project
macro (find_and_append_package name)
  find_and_append_package_to (${CMAKE_PROJECT_NAME} ${name} ${ARGN})
endmacro (find_and_append_package name)

# find a list of dependencies, adding each one of them
macro (find_and_append_package_list_to prefix)
  # setting and separating is necessary to work around apparent bugs
  # in CMake's parser (sic)
  set (_deps ${ARGN})
  foreach (_dep IN LISTS _deps)
	separate_arguments (_args UNIX_COMMAND ${_dep})
	find_and_append_package_to (${prefix} ${_args})
  endforeach (_dep)
endmacro (find_and_append_package_list_to prefix)

# convenience method to supply the project name as prefix
macro (find_and_append_package_list)
  find_and_append_package_list_to (${CMAKE_PROJECT_NAME} ${ARGN})
endmacro (find_and_append_package_list)