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: 5FindPackageHandleStandardArgs 6----------------------------- 7 8This module provides functions intended to be used in :ref:`Find Modules` 9implementing :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 120Example 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 127The ``LibXml2`` package is considered to be found if both 128``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. 129Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found 130and ``REQUIRED`` was used, it fails with a 131:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was 132used or not. If it is found, success will be reported, including 133the content of the first ``<required-var>``. On repeated CMake runs, 134the 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 147Example 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 155In this case, the ``LibArchive`` package is considered to be found if 156both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. 157Also the version of ``LibArchive`` will be checked by using the version 158contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, 159the default messages will be printed. 160 161Another 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 168In this case, a ``FindAutmoc4.cmake`` module wraps a call to 169``find_package(Automoc4 NO_MODULE)`` and adds an additional search 170directory for ``automoc4``. Then the call to 171``find_package_handle_standard_args`` produces a proper success/failure 172message. 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 200Example 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 213include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) 214 215 216cmake_policy(PUSH) 217# numbers and boolean constants 218cmake_policy (SET CMP0012 NEW) 219# IN_LIST operator 220cmake_policy (SET CMP0057 NEW) 221 222 223# internal helper macro 224macro(_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 () 236endmacro() 237 238 239# internal helper macro to generate the failure message when used in CONFIG_MODE: 240macro(_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() 272endmacro() 273 274 275function(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() 372endfunction() 373 374 375function(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 with DEFINED here as the requested or found version may be "0" 539 if (DEFINED ${_NAME}_FIND_VERSION) 540 if(DEFINED ${FPHSA_VERSION_VAR}) 541 set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) 542 if (FPHSA_HANDLE_VERSION_RANGE) 543 set (FPCV_HANDLE_VERSION_RANGE HANDLE_VERSION_RANGE) 544 else() 545 set(FPCV_HANDLE_VERSION_RANGE NO_AUTHOR_WARNING_VERSION_RANGE) 546 endif() 547 find_package_check_version ("${_FOUND_VERSION}" VERSION_OK RESULT_MESSAGE_VARIABLE VERSION_MSG 548 ${FPCV_HANDLE_VERSION_RANGE}) 549 else() 550 # if the package was not found, but a version was given, add that to the output: 551 if(${_NAME}_FIND_VERSION_EXACT) 552 set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") 553 elseif (FPHSA_HANDLE_VERSION_RANGE AND ${_NAME}_FIND_VERSION_RANGE) 554 set(VERSION_MSG "(Required is version range \"${${_NAME}_FIND_VERSION_RANGE}\")") 555 else() 556 set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") 557 endif() 558 endif() 559 else () 560 # Check with DEFINED as the found version may be 0. 561 if(DEFINED ${FPHSA_VERSION_VAR}) 562 set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") 563 endif() 564 endif () 565 566 if(VERSION_OK) 567 string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") 568 else() 569 set(${_NAME}_FOUND FALSE) 570 endif() 571 572 573 # print the result: 574 if (${_NAME}_FOUND) 575 FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") 576 else () 577 578 if(FPHSA_CONFIG_MODE) 579 _FPHSA_HANDLE_FAILURE_CONFIG_MODE() 580 else() 581 if(NOT VERSION_OK) 582 set(RESULT_MSG) 583 if (_FIRST_REQUIRED_VAR) 584 string (APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}") 585 endif() 586 if (COMPONENT_MSG) 587 if (RESULT_MSG) 588 string (APPEND RESULT_MSG ", ") 589 endif() 590 string (APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}") 591 endif() 592 _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (${RESULT_MSG})") 593 else() 594 _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") 595 endif() 596 endif() 597 598 endif () 599 600 set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) 601 set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) 602endfunction() 603 604 605cmake_policy(POP) 606