[cmake-developers] Is GET_OPTION_VALUE() a good name ?
Alexander Neundorf
neundorf at kde.org
Mon Aug 9 17:27:04 EDT 2010
On Monday 09 August 2010, Alexander Neundorf wrote:
> On Monday 09 August 2010, Brad King wrote:
> > On 08/07/2010 03:41 PM, Alexander Neundorf wrote:
> > > # Call the function, if the keyword is present the value(s) following
> > > it will # be returned in _FAIL_MESSAFE/_VERSION_VAR/_REQUIRED_VARS:
> > > FPHSA_GET_OPTION_VALUE("FAIL_MESSAGE" _FAIL_MESSAGE ALL_ARGS _KEYWORDS
> > > FALSE) FPHSA_GET_OPTION_VALUE("VERSION_VAR" _VERSION_VAR ALL_ARGS
> > > _KEYWORDS FALSE) FPHSA_GET_OPTION_VALUE("REQUIRED_VARS" _REQUIRED_VARS
> > > ALL_ARGS _KEYWORDS TRUE)
> >
> > I think a better name would be something like
> > "cmake_get_keyword_argument".
>
> Ok.
>
> > This interface requires the same argument lists to be traversed many
> > times.
>
> Not completely.
> It stops when it has finished the arguments for one keyword and it also
> removes the stuff it consumed from the list, so the list gets shorter each
> call.
>
> > I think we should be using a macro like PARSE_ARGUMENTS from Boost's
> > CMake build system (see below). This is its interface documentation:
> >
> > # The PARSE_ARGUMENTS macro will take the arguments of another macro and
> > # define several variables. The first argument to PARSE_ARGUMENTS is a
> > # prefix to put on all variables it creates. The second argument is a
> > # list of names, and the third argument is a list of options. Both of
> > # these lists should be quoted. The rest of PARSE_ARGUMENTS are
> > # arguments from another macro to be parsed.
> > #
> > # PARSE_ARGUMENTS(prefix arg_names options arg1 arg2...)
>
> The last time I looked at some similar function (was it also in boost ?) it
> didn't seem powerful enough.
> I'll have a look.
Ok, attached you can find a CMakeParseArguments.cmake.
Docs are still missing.
The interface is similar to the one from boost, but not identical.
With this version you can specify options (no values following), single-value
arguments (0..1 value following) and multi-value arguments (0..n values
following).
This has the advantage that the function can also report the arguments which
it didn't know.
This is done in ${prefix}_UNPARSED_ARGUMENTS.
It runs once over ARGN, but the option and argument names have to checked on
each iteration, I think this can't be avoided (and is also the case in the
macro from Boost).
Alex
P.S.
Is this the current version:
http://calder.sdml.cs.kent.edu/trac/origin/browser/trunk/cmake/BoostUtils.cmake ?
It seems to have a bug, an option doesn't seem to terminate the collecting of
values of the previous argument (but I didn't test).
-------------- next part --------------
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
return()
endif()
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
set(${prefix}_${arg_name})
endforeach(arg_name)
foreach(option ${_optionNames})
set(${prefix}_${option} FALSE)
endforeach(option)
set(${prefix}_UNPARSED_ARGUMENTS)
set(insideValues FALSE)
set(currentArgName)
foreach(currentArg ${ARGN})
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
if(insideValues)
if("${insideValues}" STREQUAL "SINGLE")
set(${prefix}_${currentArgName} ${currentArg})
set(insideValues FALSE)
elseif("${insideValues}" STREQUAL "MULTI")
list(APPEND ${prefix}_${currentArgName} ${currentArg})
endif()
else(insideValues)
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
endif(insideValues)
else()
if(NOT ${optionIndex} EQUAL -1)
set(${prefix}_${currentArg} TRUE)
set(insideValues FALSE)
elseif(NOT ${singleArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "SINGLE")
elseif(NOT ${multiArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "MULTI")
endif()
endif()
endforeach(currentArg)
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
endforeach(arg_name)
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
-------------- next part --------------
cmake_minimum_required(VERSION 2.6)
include(CMakeParseArguments)
cmake_parse_arguments(FOO "APPEND;PREPEND" "FILENAME;WHAT;INFO" "NAMES;WORDS"
BLUB APPEND FILENAME foo.txt xyz WHAT INFO "This is info" NAMES a.txt b.txt c.txt)
macro(print_var _var)
message(STATUS "${_var} = \"${${_var}}\"")
endmacro(print_var _var)
print_var(FOO_APPEND)
print_var(FOO_PREPEND)
print_var(FOO_FILENAME)
print_var(FOO_WHAT)
print_var(FOO_INFO)
print_var(FOO_NAMES)
print_var(FOO_WORDS)
print_var(FOO_UNPARSED_ARGUMENTS)
More information about the cmake-developers
mailing list