1# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...) 2# 3# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for 4# parsing the arguments given to that macro or function. 5# It processes the arguments and defines a set of variables which hold the 6# values of the respective options. 7# 8# The <options> argument contains all options for the respective macro, 9# i.e. keywords which can be used when calling the macro without any value 10# following, like e.g. the OPTIONAL keyword of the install() command. 11# 12# The <one_value_keywords> argument contains all keywords for this macro 13# which are followed by one value, like e.g. DESTINATION keyword of the 14# install() command. 15# 16# The <multi_value_keywords> argument contains all keywords for this macro 17# which can be followed by more than one value, like e.g. the TARGETS or 18# FILES keywords of the install() command. 19# 20# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the 21# keywords listed in <options>, <one_value_keywords> and 22# <multi_value_keywords> a variable composed of the given <prefix> 23# followed by "_" and the name of the respective keyword. 24# These variables will then hold the respective value from the argument list. 25# For the <options> keywords this will be TRUE or FALSE. 26# 27# All remaining arguments are collected in a variable 28# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see whether 29# your macro was called with unrecognized parameters. 30# 31# As an example here a my_install() macro, which takes similar arguments as the 32# real install() command: 33# 34# function(MY_INSTALL) 35# set(options OPTIONAL FAST) 36# set(oneValueArgs DESTINATION RENAME) 37# set(multiValueArgs TARGETS CONFIGURATIONS) 38# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) 39# ... 40# 41# Assume my_install() has been called like this: 42# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) 43# 44# After the cmake_parse_arguments() call the macro will have set the following 45# variables: 46# MY_INSTALL_OPTIONAL = TRUE 47# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() 48# MY_INSTALL_DESTINATION = "bin" 49# MY_INSTALL_RENAME = "" (was not used) 50# MY_INSTALL_TARGETS = "foo;bar" 51# MY_INSTALL_CONFIGURATIONS = "" (was not used) 52# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" 53# 54# You can the continue and process these variables. 55# 56# Keywords terminate lists of values, e.g. if directly after a one_value_keyword 57# another recognized keyword follows, this is interpreted as the beginning of 58# the new option. 59# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in 60# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would 61# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. 62 63#============================================================================= 64# Copyright 2010 Alexander Neundorf <[email protected]> 65# 66# Distributed under the OSI-approved BSD License (the "License"); 67# see accompanying file Copyright.txt for details. 68# 69# This software is distributed WITHOUT ANY WARRANTY; without even the 70# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 71# See the License for more information. 72#============================================================================= 73# (To distribute this file outside of CMake, substitute the full 74# License text for the above reference.) 75 76 77if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) 78 return() 79endif() 80set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) 81 82 83function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) 84 # first set all result variables to empty/FALSE 85 foreach(arg_name ${_singleArgNames} ${_multiArgNames}) 86 set(${prefix}_${arg_name}) 87 endforeach() 88 89 foreach(option ${_optionNames}) 90 set(${prefix}_${option} FALSE) 91 endforeach() 92 93 set(${prefix}_UNPARSED_ARGUMENTS) 94 95 set(insideValues FALSE) 96 set(currentArgName) 97 98 # now iterate over all arguments and fill the result variables 99 foreach(currentArg ${ARGN}) 100 list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword 101 list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword 102 list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword 103 104 if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) 105 if(insideValues) 106 if("${insideValues}" STREQUAL "SINGLE") 107 set(${prefix}_${currentArgName} ${currentArg}) 108 set(insideValues FALSE) 109 elseif("${insideValues}" STREQUAL "MULTI") 110 list(APPEND ${prefix}_${currentArgName} ${currentArg}) 111 endif() 112 else() 113 list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) 114 endif() 115 else() 116 if(NOT ${optionIndex} EQUAL -1) 117 set(${prefix}_${currentArg} TRUE) 118 set(insideValues FALSE) 119 elseif(NOT ${singleArgIndex} EQUAL -1) 120 set(currentArgName ${currentArg}) 121 set(${prefix}_${currentArgName}) 122 set(insideValues "SINGLE") 123 elseif(NOT ${multiArgIndex} EQUAL -1) 124 set(currentArgName ${currentArg}) 125 set(${prefix}_${currentArgName}) 126 set(insideValues "MULTI") 127 endif() 128 endif() 129 130 endforeach() 131 132 # propagate the result variables to the caller: 133 foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) 134 set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) 135 endforeach() 136 set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) 137 138endfunction() 139