1*e25b118aSDominic Spill# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> ... ) 2*e25b118aSDominic Spill# 3*e25b118aSDominic Spill# This function is intended to be used in FindXXX.cmake modules files. 4*e25b118aSDominic Spill# It handles the REQUIRED, QUIET and version-related arguments to find_package(). 5*e25b118aSDominic Spill# It also sets the <UPPERCASED_NAME>_FOUND variable. 6*e25b118aSDominic Spill# The package is considered found if all variables <var1>... listed contain 7*e25b118aSDominic Spill# valid results, e.g. valid filepaths. 8*e25b118aSDominic Spill# 9*e25b118aSDominic Spill# There are two modes of this function. The first argument in both modes is 10*e25b118aSDominic Spill# the name of the Find-module where it is called (in original casing). 11*e25b118aSDominic Spill# 12*e25b118aSDominic Spill# The first simple mode looks like this: 13*e25b118aSDominic Spill# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> (DEFAULT_MSG|"Custom failure message") <var1>...<varN> ) 14*e25b118aSDominic Spill# If the variables <var1> to <varN> are all valid, then <UPPERCASED_NAME>_FOUND 15*e25b118aSDominic Spill# will be set to TRUE. 16*e25b118aSDominic Spill# If DEFAULT_MSG is given as second argument, then the function will generate 17*e25b118aSDominic Spill# itself useful success and error messages. You can also supply a custom error message 18*e25b118aSDominic Spill# for the failure case. This is not recommended. 19*e25b118aSDominic Spill# 20*e25b118aSDominic Spill# The second mode is more powerful and also supports version checking: 21*e25b118aSDominic Spill# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS <var1>...<varN>] 22*e25b118aSDominic Spill# [VERSION_VAR <versionvar>] 23*e25b118aSDominic Spill# [HANDLE_COMPONENTS] 24*e25b118aSDominic Spill# [CONFIG_MODE] 25*e25b118aSDominic Spill# [FAIL_MESSAGE "Custom failure message"] ) 26*e25b118aSDominic Spill# 27*e25b118aSDominic Spill# As above, if <var1> through <varN> are all valid, <UPPERCASED_NAME>_FOUND 28*e25b118aSDominic Spill# will be set to TRUE. 29*e25b118aSDominic Spill# After REQUIRED_VARS the variables which are required for this package are listed. 30*e25b118aSDominic Spill# Following VERSION_VAR the name of the variable can be specified which holds 31*e25b118aSDominic Spill# the version of the package which has been found. If this is done, this version 32*e25b118aSDominic Spill# will be checked against the (potentially) specified required version used 33*e25b118aSDominic Spill# in the find_package() call. The EXACT keyword is also handled. The default 34*e25b118aSDominic Spill# messages include information about the required version and the version 35*e25b118aSDominic Spill# which has been actually found, both if the version is ok or not. 36*e25b118aSDominic Spill# If the package supports components, use the HANDLE_COMPONENTS option to enable 37*e25b118aSDominic Spill# handling them. In this case, find_package_handle_standard_args() will report 38*e25b118aSDominic Spill# which components have been found and which are missing, and the <NAME>_FOUND 39*e25b118aSDominic Spill# variable will be set to FALSE if any of the required components (i.e. not the 40*e25b118aSDominic Spill# ones listed after OPTIONAL_COMPONENTS) are missing. 41*e25b118aSDominic Spill# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for 42*e25b118aSDominic Spill# a find_package(... NO_MODULE) call. In this case VERSION_VAR will be set 43*e25b118aSDominic Spill# to <NAME>_VERSION and the macro will automatically check whether the 44*e25b118aSDominic Spill# Config module was found. 45*e25b118aSDominic Spill# Via FAIL_MESSAGE a custom failure message can be specified, if this is not 46*e25b118aSDominic Spill# used, the default message will be displayed. 47*e25b118aSDominic Spill# 48*e25b118aSDominic Spill# Example for mode 1: 49*e25b118aSDominic Spill# 50*e25b118aSDominic Spill# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) 51*e25b118aSDominic Spill# 52*e25b118aSDominic Spill# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and 53*e25b118aSDominic Spill# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. 54*e25b118aSDominic Spill# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, 55*e25b118aSDominic Spill# independent whether QUIET was used or not. 56*e25b118aSDominic Spill# If it is found, success will be reported, including the content of <var1>. 57*e25b118aSDominic Spill# On repeated Cmake runs, the same message won't be printed again. 58*e25b118aSDominic Spill# 59*e25b118aSDominic Spill# Example for mode 2: 60*e25b118aSDominic Spill# 61*e25b118aSDominic Spill# FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE 62*e25b118aSDominic Spill# VERSION_VAR BISON_VERSION) 63*e25b118aSDominic Spill# In this case, BISON is considered to be found if the variable(s) listed 64*e25b118aSDominic Spill# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case. 65*e25b118aSDominic Spill# Also the version of BISON will be checked by using the version contained 66*e25b118aSDominic Spill# in BISON_VERSION. 67*e25b118aSDominic Spill# Since no FAIL_MESSAGE is given, the default messages will be printed. 68*e25b118aSDominic Spill# 69*e25b118aSDominic Spill# Another example for mode 2: 70*e25b118aSDominic Spill# 71*e25b118aSDominic Spill# find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) 72*e25b118aSDominic Spill# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4 CONFIG_MODE) 73*e25b118aSDominic Spill# In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4 NO_MODULE) 74*e25b118aSDominic Spill# and adds an additional search directory for automoc4. 75*e25b118aSDominic Spill# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper 76*e25b118aSDominic Spill# success/error message. 77*e25b118aSDominic Spill 78*e25b118aSDominic Spill#============================================================================= 79*e25b118aSDominic Spill# Copyright 2007-2009 Kitware, Inc. 80*e25b118aSDominic Spill# 81*e25b118aSDominic Spill# Distributed under the OSI-approved BSD License (the "License"); 82*e25b118aSDominic Spill# see accompanying file Copyright.txt for details. 83*e25b118aSDominic Spill# 84*e25b118aSDominic Spill# This software is distributed WITHOUT ANY WARRANTY; without even the 85*e25b118aSDominic Spill# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 86*e25b118aSDominic Spill# See the License for more information. 87*e25b118aSDominic Spill#============================================================================= 88*e25b118aSDominic Spill# (To distribute this file outside of CMake, substitute the full 89*e25b118aSDominic Spill# License text for the above reference.) 90*e25b118aSDominic Spill 91*e25b118aSDominic Spillinclude(FindPackageMessage) 92*e25b118aSDominic Spillinclude(CMakeParseArguments) 93*e25b118aSDominic Spill 94*e25b118aSDominic Spill# internal helper macro 95*e25b118aSDominic Spillmacro(_FPHSA_FAILURE_MESSAGE _msg) 96*e25b118aSDominic Spill if (${_NAME}_FIND_REQUIRED) 97*e25b118aSDominic Spill message(FATAL_ERROR "${_msg}") 98*e25b118aSDominic Spill else () 99*e25b118aSDominic Spill if (NOT ${_NAME}_FIND_QUIETLY) 100*e25b118aSDominic Spill message(STATUS "${_msg}") 101*e25b118aSDominic Spill endif () 102*e25b118aSDominic Spill endif () 103*e25b118aSDominic Spillendmacro() 104*e25b118aSDominic Spill 105*e25b118aSDominic Spill 106*e25b118aSDominic Spill# internal helper macro to generate the failure message when used in CONFIG_MODE: 107*e25b118aSDominic Spillmacro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) 108*e25b118aSDominic Spill # <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: 109*e25b118aSDominic Spill if(${_NAME}_CONFIG) 110*e25b118aSDominic Spill _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") 111*e25b118aSDominic Spill else() 112*e25b118aSDominic Spill # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. 113*e25b118aSDominic Spill # List them all in the error message: 114*e25b118aSDominic Spill if(${_NAME}_CONSIDERED_CONFIGS) 115*e25b118aSDominic Spill set(configsText "") 116*e25b118aSDominic Spill list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) 117*e25b118aSDominic Spill math(EXPR configsCount "${configsCount} - 1") 118*e25b118aSDominic Spill foreach(currentConfigIndex RANGE ${configsCount}) 119*e25b118aSDominic Spill list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) 120*e25b118aSDominic Spill list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) 121*e25b118aSDominic Spill set(configsText "${configsText} ${filename} (version ${version})\n") 122*e25b118aSDominic Spill endforeach() 123*e25b118aSDominic Spill if (${_NAME}_NOT_FOUND_MESSAGE) 124*e25b118aSDominic Spill set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") 125*e25b118aSDominic Spill endif() 126*e25b118aSDominic Spill _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") 127*e25b118aSDominic Spill 128*e25b118aSDominic Spill else() 129*e25b118aSDominic Spill # Simple case: No Config-file was found at all: 130*e25b118aSDominic Spill _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") 131*e25b118aSDominic Spill endif() 132*e25b118aSDominic Spill endif() 133*e25b118aSDominic Spillendmacro() 134*e25b118aSDominic Spill 135*e25b118aSDominic Spill 136*e25b118aSDominic Spillfunction(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) 137*e25b118aSDominic Spill 138*e25b118aSDominic Spill# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in 139*e25b118aSDominic Spill# new extended or in the "old" mode: 140*e25b118aSDominic Spill set(options CONFIG_MODE HANDLE_COMPONENTS) 141*e25b118aSDominic Spill set(oneValueArgs FAIL_MESSAGE VERSION_VAR) 142*e25b118aSDominic Spill set(multiValueArgs REQUIRED_VARS) 143*e25b118aSDominic Spill set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) 144*e25b118aSDominic Spill list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) 145*e25b118aSDominic Spill 146*e25b118aSDominic Spill if(${INDEX} EQUAL -1) 147*e25b118aSDominic Spill set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) 148*e25b118aSDominic Spill set(FPHSA_REQUIRED_VARS ${ARGN}) 149*e25b118aSDominic Spill set(FPHSA_VERSION_VAR) 150*e25b118aSDominic Spill else() 151*e25b118aSDominic Spill 152*e25b118aSDominic Spill CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) 153*e25b118aSDominic Spill 154*e25b118aSDominic Spill if(FPHSA_UNPARSED_ARGUMENTS) 155*e25b118aSDominic Spill message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") 156*e25b118aSDominic Spill endif() 157*e25b118aSDominic Spill 158*e25b118aSDominic Spill if(NOT FPHSA_FAIL_MESSAGE) 159*e25b118aSDominic Spill set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") 160*e25b118aSDominic Spill endif() 161*e25b118aSDominic Spill endif() 162*e25b118aSDominic Spill 163*e25b118aSDominic Spill# now that we collected all arguments, process them 164*e25b118aSDominic Spill 165*e25b118aSDominic Spill if("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") 166*e25b118aSDominic Spill set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") 167*e25b118aSDominic Spill endif() 168*e25b118aSDominic Spill 169*e25b118aSDominic Spill # In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package() 170*e25b118aSDominic Spill # when it successfully found the config-file, including version checking: 171*e25b118aSDominic Spill if(FPHSA_CONFIG_MODE) 172*e25b118aSDominic Spill list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) 173*e25b118aSDominic Spill list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) 174*e25b118aSDominic Spill set(FPHSA_VERSION_VAR ${_NAME}_VERSION) 175*e25b118aSDominic Spill endif() 176*e25b118aSDominic Spill 177*e25b118aSDominic Spill if(NOT FPHSA_REQUIRED_VARS) 178*e25b118aSDominic Spill message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") 179*e25b118aSDominic Spill endif() 180*e25b118aSDominic Spill 181*e25b118aSDominic Spill list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) 182*e25b118aSDominic Spill 183*e25b118aSDominic Spill string(TOUPPER ${_NAME} _NAME_UPPER) 184*e25b118aSDominic Spill string(TOLOWER ${_NAME} _NAME_LOWER) 185*e25b118aSDominic Spill 186*e25b118aSDominic Spill # collect all variables which were not found, so they can be printed, so the 187*e25b118aSDominic Spill # user knows better what went wrong (#6375) 188*e25b118aSDominic Spill set(MISSING_VARS "") 189*e25b118aSDominic Spill set(DETAILS "") 190*e25b118aSDominic Spill set(${_NAME_UPPER}_FOUND TRUE) 191*e25b118aSDominic Spill # check if all passed variables are valid 192*e25b118aSDominic Spill foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) 193*e25b118aSDominic Spill if(NOT ${_CURRENT_VAR}) 194*e25b118aSDominic Spill set(${_NAME_UPPER}_FOUND FALSE) 195*e25b118aSDominic Spill set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}") 196*e25b118aSDominic Spill else() 197*e25b118aSDominic Spill set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") 198*e25b118aSDominic Spill endif() 199*e25b118aSDominic Spill endforeach() 200*e25b118aSDominic Spill 201*e25b118aSDominic Spill # component handling 202*e25b118aSDominic Spill unset(FOUND_COMPONENTS_MSG) 203*e25b118aSDominic Spill unset(MISSING_COMPONENTS_MSG) 204*e25b118aSDominic Spill 205*e25b118aSDominic Spill if(FPHSA_HANDLE_COMPONENTS) 206*e25b118aSDominic Spill foreach(comp ${${_NAME}_FIND_COMPONENTS}) 207*e25b118aSDominic Spill if(${_NAME}_${comp}_FOUND) 208*e25b118aSDominic Spill 209*e25b118aSDominic Spill if(NOT DEFINED FOUND_COMPONENTS_MSG) 210*e25b118aSDominic Spill set(FOUND_COMPONENTS_MSG "found components: ") 211*e25b118aSDominic Spill endif() 212*e25b118aSDominic Spill set(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}") 213*e25b118aSDominic Spill 214*e25b118aSDominic Spill else() 215*e25b118aSDominic Spill 216*e25b118aSDominic Spill if(NOT DEFINED MISSING_COMPONENTS_MSG) 217*e25b118aSDominic Spill set(MISSING_COMPONENTS_MSG "missing components: ") 218*e25b118aSDominic Spill endif() 219*e25b118aSDominic Spill set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}") 220*e25b118aSDominic Spill 221*e25b118aSDominic Spill if(${_NAME}_FIND_REQUIRED_${comp}) 222*e25b118aSDominic Spill set(${_NAME_UPPER}_FOUND FALSE) 223*e25b118aSDominic Spill set(MISSING_VARS "${MISSING_VARS} ${comp}") 224*e25b118aSDominic Spill endif() 225*e25b118aSDominic Spill 226*e25b118aSDominic Spill endif() 227*e25b118aSDominic Spill endforeach() 228*e25b118aSDominic Spill set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") 229*e25b118aSDominic Spill set(DETAILS "${DETAILS}[c${COMPONENT_MSG}]") 230*e25b118aSDominic Spill endif() 231*e25b118aSDominic Spill 232*e25b118aSDominic Spill # version handling: 233*e25b118aSDominic Spill set(VERSION_MSG "") 234*e25b118aSDominic Spill set(VERSION_OK TRUE) 235*e25b118aSDominic Spill set(VERSION ${${FPHSA_VERSION_VAR}} ) 236*e25b118aSDominic Spill if (${_NAME}_FIND_VERSION) 237*e25b118aSDominic Spill 238*e25b118aSDominic Spill if(VERSION) 239*e25b118aSDominic Spill 240*e25b118aSDominic Spill if(${_NAME}_FIND_VERSION_EXACT) # exact version required 241*e25b118aSDominic Spill if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") 242*e25b118aSDominic Spill set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") 243*e25b118aSDominic Spill set(VERSION_OK FALSE) 244*e25b118aSDominic Spill else () 245*e25b118aSDominic Spill set(VERSION_MSG "(found suitable exact version \"${VERSION}\")") 246*e25b118aSDominic Spill endif () 247*e25b118aSDominic Spill 248*e25b118aSDominic Spill else() # minimum version specified: 249*e25b118aSDominic Spill if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") 250*e25b118aSDominic Spill set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") 251*e25b118aSDominic Spill set(VERSION_OK FALSE) 252*e25b118aSDominic Spill else () 253*e25b118aSDominic Spill set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") 254*e25b118aSDominic Spill endif () 255*e25b118aSDominic Spill endif() 256*e25b118aSDominic Spill 257*e25b118aSDominic Spill else() 258*e25b118aSDominic Spill 259*e25b118aSDominic Spill # if the package was not found, but a version was given, add that to the output: 260*e25b118aSDominic Spill if(${_NAME}_FIND_VERSION_EXACT) 261*e25b118aSDominic Spill set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") 262*e25b118aSDominic Spill else() 263*e25b118aSDominic Spill set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") 264*e25b118aSDominic Spill endif() 265*e25b118aSDominic Spill 266*e25b118aSDominic Spill endif() 267*e25b118aSDominic Spill else () 268*e25b118aSDominic Spill if(VERSION) 269*e25b118aSDominic Spill set(VERSION_MSG "(found version \"${VERSION}\")") 270*e25b118aSDominic Spill endif() 271*e25b118aSDominic Spill endif () 272*e25b118aSDominic Spill 273*e25b118aSDominic Spill if(VERSION_OK) 274*e25b118aSDominic Spill set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]") 275*e25b118aSDominic Spill else() 276*e25b118aSDominic Spill set(${_NAME_UPPER}_FOUND FALSE) 277*e25b118aSDominic Spill endif() 278*e25b118aSDominic Spill 279*e25b118aSDominic Spill 280*e25b118aSDominic Spill # print the result: 281*e25b118aSDominic Spill if (${_NAME_UPPER}_FOUND) 282*e25b118aSDominic Spill FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") 283*e25b118aSDominic Spill else () 284*e25b118aSDominic Spill 285*e25b118aSDominic Spill if(FPHSA_CONFIG_MODE) 286*e25b118aSDominic Spill _FPHSA_HANDLE_FAILURE_CONFIG_MODE() 287*e25b118aSDominic Spill else() 288*e25b118aSDominic Spill if(NOT VERSION_OK) 289*e25b118aSDominic Spill _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") 290*e25b118aSDominic Spill else() 291*e25b118aSDominic Spill _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}") 292*e25b118aSDominic Spill endif() 293*e25b118aSDominic Spill endif() 294*e25b118aSDominic Spill 295*e25b118aSDominic Spill endif () 296*e25b118aSDominic Spill 297*e25b118aSDominic Spill set(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE) 298*e25b118aSDominic Spill 299*e25b118aSDominic Spillendfunction() 300