1
#[=======================================================================[.rst:
2
FindPackageHandleStandardArgs
3
-----------------------------
5
This module provides a function intended to be used in :ref:`Find Modules`
6
implementing :command:`find_package(<PackageName>)` calls. It handles the
7
``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``.
8
It also sets the ``<PackageName>_FOUND`` variable. The package is
9
considered found if all variables listed contain valid results, e.g.
12
.. command:: find_package_handle_standard_args
14
There are two signatures::
16
find_package_handle_standard_args(<PackageName>
17
(DEFAULT_MSG|<custom-failure-message>)
21
find_package_handle_standard_args(<PackageName>
22
[FOUND_VAR <result-var>]
23
[REQUIRED_VARS <required-var>...]
24
[VERSION_VAR <version-var>]
27
[FAIL_MESSAGE <custom-failure-message>]
30
The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all
31
the variables ``<required-var>...`` are valid and any optional
32
constraints are satisfied, and ``FALSE`` otherwise. A success or
33
failure message may be displayed based on the results and on
34
whether the ``REQUIRED`` and/or ``QUIET`` option was given to
35
the :command:`find_package` call.
39
``(DEFAULT_MSG|<custom-failure-message>)``
40
In the simple signature this specifies the failure message.
41
Use ``DEFAULT_MSG`` to ask for a default message to be computed
42
(recommended). Not valid in the full signature.
44
``FOUND_VAR <result-var>``
45
Obsolete. Specifies either ``<PackageName>_FOUND`` or
46
``<PACKAGENAME>_FOUND`` as the result variable. This exists only
47
for compatibility with older versions of CMake and is now ignored.
48
Result variables of both names are always set for compatibility.
50
``REQUIRED_VARS <required-var>...``
51
Specify the variables which are required for this package.
52
These may be named in the generated failure message asking the
53
user to set the missing variable values. Therefore these should
54
typically be cache entries such as ``FOO_LIBRARY`` and not output
55
variables like ``FOO_LIBRARIES``.
57
``VERSION_VAR <version-var>``
58
Specify the name of a variable that holds the version of the package
59
that has been found. This version will be checked against the
60
(potentially) specified required version given to the
61
:command:`find_package` call, including its ``EXACT`` option.
62
The default messages include information about the required
63
version and the version which has been actually found, both
64
if the version is ok or not.
67
Enable handling of package components. In this case, the command
68
will report which components have been found and which are missing,
69
and the ``<PackageName>_FOUND`` variable will be set to ``FALSE``
70
if any of the required components (i.e. not the ones listed after
71
the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are
75
Specify that the calling find module is a wrapper around a
76
call to ``find_package(<PackageName> NO_MODULE)``. This implies
77
a ``VERSION_VAR`` value of ``<PackageName>_VERSION``. The command
78
will automatically check whether the package configuration file
81
``FAIL_MESSAGE <custom-failure-message>``
82
Specify a custom failure message instead of using the default
83
generated message. Not recommended.
85
Example for the simple signature:
89
find_package_handle_standard_args(LibXml2 DEFAULT_MSG
90
LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
92
The ``LibXml2`` package is considered to be found if both
93
``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid.
94
Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found
95
and ``REQUIRED`` was used, it fails with a
96
:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was
97
used or not. If it is found, success will be reported, including
98
the content of the first ``<required-var>``. On repeated CMake runs,
99
the same message will not be printed again.
101
Example for the full signature:
103
.. code-block:: cmake
105
find_package_handle_standard_args(LibArchive
106
REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
107
VERSION_VAR LibArchive_VERSION)
109
In this case, the ``LibArchive`` package is considered to be found if
110
both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid.
111
Also the version of ``LibArchive`` will be checked by using the version
112
contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given,
113
the default messages will be printed.
115
Another example for the full signature:
117
.. code-block:: cmake
119
find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
120
find_package_handle_standard_args(Automoc4 CONFIG_MODE)
122
In this case, a ``FindAutmoc4.cmake`` module wraps a call to
123
``find_package(Automoc4 NO_MODULE)`` and adds an additional search
124
directory for ``automoc4``. Then the call to
125
``find_package_handle_standard_args`` produces a proper success/failure
127
#]=======================================================================]
129
#=============================================================================
130
# Copyright 2007-2009 Kitware, Inc.
132
# Distributed under the OSI-approved BSD License (the "License");
133
# see accompanying file Copyright.txt for details.
135
# This software is distributed WITHOUT ANY WARRANTY; without even the
136
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
137
# See the License for more information.
138
#=============================================================================
139
# (To distribute this file outside of CMake, substitute the full
140
# License text for the above reference.)
142
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
143
include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
145
# internal helper macro
146
macro(_FPHSA_FAILURE_MESSAGE _msg)
147
if (${_NAME}_FIND_REQUIRED)
148
message(FATAL_ERROR "${_msg}")
150
if (NOT ${_NAME}_FIND_QUIETLY)
151
message(STATUS "${_msg}")
157
# internal helper macro to generate the failure message when used in CONFIG_MODE:
158
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
159
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
161
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
163
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
164
# List them all in the error message:
165
if(${_NAME}_CONSIDERED_CONFIGS)
167
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
168
math(EXPR configsCount "${configsCount} - 1")
169
foreach(currentConfigIndex RANGE ${configsCount})
170
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
171
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
172
set(configsText "${configsText} ${filename} (version ${version})\n")
174
if (${_NAME}_NOT_FOUND_MESSAGE)
175
set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n")
177
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
180
# Simple case: No Config-file was found at all:
181
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
187
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
189
# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
190
# new extended or in the "old" mode:
191
set(options CONFIG_MODE HANDLE_COMPONENTS)
192
set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR)
193
set(multiValueArgs REQUIRED_VARS)
194
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
195
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
197
if(${INDEX} EQUAL -1)
198
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
199
set(FPHSA_REQUIRED_VARS ${ARGN})
200
set(FPHSA_VERSION_VAR)
203
CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
205
if(FPHSA_UNPARSED_ARGUMENTS)
206
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
209
if(NOT FPHSA_FAIL_MESSAGE)
210
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
214
# now that we collected all arguments, process them
216
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
217
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
220
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
221
# when it successfully found the config-file, including version checking:
222
if(FPHSA_CONFIG_MODE)
223
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
224
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
225
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
228
if(NOT FPHSA_REQUIRED_VARS)
229
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
232
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
234
string(TOUPPER ${_NAME} _NAME_UPPER)
235
string(TOLOWER ${_NAME} _NAME_LOWER)
238
if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
239
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
241
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
244
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
247
# collect all variables which were not found, so they can be printed, so the
248
# user knows better what went wrong (#6375)
251
# check if all passed variables are valid
252
set(FPHSA_FOUND_${_NAME} TRUE)
253
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
254
if(NOT ${_CURRENT_VAR})
255
set(FPHSA_FOUND_${_NAME} FALSE)
256
set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
258
set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
261
if(FPHSA_FOUND_${_NAME})
262
set(${_NAME}_FOUND TRUE)
263
set(${_NAME_UPPER}_FOUND TRUE)
265
set(${_NAME}_FOUND FALSE)
266
set(${_NAME_UPPER}_FOUND FALSE)
270
unset(FOUND_COMPONENTS_MSG)
271
unset(MISSING_COMPONENTS_MSG)
273
if(FPHSA_HANDLE_COMPONENTS)
274
foreach(comp ${${_NAME}_FIND_COMPONENTS})
275
if(${_NAME}_${comp}_FOUND)
277
if(NOT DEFINED FOUND_COMPONENTS_MSG)
278
set(FOUND_COMPONENTS_MSG "found components: ")
280
set(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}")
284
if(NOT DEFINED MISSING_COMPONENTS_MSG)
285
set(MISSING_COMPONENTS_MSG "missing components: ")
287
set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
289
if(${_NAME}_FIND_REQUIRED_${comp})
290
set(${_NAME}_FOUND FALSE)
291
set(MISSING_VARS "${MISSING_VARS} ${comp}")
296
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
297
set(DETAILS "${DETAILS}[c${COMPONENT_MSG}]")
303
set(VERSION ${${FPHSA_VERSION_VAR}})
305
# check with DEFINED here as the requested or found version may be "0"
306
if (DEFINED ${_NAME}_FIND_VERSION)
307
if(DEFINED ${FPHSA_VERSION_VAR})
309
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
310
# count the dots in the version string
311
string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${VERSION}")
312
# add one dot because there is one dot more than there are components
313
string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
314
if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
315
# Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
316
# is at most 4 here. Therefore a simple lookup table is used.
317
if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
318
set(_VERSION_REGEX "[^.]*")
319
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
320
set(_VERSION_REGEX "[^.]*\\.[^.]*")
321
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
322
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
324
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
326
string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${VERSION}")
327
unset(_VERSION_REGEX)
328
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
329
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
330
set(VERSION_OK FALSE)
332
set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
336
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL VERSION)
337
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
338
set(VERSION_OK FALSE)
340
set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
345
else() # minimum version specified:
346
if (${_NAME}_FIND_VERSION VERSION_GREATER VERSION)
347
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
348
set(VERSION_OK FALSE)
350
set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")")
356
# if the package was not found, but a version was given, add that to the output:
357
if(${_NAME}_FIND_VERSION_EXACT)
358
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
360
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
366
set(VERSION_MSG "(found version \"${VERSION}\")")
371
set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
373
set(${_NAME}_FOUND FALSE)
379
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
382
if(FPHSA_CONFIG_MODE)
383
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
386
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
388
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
394
set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
395
set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)