|
|
**CAUTION: The contents of this page may be obsolete**
|
|
|
![120px-Old_finnish_stop_sign.svg](/uploads/521180f925eeefd545a3a7a761185c2e/120px-Old_finnish_stop_sign.svg.png)
|
|
|
|
|
|
----
|
|
|
|
|
|
[Back](CMake_User_Contributed_Macros "wikilink")
|
|
|
|
|
|
## Definition
|
|
|
|
|
|
There is a general convention for CMake commands that take optional
|
|
|
flags and/or variable arguments. Optional flags are all caps and are
|
|
|
added to the arguments to turn on. Variable arguments have an all caps
|
|
|
identifier to determine where each variable argument list starts.
|
|
|
|
|
|
If you are using CMake 2.8.3 or newer please use the
|
|
|
[CMakeParseArguments](http://www.cmake.org/cmake/help/v2.8.9/cmake.html#module:CMakeParseArguments)
|
|
|
macro provided by the default CMake installation instead of the code
|
|
|
below.
|
|
|
|
|
|
The PARSE_ARGUMENTS macro, defined below, can be used by other macros
|
|
|
to parse arguments defined in this way. Note that this macro relies on
|
|
|
the [LIST_CONTAINS](CMakeMacroListOperations#LIST_CONTAINS "wikilink")
|
|
|
command.
|
|
|
|
|
|
MACRO(PARSE_ARGUMENTS prefix arg_names option_names)
|
|
|
SET(DEFAULT_ARGS)
|
|
|
FOREACH(arg_name ${arg_names})
|
|
|
SET(${prefix}_${arg_name})
|
|
|
ENDFOREACH(arg_name)
|
|
|
FOREACH(option ${option_names})
|
|
|
SET(${prefix}_${option} FALSE)
|
|
|
ENDFOREACH(option)
|
|
|
|
|
|
SET(current_arg_name DEFAULT_ARGS)
|
|
|
SET(current_arg_list)
|
|
|
FOREACH(arg ${ARGN})
|
|
|
LIST_CONTAINS(is_arg_name ${arg} ${arg_names})
|
|
|
IF (is_arg_name)
|
|
|
SET(${prefix}_${current_arg_name} ${current_arg_list})
|
|
|
SET(current_arg_name ${arg})
|
|
|
SET(current_arg_list)
|
|
|
ELSE (is_arg_name)
|
|
|
LIST_CONTAINS(is_option ${arg} ${option_names})
|
|
|
IF (is_option)
|
|
|
SET(${prefix}_${arg} TRUE)
|
|
|
ELSE (is_option)
|
|
|
SET(current_arg_list ${current_arg_list} ${arg})
|
|
|
ENDIF (is_option)
|
|
|
ENDIF (is_arg_name)
|
|
|
ENDFOREACH(arg)
|
|
|
SET(${prefix}_${current_arg_name} ${current_arg_list})
|
|
|
ENDMACRO(PARSE_ARGUMENTS)
|
|
|
|
|
|
If you are using CMake version greater than 2.4.7 you may use the
|
|
|
following version which use LIST builtin command FIND which may be more
|
|
|
efficient:
|
|
|
|
|
|
MACRO(PARSE_ARGUMENTS prefix arg_names option_names)
|
|
|
SET(DEFAULT_ARGS)
|
|
|
FOREACH(arg_name ${arg_names})
|
|
|
SET(${prefix}_${arg_name})
|
|
|
ENDFOREACH(arg_name)
|
|
|
FOREACH(option ${option_names})
|
|
|
SET(${prefix}_${option} FALSE)
|
|
|
ENDFOREACH(option)
|
|
|
|
|
|
SET(current_arg_name DEFAULT_ARGS)
|
|
|
SET(current_arg_list)
|
|
|
FOREACH(arg ${ARGN})
|
|
|
SET(larg_names ${arg_names})
|
|
|
LIST(FIND larg_names "${arg}" is_arg_name)
|
|
|
IF (is_arg_name GREATER -1)
|
|
|
SET(${prefix}_${current_arg_name} ${current_arg_list})
|
|
|
SET(current_arg_name ${arg})
|
|
|
SET(current_arg_list)
|
|
|
ELSE (is_arg_name GREATER -1)
|
|
|
SET(loption_names ${option_names})
|
|
|
LIST(FIND loption_names "${arg}" is_option)
|
|
|
IF (is_option GREATER -1)
|
|
|
SET(${prefix}_${arg} TRUE)
|
|
|
ELSE (is_option GREATER -1)
|
|
|
SET(current_arg_list ${current_arg_list} ${arg})
|
|
|
ENDIF (is_option GREATER -1)
|
|
|
ENDIF (is_arg_name GREATER -1)
|
|
|
ENDFOREACH(arg)
|
|
|
SET(${prefix}_${current_arg_name} ${current_arg_list})
|
|
|
ENDMACRO(PARSE_ARGUMENTS)
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
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.
|
|
|
|
|
|
<tt>
|
|
|
|
|
|
-
|
|
|
PARSE_ARGUMENTS(*prefix* *arg_names* *options* *arg1* *arg2*...)
|
|
|
|
|
|
</tt>
|
|
|
|
|
|
For each item in *options*, PARSE_ARGUMENTS will create a variable with
|
|
|
that name, prefixed with *`prefix`*`_`. So, for example, if *prefix* is
|
|
|
`MY_MACRO` and *options* is `OPTION1;OPTION2`, then PARSE_ARGUMENTS
|
|
|
will create the variables MY_MACRO_OPTION1 and MY_MACRO_OPTION2.
|
|
|
These variables will be set to true if the option exists in the command
|
|
|
line or false otherwise.
|
|
|
|
|
|
For each item in *arg_names*, PARSE_ARGUMENTS will create a variable
|
|
|
with that name, prefixed with *`prefix`*`_`. Each variable will be
|
|
|
filled with the arguments that occur after the given arg_name is
|
|
|
encountered up to the next arg_name or the end of the arguments. All
|
|
|
options are removed from these lists. PARSE_ARGUMENTS also creates a
|
|
|
*`prefix`*`_DEFAULT_ARGS` variable containing the list of all arguments
|
|
|
up to the first arg_name encountered.
|
|
|
|
|
|
Here is a simple, albeit impractical, example of using PARSE_ARGUMENTS
|
|
|
that demonstrates its behavior.
|
|
|
|
|
|
SET(arguments
|
|
|
hello OPTION3 world
|
|
|
LIST3 foo bar
|
|
|
OPTION2
|
|
|
LIST1 fuz baz
|
|
|
)
|
|
|
PARSE_ARGUMENTS(ARG "LIST1;LIST2;LIST3" "OPTION1;OPTION2;OPTION3" ${arguments})
|
|
|
|
|
|
PARSE_ARGUMENTS creates 7 variables and sets them as follows:
|
|
|
|
|
|
- `ARG_DEFAULT_ARGS`: `hello;world`
|
|
|
- `ARG_LIST1`: `fuz;baz`
|
|
|
- `ARG_LIST2`:
|
|
|
- `ARG_LIST3`: `foo;bar`
|
|
|
- `ARG_OPTION1`: `FALSE`
|
|
|
- `ARG_OPTION2`: `TRUE`
|
|
|
- `ARG_OPTION3`: `TRUE`
|
|
|
|
|
|
If you don't have any options, use an empty string in its place.
|
|
|
|
|
|
PARSE_ARGUMENTS(ARG "LIST1;LIST2;LIST3" "" ${arguments})
|
|
|
|
|
|
Likewise if you have no lists.
|
|
|
|
|
|
PARSE_ARGUMENTS(ARG "" "OPTION1;OPTION2;OPTION3" ${arguments})
|
|
|
|
|
|
## Example
|
|
|
|
|
|
Here is a somewhat more realistic usage of `PARSE_ARGUMENTS`. Let us say
|
|
|
that we are creating an application that accepts plugins with
|
|
|
components, and we need a CMake macro that makes it easy to compile and
|
|
|
link a plugin. The plugin will have some code in it, and it will have to
|
|
|
have some sort of factory built in that allows the introspection and
|
|
|
creation of components in the plugin. We also may want to embed some
|
|
|
scripts in the plugin. The plugin may depend on other libraries and
|
|
|
plugins. Finally, we may have some options to determine how the plugin
|
|
|
may be compiled or used. We will create a macro command that can be
|
|
|
called as follows.
|
|
|
|
|
|
ADD_PLUGIN(name [AUTO_INSTALL] [NO_MODULE] source1 source2 ...
|
|
|
EXPORTS object1 object2 ...
|
|
|
[AUTOLOAD_SCRIPTS script1 script2 ...]
|
|
|
[LINK_LIBRARIES lib1 lib2 ...]
|
|
|
[DEPENDS plugin1 plugin2 ...]
|
|
|
)
|
|
|
|
|
|
Although the argument usage is easy for a user to understand (especially
|
|
|
one familiar with using other CMake commands), but it can be a hassle
|
|
|
for a macro to parse. Of course, `PARSE_ARGUMENTS` will do it for us.
|
|
|
|
|
|
Here is a vacuous implementation of `ADD_PLUGIN`. It uses
|
|
|
`PARSE_ARGUMENTS` to parse the argument specification above, and then
|
|
|
simply prints out each argument list and option. Note that this example
|
|
|
uses the [CAR and CDR](CMakeMacroListOperations#CAR_and_CDR "wikilink")
|
|
|
macros.
|
|
|
|
|
|
MACRO(ADD_PLUGIN)
|
|
|
PARSE_ARGUMENTS(PLUGIN
|
|
|
"EXPORTS;AUTOLOAD_SCRIPTS;LINK_LIBRARIES;DEPENDS"
|
|
|
"AUTO_INSTALL;NO_MODULE"
|
|
|
${ARGN}
|
|
|
)
|
|
|
CAR(PLUGIN_NAME ${PLUGIN_DEFAULT_ARGS})
|
|
|
CDR(PLUGIN_SOURCES ${PLUGIN_DEFAULT_ARGS})
|
|
|
|
|
|
MESSAGE("*** Arguments for ${PLUGIN_NAME}")
|
|
|
MESSAGE("Sources: ${PLUGIN_SOURCES}")
|
|
|
MESSAGE("Exports: ${PLUGIN_EXPORTS}")
|
|
|
MESSAGE("Autoload scripts: ${PLUGIN_AUTOLOAD_SCRIPTS}")
|
|
|
MESSAGE("Link libraries: ${PLUGIN_LINK_LIBRARIES}")
|
|
|
MESSAGE("Depends: ${PLUGIN_DEPENDS}")
|
|
|
IF (PLUGIN_AUTO_INSTALL)
|
|
|
MESSAGE("Auto install")
|
|
|
ENDIF (PLUGIN_AUTO_INSTALL)
|
|
|
IF (PLUGIN_NO_MODULE)
|
|
|
MESSAGE("No module")
|
|
|
ENDIF (PLUGIN_NO_MODULE)
|
|
|
ENDMACRO(ADD_PLUGIN)
|
|
|
|
|
|
Here are some examples of using this macro so you can see how
|
|
|
`PARSE_ARGUMENTS` breaks up the arguments.
|
|
|
|
|
|
<table>
|
|
|
<thead>
|
|
|
<tr class="header">
|
|
|
<th><p>Input</p></th>
|
|
|
<th><p>Output</p></th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr class="odd">
|
|
|
<td><pre><code>ADD_PLUGIN(MyAppCore NO_MODULE
|
|
|
CoreSource1.cxx CoreSource2.cxx
|
|
|
EXPORTS RequiredObject1 RequredObject2
|
|
|
AUTOLOAD_SCRIPTS startup.py initialize.py
|
|
|
)</code></pre></td>
|
|
|
<td><pre><code>*** Arguments for MyAppCore
|
|
|
Sources: CoreSource1.cxx;CoreSource2.cxx
|
|
|
Exports: RequiredObject1;RequredObject2
|
|
|
Autoload scripts: startup.py;initialize.py
|
|
|
Link libraries:
|
|
|
Depends:
|
|
|
No module</code></pre></td>
|
|
|
</tr>
|
|
|
<tr class="even">
|
|
|
<td><pre><code>ADD_PLUGIN(MyAppDefaultComponents
|
|
|
Component1.cxx Component2.cxx
|
|
|
EXPORTS Component1 Component2
|
|
|
DEPENDS MyAppCore
|
|
|
AUTO_INSTALL
|
|
|
)</code></pre></td>
|
|
|
<td><pre><code>*** Arguments for MyAppDefaultComponents
|
|
|
Sources: Component1.cxx;Component2.cxx
|
|
|
Exports: Component1;Component2
|
|
|
Autoload scripts:
|
|
|
Link libraries:
|
|
|
Depends: MyAppCore
|
|
|
Auto install</code></pre></td>
|
|
|
</tr>
|
|
|
<tr class="odd">
|
|
|
<td><pre><code>ADD_PLUGIN(PartialDiffEqu
|
|
|
Solver.cxx
|
|
|
DEPENDS MyAppCore MyAppDefaultComponents
|
|
|
LINK_LIBRARIES NumericalAnalysisPackage
|
|
|
EXPORTS SolverObject
|
|
|
)</code></pre></td>
|
|
|
<td><pre><code>*** Arguments for PartialDiffEqu
|
|
|
Sources: Solver.cxx
|
|
|
Exports: SolverObject
|
|
|
Autoload scripts:
|
|
|
Link libraries: NumericalAnalysisPackage
|
|
|
Depends: MyAppCore;MyAppDefaultComponents</code></pre></td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
|
|
|
-----
|
|
|
|
|
|
[Back](CMake_User_Contributed_Macros "wikilink")
|
|
|
|
|
|
|
|
|
----
|
|
|
This page was initially populated by conversion from its [original location](https://public.kitware.com/Wiki/CMakeMacroParseArguments) in another wiki. |