Spaces:
Running
on
Zero
Running
on
Zero
File size: 14,804 Bytes
5f9d349 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# Copyright (C) 2020, Inria
# GRAPHDECO research group, https://team.inria.fr/graphdeco
# All rights reserved.
#
# This software is free for non-commercial, research and evaluation use
# under the terms of the LICENSE.md file.
#
# For inquiries contact [email protected] and/or [email protected]
if(NOT WIN32 OR __parse_arguments_multi_cmake_INCLUDED__)
return()
else()
set(__parse_arguments_multi_cmake_INCLUDED__ ON)
endif()
## This macro allow to process repeating multi value args from a given function which use cmake_parse_arguments module.
##
## cmake_parse_arguments multi args standard behavior:
## function(foo)
## cmake_parse_arguments(arg "" "" "MULTI" ${ARGN})
## foreach(item IN LISTS arg_MULTI)
## message(STATUS "${item}")
## endforeach()
## endfunction()
## foo(MULTI x y MULTI z w)
## The above code outputs 'z' and 'w'. It originally expected it to output all of 'x' 'y' 'z' 'w'.
##
## Using this macro inside a function which want to handle repeating multi args values
## will recursively iterate onto the multi tags list to process each sub list.
## It take as 1st argument the subTag flag to separate sub list from the main multi list.
## It take as 2nd argument the nameList of the main multi list (the multiValuesArgs from cmake_parse_arguments: here it is MULTI in the example)
## and that's why it is important that it should be a macro and not a function (to get access to external variable).
## Then you give the content of this list allowing to be processed by the macro.
##
## parse_arguments_multi macro call a parse_arguments_multi_function which do actually the process from the given sub-list.
## By default this function only print infos about what variables you are trying to pass/process (only verbose messages),
## but, by overloading this cmake function, you will be able to externalize the process of your multi argument list.
##
## Usage (into a function) :
## parse_arguments_multi(<multiArgsSubTag> <multiArgsList> <multiArgsListContent>
## [NEED_RESULTS <multiArgsListSize>] [EXTRAS_FLAGS <...> <...> ...]
## )
##
## Simple usage example [user point of view]:
## foo(MULTI
## SUB_MULTI x y
## SUB_MULTI z w
## )
##
## Simple usage example [inside a function]:
## function(foo)
## cmake_parse_arguments(arg "" "" "MULTI" ${ARGN})
## include(parse_arguments_multi)
## function(parse_arguments_multi_function )
## #message("I'm an overloaded cmake function used by parse_arguments_multi")
## #message("I'm processing first part of my sub list: ${ARGN}")
## message("ARGV0=${ARGV0}")
## message("ARGV1=${ARGV1}")
## endfunction()
## parse_arguments_multi(SUB_MULTI arg_MULTI ${arg_MULTI}) ## this function will process recusively items of the sub-list [default print messages]
## endfunction()
##
## Will print:
## ARGV0=z
## ARGV1=w
## ARGV0=x
## ARGV1=y
##
## WARNING : DO NEVER ADD EXTRA THINGS TO parse_arguments_multi MACRO :
## parse_arguments_multi(SUB_MULTI arg_MULTI ${arg_MULTI} EXTRAS foo bar SOMTHING) => will failed !!
## use EXTRAS_FLAGS instead !!
##
## Advanced usage example [user point of view]:
## bar(C:/prout/test.exe VERBOSE
## PLUGINS
## PLUGIN_PATH_NAME x PLUGIN_PATH_DEST w
## PLUGIN_PATH_NAME a b PLUGIN_PATH_DEST y
## PLUGIN_PATH_NAME c
## )
##
## Advanced usage example [inside a function]:
## function(bar execFilePathName)
## cmake_parse_arguments(arg "VERBOSE" "" "PLUGINS" ${ARGN})
##
## include(parse_arguments_multi)
## function(parse_arguments_multi_function results)
## cmake_parse_arguments(pamf "VERBOSE" "PLUGIN_PATH_DEST;EXEC_PATH" "" ${ARGN}) ## EXEC_PATH is for internal use
## message("")
## message("I'm an overloaded cmake function used by parse_arguments_multi from install_runtime function")
## message("I'm processing first part of my sub list: ${ARGN}")
## message("PLUGIN_PATH_NAME = ${pamf_UNPARSED_ARGUMENTS}")
## message(pamf_VERBOSE = ${pamf_VERBOSE})
## message("pamf_PLUGIN_PATH_DEST = ${pamf_PLUGIN_PATH_DEST}")
## message(pamf_EXEC_PATH = ${pamf_EXEC_PATH})
## if(NOT ${pamf_PLUGIN_PATH_DEST})
## set(pamf_PLUGIN_PATH_DEST ${pamf_EXEC_PATH})
## endif()
## foreach(plugin ${pamf_UNPARSED_ARGUMENTS})
## get_filename_component(pluginName ${plugin} NAME)
## list(APPEND pluginsList ${pamf_PLUGIN_PATH_DEST}/${pluginName})
## endforeach()
## set(${results} ${pluginsList} PARENT_SCOPE)
## endfunction()
##
## if(arg_VERBOSE)
## list(APPEND extra_flags_to_add VERBOSE) ## here we transmit the VERNOSE flag
## endif()
## get_filename_component(EXEC_PATH ${execFilePathName} PATH) ## will be the default value if PLUGIN_PATH_DEST option is not provided
## list(APPEND extra_flags_to_add EXEC_PATH ${EXEC_PATH})
## list(LENGTH arg_PLUGINS arg_PLUGINS_count)
## parse_arguments_multi(PLUGIN_PATH_NAME arg_PLUGINS ${arg_PLUGINS}
## NEED_RESULTS ${arg_PLUGINS_count} ## this is used to check when we are in the first loop (in order to reset parse_arguments_multi_results)
## EXTRAS_FLAGS ${extra_flags_to_add} ## this is used to allow catching VERBOSE and PLUGIN_PATH_DEST flags of our overloaded function
## )
## endfunction()
## message(parse_arguments_multi_results = ${parse_arguments_multi_results}) ## list of the whole pluginsList
## #Will print w/x;a/y;b/y;C:/prout/c
##
## NOTE that here, since our overloaded function need to provide a result list, we use the other parse_arguments_multi_function signature (the which one with a results arg)
##
function(parse_arguments_multi_function_default) ## used in case of you want to reset the default behavior of this function process
message("[default function] parse_arguments_multi_function(ARGC=${ARGC} ARGV=${ARGV} ARGN=${ARGN})")
message("This function is used by parse_arguments_multi and have to be overloaded to process sub list of multi values args")
endfunction()
function(parse_arguments_multi_function ) ## => the function to overload
parse_arguments_multi_function_default(${ARGN})
endfunction()
## first default signature above
##------------------------------
## second results signature behind
function(parse_arguments_multi_function_default result) ## used in case of you want to reset the default behavior of this function process
message("[default function] parse_arguments_multi_function(ARGC=${ARGC} ARGV=${ARGV} ARGN=${ARGN})")
message("This function is used by parse_arguments_multi and have to be overloaded to process sub list of muluti values args")
endfunction()
function(parse_arguments_multi_function result) ## => the function to overload
parse_arguments_multi_function_default(result ${ARGN})
endfunction()
## => the macro to use inside your function which use cmake_parse_arguments
# NOTE: entry point of parse_arguments_multi, which is called from win3rdPart)
macro(parse_arguments_multi multiArgsSubTag multiArgsList #<${multiArgsList}> the content of the list
)
# message (STATUS "")
# message(STATUS "calling parse_arguemnts_multi defined in parse_arguments_multi.cmake:141")
# message(STATUS "multiArgsSubTag = ${multiArgsSubTag}") # CHECK_CACHED_VAR
# message(STATUS "multiArgsList = ${multiArgsList}") # it contains the name of the variable which is holding the list i.e w3p_MULTI_SET
# message(STATUS "value of ${multiArgsList} = ${${multiArgsList}}") # a semicolon separated list of values passed to SET or MULTISET keyword in win3rdParty
# message(STATUS "actual values ARGN = ${ARGN}") # the same as ${${multiArgsList}}
## INFO
## starting from CMake 3.5 cmake_parse_arguments is not a module anymore and now is a native CMake command.
## the behaviour is different though
## In CMake 3.4, if you pass multiple times a multi_value_keyword, CMake returns the values of the LAST match
## In CMake 3.5 and above, CMake returns the whole list of values that were following that multi_value_keyword
## example:
## cmake_parse_arguments(
## <prefix>
## "" # options
## "" # one value keywords
## "MY_MULTI_VALUE_TAG"
## MY_MULTI_VALUE_TAG value1 value2
## MY_MULTI_VALUE_TAG value3 value4
## MY_MULTI_VALUE_TAG value5 value6
## )
## result in CMake 3.4
## <prefix>_MY_MULTI_VALUE_TAG = "value5;value6"
##
## result in CMake 3.8
## <prefix>_MY_MULTI_VALUE_TAG = "value5;value6"
#include(CMakeParseArguments) #module CMakeParseArguments is obsolete since cmake 3.5
# cmake_parse_arguments (<prefix> <options> <one_value_keywords> <multi_value_keywords> args)
# <options> : options (flags) pass to the macro
# <one_value_keywords> : options that neeed a value
# <multi_value_keywords> : options that neeed more than one value
cmake_parse_arguments(_pam "" "NEED_RESULTS" "${multiArgsSubTag};EXTRAS_FLAGS" ${ARGN})
## multiArgsList is the name of the list used by the multiValuesOption flag from the cmake_parse_arguments of the user function
## that's why we absolutly need to use MACRO here (and also for passing parse_arguments_multi_results when NEED_RESULTS flag is set)
## for debugging
#message("")
#message("[parse_arguments_multi] => ARGN = ${ARGN}")
#message("_pam_NEED_RESULTS=${_pam_NEED_RESULTS}")
#message("_pam_EXTRAS_FLAGS=${_pam_EXTRAS_FLAGS}")
# foreach(var ${_pam_${multiArgsSubTag}})
# message("arg=${var}")
# endforeach()
if (${CMAKE_VERSION} VERSION_GREATER "3.5")
# lets make ${_pam_${multiArgsSubTag}} behave as it is in version 3.4
# that means, cmake_parse_arguments should have only the last values of a multi set for a given keyword
# message("")
# message("values in multiArgsList")
# foreach(val ${${multiArgsList}})
# message(STATUS ${val})
# endforeach()
# message("end values in multiArgsList")
set(lastIndexFound OFF)
list(LENGTH ${multiArgsList} argnLength)
# message(${argnLength})
math(EXPR argnLength "${argnLength}-1") # make last index a valid one
set(recordIndex 0)
set(records "") # clear records list
set(record0 "") # clear first record list
foreach(iter RANGE ${argnLength})
list(GET ${multiArgsList} ${iter} value)
# message(STATUS "index=${iter} value=${value}")
if (${value} STREQUAL ${multiArgsSubTag})
if (lastIndexFound)
list(APPEND records ${recordIndex}) # records store the list NAMES
math(EXPR recordIndex "${recordIndex}+1")
set(record${recordIndex} "") # clear record list
else ()
set(lastIndexFound ON)
endif()
set(lastIndex ${iter})
else ()
if (lastIndexFound)
# message(${value})
list(APPEND record${recordIndex} ${value})
endif()
endif()
endforeach()
# save the last list of values
if (lastIndexFound)
list(APPEND records ${recordIndex}) # records store the list NAMES
endif()
# set multiArgsList to make it behave like CMake 3.4
# message("")
# message("using my records")
foreach(recordName ${records})
# message(${recordName})
# foreach(value ${record${recordName}})
# message(${value})
# endforeach()
# message("")
set(_pam_${multiArgsSubTag} ${record${recordName}})
endforeach()
# message(${_pam_${multiArgsSubTag}})
# message("")
# message("using argn")
# foreach(value ${ARGN})
# message(${value})
# endforeach()
endif() # end if cmake > 3.5
# message("values with pam ${_pam_${multiArgsSubTag}}")
## check and init
list(LENGTH ${multiArgsList} globalListCount) # GLUT_TRACE: globalListCound=16 in CMake3.4 and CMake3.8
# message(STATUS "nr items in multiArgsList: ${globalListCount}")
math(EXPR globalListCount "${globalListCount}-1") ## because it will contain [multiArgsSubTag + ${multiArgsList}]
if(_pam_NEED_RESULTS)
if(${globalListCount} EQUAL ${_pam_NEED_RESULTS})
## first time we enter into this macro (because we call it recursively)
unset(parse_arguments_multi_results)
endif()
endif()
## process the part of the multi agrs list
## ${ARGN} shouldn't be passed to the function in order to avoid missmatch size list ${multiArgsList} and _pam_${multiArgsSubTag}
## if you want to pass extra internal flags from your function to this callback, use EXTRAS_FLAGS
if(_pam_NEED_RESULTS)
parse_arguments_multi_function(parse_arguments_multi_function_result ${_pam_${multiArgsSubTag}} ${_pam_EXTRAS_FLAGS})
list(APPEND parse_arguments_multi_results ${parse_arguments_multi_function_result})
else()
# message(STATUS "about to call parse_arguments_multi_function in parse_arguments_multi.cmake:177 ${_pam_${multiArgsSubTag}} and extra flags ${_pam_EXTRAS_FLAGS}")
parse_arguments_multi_function(${_pam_${multiArgsSubTag}} ${_pam_EXTRAS_FLAGS})
endif()
## remove just processed items from the main list to process (multiArgsList)
list(REVERSE ${multiArgsList})
list(LENGTH _pam_${multiArgsSubTag} subTagListCount)
unset(ids)
foreach(id RANGE ${subTagListCount})
list(APPEND ids ${id})
endforeach()
list(REMOVE_AT ${multiArgsList} ${ids})
list(REVERSE ${multiArgsList})
## test if remain sub multi list to process (recursive call) or finish the process
list(LENGTH ${multiArgsList} mainTagListCount)
if(${mainTagListCount} GREATER 1)
## do not pass ${ARGN} just because it will re pass the initial 2 inputs args and we wont as they was consumed (in order to avoir conflicts)
# message(STATUS "about to call a parse_arguments_multi but without knowing where the definition is going to be taken from")
parse_arguments_multi(${multiArgsSubTag} ${multiArgsList} ${${multiArgsList}}
NEED_RESULTS ${_pam_NEED_RESULTS} EXTRAS_FLAGS ${_pam_EXTRAS_FLAGS}
)
endif()
endmacro()
|