Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Modules / FindPackageHandleStandardArgs.cmake
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
3
4 #[=======================================================================[.rst:
5 FindPackageHandleStandardArgs
6 -----------------------------
7
8 This module provides functions intended to be used in :ref:`Find Modules`
9 implementing :command:`find_package(<PackageName>)` calls.
10
11 .. command:: find_package_handle_standard_args
12
13   This command handles the ``REQUIRED``, ``QUIET`` and version-related
14   arguments of :command:`find_package`.  It also sets the
15   ``<PackageName>_FOUND`` variable.  The package is considered found if all
16   variables listed contain valid results, e.g. valid filepaths.
17
18   There are two signatures:
19
20   .. code-block:: cmake
21
22     find_package_handle_standard_args(<PackageName>
23       (DEFAULT_MSG|<custom-failure-message>)
24       <required-var>...
25       )
26
27     find_package_handle_standard_args(<PackageName>
28       [FOUND_VAR <result-var>]
29       [REQUIRED_VARS <required-var>...]
30       [VERSION_VAR <version-var>]
31       [HANDLE_VERSION_RANGE]
32       [HANDLE_COMPONENTS]
33       [CONFIG_MODE]
34       [NAME_MISMATCHED]
35       [REASON_FAILURE_MESSAGE <reason-failure-message>]
36       [FAIL_MESSAGE <custom-failure-message>]
37       )
38
39   The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all
40   the variables ``<required-var>...`` are valid and any optional
41   constraints are satisfied, and ``FALSE`` otherwise.  A success or
42   failure message may be displayed based on the results and on
43   whether the ``REQUIRED`` and/or ``QUIET`` option was given to
44   the :command:`find_package` call.
45
46   The options are:
47
48   ``(DEFAULT_MSG|<custom-failure-message>)``
49     In the simple signature this specifies the failure message.
50     Use ``DEFAULT_MSG`` to ask for a default message to be computed
51     (recommended).  Not valid in the full signature.
52
53   ``FOUND_VAR <result-var>``
54     .. deprecated:: 3.3
55
56     Specifies either ``<PackageName>_FOUND`` or
57     ``<PACKAGENAME>_FOUND`` as the result variable.  This exists only
58     for compatibility with older versions of CMake and is now ignored.
59     Result variables of both names are always set for compatibility.
60
61   ``REQUIRED_VARS <required-var>...``
62     Specify the variables which are required for this package.
63     These may be named in the generated failure message asking the
64     user to set the missing variable values.  Therefore these should
65     typically be cache entries such as ``FOO_LIBRARY`` and not output
66     variables like ``FOO_LIBRARIES``.
67
68     .. versionchanged:: 3.18
69       If ``HANDLE_COMPONENTS`` is specified, this option can be omitted.
70
71   ``VERSION_VAR <version-var>``
72     Specify the name of a variable that holds the version of the package
73     that has been found.  This version will be checked against the
74     (potentially) specified required version given to the
75     :command:`find_package` call, including its ``EXACT`` option.
76     The default messages include information about the required
77     version and the version which has been actually found, both
78     if the version is ok or not.
79
80   ``HANDLE_VERSION_RANGE``
81     .. versionadded:: 3.19
82
83     Enable handling of a version range, if one is specified. Without this
84     option, a developer warning will be displayed if a version range is
85     specified.
86
87   ``HANDLE_COMPONENTS``
88     Enable handling of package components.  In this case, the command
89     will report which components have been found and which are missing,
90     and the ``<PackageName>_FOUND`` variable will be set to ``FALSE``
91     if any of the required components (i.e. not the ones listed after
92     the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are
93     missing.
94
95   ``CONFIG_MODE``
96     Specify that the calling find module is a wrapper around a
97     call to ``find_package(<PackageName> NO_MODULE)``.  This implies
98     a ``VERSION_VAR`` value of ``<PackageName>_VERSION``.  The command
99     will automatically check whether the package configuration file
100     was found.
101
102   ``REASON_FAILURE_MESSAGE <reason-failure-message>``
103     .. versionadded:: 3.16
104
105     Specify a custom message of the reason for the failure which will be
106     appended to the default generated message.
107
108   ``FAIL_MESSAGE <custom-failure-message>``
109     Specify a custom failure message instead of using the default
110     generated message.  Not recommended.
111
112   ``NAME_MISMATCHED``
113     .. versionadded:: 3.17
114
115     Indicate that the ``<PackageName>`` does not match
116     ``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a
117     warning, but it may be intentional for usage of the command for components
118     of a larger package.
119
120 Example for the simple signature:
121
122 .. code-block:: cmake
123
124   find_package_handle_standard_args(LibXml2 DEFAULT_MSG
125     LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
126
127 The ``LibXml2`` package is considered to be found if both
128 ``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid.
129 Then also ``LibXml2_FOUND`` is set to ``TRUE``.  If it is not found
130 and ``REQUIRED`` was used, it fails with a
131 :command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was
132 used or not.  If it is found, success will be reported, including
133 the content of the first ``<required-var>``.  On repeated CMake runs,
134 the same message will not be printed again.
135
136 .. note::
137
138   If ``<PackageName>`` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the
139   calling module, a warning that there is a mismatch is given. The
140   ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using
141   the old signature and the ``NAME_MISMATCHED`` argument using the new
142   signature. To avoid forcing the caller to require newer versions of CMake for
143   usage, the variable's value will be used if defined when the
144   ``NAME_MISMATCHED`` argument is not passed for the new signature (but using
145   both is an error)..
146
147 Example for the full signature:
148
149 .. code-block:: cmake
150
151   find_package_handle_standard_args(LibArchive
152     REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
153     VERSION_VAR LibArchive_VERSION)
154
155 In this case, the ``LibArchive`` package is considered to be found if
156 both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid.
157 Also the version of ``LibArchive`` will be checked by using the version
158 contained in ``LibArchive_VERSION``.  Since no ``FAIL_MESSAGE`` is given,
159 the default messages will be printed.
160
161 Another example for the full signature:
162
163 .. code-block:: cmake
164
165   find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
166   find_package_handle_standard_args(Automoc4  CONFIG_MODE)
167
168 In this case, a ``FindAutmoc4.cmake`` module wraps a call to
169 ``find_package(Automoc4 NO_MODULE)`` and adds an additional search
170 directory for ``automoc4``.  Then the call to
171 ``find_package_handle_standard_args`` produces a proper success/failure
172 message.
173
174 .. command:: find_package_check_version
175
176   .. versionadded:: 3.19
177
178   Helper function which can be used to check if a ``<version>`` is valid
179   against version-related arguments of :command:`find_package`.
180
181   .. code-block:: cmake
182
183     find_package_check_version(<version> <result-var>
184       [HANDLE_VERSION_RANGE]
185       [RESULT_MESSAGE_VARIABLE <message-var>]
186       )
187
188   The ``<result-var>`` will hold a boolean value giving the result of the check.
189
190   The options are:
191
192   ``HANDLE_VERSION_RANGE``
193     Enable handling of a version range, if one is specified. Without this
194     option, a developer warning will be displayed if a version range is
195     specified.
196
197   ``RESULT_MESSAGE_VARIABLE <message-var>``
198     Specify a variable to get back a message describing the result of the check.
199
200 Example for the usage:
201
202 .. code-block:: cmake
203
204   find_package_check_version(1.2.3 result HANDLE_VERSION_RANGE
205     RESULT_MESSAGE_VARIABLE reason)
206   if (result)
207     message (STATUS "${reason}")
208   else()
209     message (FATAL_ERROR "${reason}")
210   endif()
211 #]=======================================================================]
212
213 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
214
215
216 cmake_policy(PUSH)
217 # numbers and boolean constants
218 cmake_policy (SET CMP0012 NEW)
219 # IN_LIST operator
220 cmake_policy (SET CMP0057 NEW)
221
222
223 # internal helper macro
224 macro(_FPHSA_FAILURE_MESSAGE _msg)
225   set (__msg "${_msg}")
226   if (FPHSA_REASON_FAILURE_MESSAGE)
227     string(APPEND __msg "\n    Reason given by package: ${FPHSA_REASON_FAILURE_MESSAGE}\n")
228   endif()
229   if (${_NAME}_FIND_REQUIRED)
230     message(FATAL_ERROR "${__msg}")
231   else ()
232     if (NOT ${_NAME}_FIND_QUIETLY)
233       message(STATUS "${__msg}")
234     endif ()
235   endif ()
236 endmacro()
237
238
239 # internal helper macro to generate the failure message when used in CONFIG_MODE:
240 macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
241   # <PackageName>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
242   if(${_NAME}_CONFIG)
243     _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
244   else()
245     # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
246     # List them all in the error message:
247     if(${_NAME}_CONSIDERED_CONFIGS)
248       set(configsText "")
249       list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
250       math(EXPR configsCount "${configsCount} - 1")
251       foreach(currentConfigIndex RANGE ${configsCount})
252         list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
253         list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
254         string(APPEND configsText "\n    ${filename} (version ${version})")
255       endforeach()
256       if (${_NAME}_NOT_FOUND_MESSAGE)
257         if (FPHSA_REASON_FAILURE_MESSAGE)
258           string(PREPEND FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}\n    ")
259         else()
260           set(FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}")
261         endif()
262       else()
263         string(APPEND configsText "\n")
264       endif()
265       _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:${configsText}")
266
267     else()
268       # Simple case: No Config-file was found at all:
269       _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
270     endif()
271   endif()
272 endmacro()
273
274
275 function(FIND_PACKAGE_CHECK_VERSION version result)
276   cmake_parse_arguments (PARSE_ARGV 2 FPCV "HANDLE_VERSION_RANGE;NO_AUTHOR_WARNING_VERSION_RANGE" "RESULT_MESSAGE_VARIABLE" "")
277
278   if (FPCV_UNPARSED_ARGUMENTS)
279     message (FATAL_ERROR "find_package_check_version(): ${FPCV_UNPARSED_ARGUMENTS}: unexpected arguments")
280   endif()
281   if ("RESULT_MESSAGE_VARIABLE" IN_LIST FPCV_KEYWORDS_MISSING_VALUES)
282     message (FATAL_ERROR "find_package_check_version(): RESULT_MESSAGE_VARIABLE expects an argument")
283   endif()
284
285   set (${result} FALSE PARENT_SCOPE)
286   if (FPCV_RESULT_MESSAGE_VARIABLE)
287     unset (${FPCV_RESULT_MESSAGE_VARIABLE} PARENT_SCOPE)
288   endif()
289
290   if (_CMAKE_FPHSA_PACKAGE_NAME)
291     set (package "${_CMAKE_FPHSA_PACKAGE_NAME}")
292   elseif (CMAKE_FIND_PACKAGE_NAME)
293     set (package "${CMAKE_FIND_PACKAGE_NAME}")
294   else()
295     message (FATAL_ERROR "find_package_check_version(): Cannot be used outside a 'Find Module'")
296   endif()
297
298   if (NOT FPCV_NO_AUTHOR_WARNING_VERSION_RANGE
299       AND ${package}_FIND_VERSION_RANGE AND NOT FPCV_HANDLE_VERSION_RANGE)
300     message(AUTHOR_WARNING
301       "`find_package()` specify a version range but the option "
302       "HANDLE_VERSION_RANGE` is not passed to `find_package_check_version()`. "
303       "Only the lower endpoint of the range will be used.")
304   endif()
305
306
307   set (version_ok FALSE)
308   unset (version_msg)
309
310   if (FPCV_HANDLE_VERSION_RANGE AND ${package}_FIND_VERSION_RANGE)
311     if ((${package}_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE"
312           AND version VERSION_GREATER_EQUAL ${package}_FIND_VERSION_MIN)
313         AND ((${package}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE"
314             AND version VERSION_LESS_EQUAL ${package}_FIND_VERSION_MAX)
315           OR (${package}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE"
316             AND version VERSION_LESS ${package}_FIND_VERSION_MAX)))
317       set (version_ok TRUE)
318       set(version_msg "(found suitable version \"${version}\", required range is \"${${package}_FIND_VERSION_RANGE}\")")
319     else()
320       set(version_msg "Found unsuitable version \"${version}\", required range is \"${${package}_FIND_VERSION_RANGE}\"")
321     endif()
322   elseif (DEFINED ${package}_FIND_VERSION)
323     if(${package}_FIND_VERSION_EXACT)       # exact version required
324       # count the dots in the version string
325       string(REGEX REPLACE "[^.]" "" version_dots "${version}")
326       # add one dot because there is one dot more than there are components
327       string(LENGTH "${version_dots}." version_dots)
328       if (version_dots GREATER ${package}_FIND_VERSION_COUNT)
329         # Because of the C++ implementation of find_package() ${package}_FIND_VERSION_COUNT
330         # is at most 4 here. Therefore a simple lookup table is used.
331         if (${package}_FIND_VERSION_COUNT EQUAL 1)
332           set(version_regex "[^.]*")
333         elseif (${package}_FIND_VERSION_COUNT EQUAL 2)
334           set(version_regex "[^.]*\\.[^.]*")
335         elseif (${package}_FIND_VERSION_COUNT EQUAL 3)
336           set(version_regex "[^.]*\\.[^.]*\\.[^.]*")
337         else()
338           set(version_regex "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
339         endif()
340         string(REGEX REPLACE "^(${version_regex})\\..*" "\\1" version_head "${version}")
341         if (NOT ${package}_FIND_VERSION VERSION_EQUAL version_head)
342           set(version_msg "Found unsuitable version \"${version}\", but required is exact version \"${${package}_FIND_VERSION}\"")
343         else ()
344           set(version_ok TRUE)
345           set(version_msg "(found suitable exact version \"${_FOUND_VERSION}\")")
346         endif ()
347       else ()
348         if (NOT ${package}_FIND_VERSION VERSION_EQUAL version)
349           set(version_msg "Found unsuitable version \"${version}\", but required is exact version \"${${package}_FIND_VERSION}\"")
350         else ()
351           set(version_ok TRUE)
352           set(version_msg "(found suitable exact version \"${version}\")")
353         endif ()
354       endif ()
355     else()     # minimum version
356       if (${package}_FIND_VERSION VERSION_GREATER version)
357         set(version_msg "Found unsuitable version \"${version}\", but required is at least \"${${package}_FIND_VERSION}\"")
358       else()
359         set(version_ok TRUE)
360         set(version_msg "(found suitable version \"${version}\", minimum required is \"${${package}_FIND_VERSION}\")")
361       endif()
362     endif()
363   else ()
364     set(version_ok TRUE)
365     set(version_msg "(found version \"${version}\")")
366   endif()
367
368   set (${result} ${version_ok} PARENT_SCOPE)
369   if (FPCV_RESULT_MESSAGE_VARIABLE)
370     set (${FPCV_RESULT_MESSAGE_VARIABLE} "${version_msg}" PARENT_SCOPE)
371   endif()
372 endfunction()
373
374
375 function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
376
377   # Set up the arguments for `cmake_parse_arguments`.
378   set(options  CONFIG_MODE  HANDLE_COMPONENTS NAME_MISMATCHED HANDLE_VERSION_RANGE)
379   set(oneValueArgs  FAIL_MESSAGE  REASON_FAILURE_MESSAGE VERSION_VAR  FOUND_VAR)
380   set(multiValueArgs REQUIRED_VARS)
381
382   # Check whether we are in 'simple' or 'extended' mode:
383   set(_KEYWORDS_FOR_EXTENDED_MODE  ${options} ${oneValueArgs} ${multiValueArgs} )
384   list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
385
386   unset(FPHSA_NAME_MISMATCHED_override)
387   if (DEFINED FPHSA_NAME_MISMATCHED)
388     # If the variable NAME_MISMATCHED variable is set, error if it is passed as
389     # an argument. The former is for old signatures, the latter is for new
390     # signatures.
391     list(FIND ARGN "NAME_MISMATCHED" name_mismatched_idx)
392     if (NOT name_mismatched_idx EQUAL "-1")
393       message(FATAL_ERROR
394         "The `NAME_MISMATCHED` argument may only be specified by the argument or "
395         "the variable, not both.")
396     endif ()
397
398     # But use the variable if it is not an argument to avoid forcing minimum
399     # CMake version bumps for calling modules.
400     set(FPHSA_NAME_MISMATCHED_override "${FPHSA_NAME_MISMATCHED}")
401   endif ()
402
403   if(${INDEX} EQUAL -1)
404     set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
405     set(FPHSA_REQUIRED_VARS ${ARGN})
406     set(FPHSA_VERSION_VAR)
407   else()
408     cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}"  ${_FIRST_ARG} ${ARGN})
409
410     if(FPHSA_UNPARSED_ARGUMENTS)
411       message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
412     endif()
413
414     if(NOT FPHSA_FAIL_MESSAGE)
415       set(FPHSA_FAIL_MESSAGE  "DEFAULT_MSG")
416     endif()
417
418     # In config-mode, we rely on the variable <PackageName>_CONFIG, which is set by find_package()
419     # when it successfully found the config-file, including version checking:
420     if(FPHSA_CONFIG_MODE)
421       list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
422       list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
423       set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
424     endif()
425
426     if(NOT FPHSA_REQUIRED_VARS AND NOT FPHSA_HANDLE_COMPONENTS)
427       message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
428     endif()
429   endif()
430
431   if (DEFINED FPHSA_NAME_MISMATCHED_override)
432     set(FPHSA_NAME_MISMATCHED "${FPHSA_NAME_MISMATCHED_override}")
433   endif ()
434
435   if (DEFINED CMAKE_FIND_PACKAGE_NAME
436       AND NOT FPHSA_NAME_MISMATCHED
437       AND NOT _NAME STREQUAL CMAKE_FIND_PACKAGE_NAME)
438     message(AUTHOR_WARNING
439       "The package name passed to `find_package_handle_standard_args` "
440       "(${_NAME}) does not match the name of the calling package "
441       "(${CMAKE_FIND_PACKAGE_NAME}). This can lead to problems in calling "
442       "code that expects `find_package` result variables (e.g., `_FOUND`) "
443       "to follow a certain pattern.")
444   endif ()
445
446   if (${_NAME}_FIND_VERSION_RANGE AND NOT FPHSA_HANDLE_VERSION_RANGE)
447     message(AUTHOR_WARNING
448       "`find_package()` specify a version range but the module ${_NAME} does "
449       "not support this capability. Only the lower endpoint of the range "
450       "will be used.")
451   endif()
452
453   # to propagate package name to FIND_PACKAGE_CHECK_VERSION
454   set(_CMAKE_FPHSA_PACKAGE_NAME "${_NAME}")
455
456   # now that we collected all arguments, process them
457
458   if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
459     set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
460   endif()
461
462   if (FPHSA_REQUIRED_VARS)
463     list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
464   endif()
465
466   string(TOUPPER ${_NAME} _NAME_UPPER)
467   string(TOLOWER ${_NAME} _NAME_LOWER)
468
469   if(FPHSA_FOUND_VAR)
470     set(_FOUND_VAR_UPPER ${_NAME_UPPER}_FOUND)
471     set(_FOUND_VAR_MIXED ${_NAME}_FOUND)
472     if(FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_MIXED  OR  FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_UPPER)
473       set(_FOUND_VAR ${FPHSA_FOUND_VAR})
474     else()
475       message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_FOUND_VAR_MIXED}\" and \"${_FOUND_VAR_UPPER}\" are valid names.")
476     endif()
477   else()
478     set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
479   endif()
480
481   # collect all variables which were not found, so they can be printed, so the
482   # user knows better what went wrong (#6375)
483   set(MISSING_VARS "")
484   set(DETAILS "")
485   # check if all passed variables are valid
486   set(FPHSA_FOUND_${_NAME} TRUE)
487   foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
488     if(NOT ${_CURRENT_VAR})
489       set(FPHSA_FOUND_${_NAME} FALSE)
490       string(APPEND MISSING_VARS " ${_CURRENT_VAR}")
491     else()
492       string(APPEND DETAILS "[${${_CURRENT_VAR}}]")
493     endif()
494   endforeach()
495   if(FPHSA_FOUND_${_NAME})
496     set(${_NAME}_FOUND TRUE)
497     set(${_NAME_UPPER}_FOUND TRUE)
498   else()
499     set(${_NAME}_FOUND FALSE)
500     set(${_NAME_UPPER}_FOUND FALSE)
501   endif()
502
503   # component handling
504   unset(FOUND_COMPONENTS_MSG)
505   unset(MISSING_COMPONENTS_MSG)
506
507   if(FPHSA_HANDLE_COMPONENTS)
508     foreach(comp ${${_NAME}_FIND_COMPONENTS})
509       if(${_NAME}_${comp}_FOUND)
510
511         if(NOT DEFINED FOUND_COMPONENTS_MSG)
512           set(FOUND_COMPONENTS_MSG "found components:")
513         endif()
514         string(APPEND FOUND_COMPONENTS_MSG " ${comp}")
515
516       else()
517
518         if(NOT DEFINED MISSING_COMPONENTS_MSG)
519           set(MISSING_COMPONENTS_MSG "missing components:")
520         endif()
521         string(APPEND MISSING_COMPONENTS_MSG " ${comp}")
522
523         if(${_NAME}_FIND_REQUIRED_${comp})
524           set(${_NAME}_FOUND FALSE)
525           string(APPEND MISSING_VARS " ${comp}")
526         endif()
527
528       endif()
529     endforeach()
530     set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
531     string(APPEND DETAILS "[c${COMPONENT_MSG}]")
532   endif()
533
534   # version handling:
535   set(VERSION_MSG "")
536   set(VERSION_OK TRUE)
537
538   # check that the version variable is not empty to avoid emitting a misleading
539   # message (i.e. `Found unsuitable version ""`)
540   if (DEFINED ${_NAME}_FIND_VERSION)
541     if(DEFINED ${FPHSA_VERSION_VAR})
542       if(NOT "${${FPHSA_VERSION_VAR}}" STREQUAL "")
543         set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}})
544         if (FPHSA_HANDLE_VERSION_RANGE)
545           set (FPCV_HANDLE_VERSION_RANGE HANDLE_VERSION_RANGE)
546         else()
547           set(FPCV_HANDLE_VERSION_RANGE NO_AUTHOR_WARNING_VERSION_RANGE)
548         endif()
549         find_package_check_version ("${_FOUND_VERSION}" VERSION_OK RESULT_MESSAGE_VARIABLE VERSION_MSG
550           ${FPCV_HANDLE_VERSION_RANGE})
551       else()
552         set(VERSION_OK FALSE)
553       endif()
554     endif()
555     if("${${FPHSA_VERSION_VAR}}" STREQUAL "")
556       # if the package was not found, but a version was given, add that to the output:
557       if(${_NAME}_FIND_VERSION_EXACT)
558         set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
559       elseif (FPHSA_HANDLE_VERSION_RANGE AND ${_NAME}_FIND_VERSION_RANGE)
560         set(VERSION_MSG "(Required is version range \"${${_NAME}_FIND_VERSION_RANGE}\")")
561       else()
562         set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
563       endif()
564     endif()
565   else ()
566     # Check with DEFINED as the found version may be 0.
567     if(DEFINED ${FPHSA_VERSION_VAR})
568       set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")")
569     endif()
570   endif ()
571
572   if(VERSION_OK)
573     string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]")
574   else()
575     set(${_NAME}_FOUND FALSE)
576   endif()
577
578
579   # print the result:
580   if (${_NAME}_FOUND)
581     FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
582   else ()
583
584     if(FPHSA_CONFIG_MODE)
585       _FPHSA_HANDLE_FAILURE_CONFIG_MODE()
586     else()
587       if(NOT VERSION_OK)
588         set(RESULT_MSG)
589         if (_FIRST_REQUIRED_VAR)
590           string (APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}")
591         endif()
592         if (COMPONENT_MSG)
593           if (RESULT_MSG)
594             string (APPEND RESULT_MSG ", ")
595           endif()
596           string (APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}")
597         endif()
598         _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (${RESULT_MSG})")
599       else()
600         _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}")
601       endif()
602     endif()
603
604   endif ()
605
606   set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
607   set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
608 endfunction()
609
610
611 cmake_policy(POP)