Merge topic 'CMakeParseArguments-native-impl'

ab8a2808 cmake_parse_arguments: consider duplicate keyword as warning
e8b14831 CMakeParseArguments: replace by native cmake_parse_arguments command
cbbdfc2b CMakeParseArguments: add a RunCMake test suite
This commit is contained in:
Brad King 2015-12-18 10:12:35 -05:00 committed by CMake Topic Stage
commit 4395190cd4
18 changed files with 561 additions and 144 deletions

View File

@ -0,0 +1,85 @@
cmake_parse_arguments
---------------------
``cmake_parse_arguments`` is intended to be used in macros or functions for
parsing the arguments given to that macro or function. It processes the
arguments and defines a set of variables which hold the values of the
respective options.
::
cmake_parse_arguments(<prefix> <options> <one_value_keywords>
<multi_value_keywords> args...)
The ``<options>`` argument contains all options for the respective macro,
i.e. keywords which can be used when calling the macro without any value
following, like e.g. the ``OPTIONAL`` keyword of the :command:`install`
command.
The ``<one_value_keywords>`` argument contains all keywords for this macro
which are followed by one value, like e.g. ``DESTINATION`` keyword of the
:command:`install` command.
The ``<multi_value_keywords>`` argument contains all keywords for this
macro which can be followed by more than one value, like e.g. the
``TARGETS`` or ``FILES`` keywords of the :command:`install` command.
.. note::
All keywords shall be unique. I.e. every keyword shall only be specified
once in either ``<options>``, ``<one_value_keywords>`` or
``<multi_value_keywords>``. A warning will be emitted if uniqueness is
violated.
When done, ``cmake_parse_arguments`` will have defined for each of the
keywords listed in ``<options>``, ``<one_value_keywords>`` and
``<multi_value_keywords>`` a variable composed of the given ``<prefix>``
followed by ``"_"`` and the name of the respective keyword. These
variables will then hold the respective value from the argument list.
For the ``<options>`` keywords this will be ``TRUE`` or ``FALSE``.
All remaining arguments are collected in a variable
``<prefix>_UNPARSED_ARGUMENTS``, this can be checked afterwards to see
whether your macro was called with unrecognized parameters.
As an example here a ``my_install()`` macro, which takes similar arguments
as the real :command:`install` command:
.. code-block:: cmake
function(MY_INSTALL)
set(options OPTIONAL FAST)
set(oneValueArgs DESTINATION RENAME)
set(multiValueArgs TARGETS CONFIGURATIONS)
cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
"${multiValueArgs}" ${ARGN} )
# ...
Assume ``my_install()`` has been called like this:
.. code-block:: cmake
my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
After the ``cmake_parse_arguments`` call the macro will have set the
following variables::
MY_INSTALL_OPTIONAL = TRUE
MY_INSTALL_FAST = FALSE (was not used in call to my_install)
MY_INSTALL_DESTINATION = "bin"
MY_INSTALL_RENAME = "" (was not used)
MY_INSTALL_TARGETS = "foo;bar"
MY_INSTALL_CONFIGURATIONS = "" (was not used)
MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (nothing expected after "OPTIONAL")
You can then continue and process these variables.
Keywords terminate lists of values, e.g. if directly after a
one_value_keyword another recognized keyword follows, this is
interpreted as the beginning of the new option. E.g.
``my_install(TARGETS foo DESTINATION OPTIONAL)`` would result in
``MY_INSTALL_DESTINATION`` set to ``"OPTIONAL"``, but as ``OPTIONAL``
is a keyword itself ``MY_INSTALL_DESTINATION`` will be empty and
``MY_INSTALL_OPTIONAL`` will therefore be set to ``TRUE``.

View File

@ -29,6 +29,7 @@ These commands may be used freely in CMake projects.
/command/build_command
/command/cmake_host_system_information
/command/cmake_minimum_required
/command/cmake_parse_arguments
/command/cmake_policy
/command/configure_file
/command/continue

View File

@ -0,0 +1,6 @@
CMakeParseArguments-native-impl
-------------------------------
* The :command:`cmake_parse_arguments` command is now implemented natively.
The :module:`CMakeParseArguments` module remains as an empty placeholder
for compatibility.

View File

@ -2,86 +2,10 @@
# CMakeParseArguments
# -------------------
#
#
#
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords>
# <multi_value_keywords> args...)
#
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions
# for parsing the arguments given to that macro or function. It
# processes the arguments and defines a set of variables which hold the
# values of the respective options.
#
# The <options> argument contains all options for the respective macro,
# i.e. keywords which can be used when calling the macro without any
# value following, like e.g. the OPTIONAL keyword of the install()
# command.
#
# The <one_value_keywords> argument contains all keywords for this macro
# which are followed by one value, like e.g. DESTINATION keyword of the
# install() command.
#
# The <multi_value_keywords> argument contains all keywords for this
# macro which can be followed by more than one value, like e.g. the
# TARGETS or FILES keywords of the install() command.
#
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
# keywords listed in <options>, <one_value_keywords> and
# <multi_value_keywords> a variable composed of the given <prefix>
# followed by "_" and the name of the respective keyword. These
# variables will then hold the respective value from the argument list.
# For the <options> keywords this will be TRUE or FALSE.
#
# All remaining arguments are collected in a variable
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see
# whether your macro was called with unrecognized parameters.
#
# As an example here a my_install() macro, which takes similar arguments
# as the real install() command:
#
# ::
#
# function(MY_INSTALL)
# set(options OPTIONAL FAST)
# set(oneValueArgs DESTINATION RENAME)
# set(multiValueArgs TARGETS CONFIGURATIONS)
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
# "${multiValueArgs}" ${ARGN} )
# ...
#
#
#
# Assume my_install() has been called like this:
#
# ::
#
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
#
#
#
# After the cmake_parse_arguments() call the macro will have set the
# following variables:
#
# ::
#
# MY_INSTALL_OPTIONAL = TRUE
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
# MY_INSTALL_DESTINATION = "bin"
# MY_INSTALL_RENAME = "" (was not used)
# MY_INSTALL_TARGETS = "foo;bar"
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
#
#
#
# You can then continue and process these variables.
#
# Keywords terminate lists of values, e.g. if directly after a
# one_value_keyword another recognized keyword follows, this is
# interpreted as the beginning of the new option. E.g.
# my_install(TARGETS foo DESTINATION OPTIONAL) would result in
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION
# would be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
# This module once implemented the :command:`cmake_parse_arguments` command
# that is now implemented natively by CMake. It is now an empty placeholder
# for compatibility with projects that include it to get the command from
# CMake 3.4 and lower.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
@ -95,67 +19,3 @@
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
return()
endif()
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
# first set all result variables to empty/FALSE
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
set(${prefix}_${arg_name})
endforeach()
foreach(option ${_optionNames})
set(${prefix}_${option} FALSE)
endforeach()
set(${prefix}_UNPARSED_ARGUMENTS)
set(insideValues FALSE)
set(currentArgName)
# now iterate over all arguments and fill the result variables
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()
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
endif()
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()
# propagate the result variables to the caller:
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
endforeach()
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
endfunction()

View File

@ -54,6 +54,7 @@
#include "cmFunctionCommand.cxx"
#include "cmPathLabel.cxx"
#include "cmSearchPath.cxx"
#include "cmParseArgumentsCommand.cxx"
void GetBootstrapCommands1(std::vector<cmCommand*>& commands)
{
@ -91,4 +92,5 @@ void GetBootstrapCommands1(std::vector<cmCommand*>& commands)
commands.push_back(new cmFindProgramCommand);
commands.push_back(new cmForEachCommand);
commands.push_back(new cmFunctionCommand);
commands.push_back(new cmParseArgumentsCommand);
}

View File

@ -0,0 +1,192 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2015 Matthias Maennich <matthias@maennich.net>
Copyright 2010 Alexander Neundorf <neundorf@kde.org>
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmParseArgumentsCommand.h"
#include "cmAlgorithms.h"
//----------------------------------------------------------------------------
bool cmParseArgumentsCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
// cmake_parse_arguments(prefix options single multi <ARGN>)
// 1 2 3 4
if (args.size() < 4)
{
this->SetError("must be called with at least 4 arguments.");
return false;
}
std::vector<std::string>::const_iterator argIter = args.begin(),
argEnd = args.end();
// the first argument is the prefix
const std::string prefix = (*argIter++) + "_";
// define the result maps holding key/value pairs for
// options, single values and multi values
typedef std::map<std::string, bool> options_map;
typedef std::map<std::string, std::string> single_map;
typedef std::map<std::string, std::vector<std::string> > multi_map;
options_map options;
single_map single;
multi_map multi;
// anything else is put into a vector of unparsed strings
std::vector<std::string> unparsed;
// remember already defined keywords
std::set<std::string> used_keywords;
const std::string dup_warning = "keyword defined more than once: ";
// the second argument is a (cmake) list of options without argument
std::vector<std::string> list;
cmSystemTools::ExpandListArgument(*argIter++, list);
for (std::vector<std::string>::const_iterator iter = list.begin(),
end = list.end();
iter != end; ++iter)
{
if (!used_keywords.insert(*iter).second)
{
this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
}
options[*iter]; // default initialize
}
// the third argument is a (cmake) list of single argument options
list.clear();
cmSystemTools::ExpandListArgument(*argIter++, list);
for (std::vector<std::string>::const_iterator iter = list.begin(),
end = list.end();
iter != end; ++iter)
{
if (!used_keywords.insert(*iter).second)
{
this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
}
single[*iter]; // default initialize
}
// the fourth argument is a (cmake) list of multi argument options
list.clear();
cmSystemTools::ExpandListArgument(*argIter++, list);
for (std::vector<std::string>::const_iterator iter = list.begin(),
end = list.end();
iter != end; ++iter)
{
if (!used_keywords.insert(*iter).second)
{
this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
}
multi[*iter]; // default initialize
}
enum insideValues
{
NONE,
SINGLE,
MULTI
} insideValues = NONE;
std::string currentArgName;
// now iterate over the remaining arguments
// and fill in the values where applicable
for(; argIter != argEnd; ++argIter)
{
const options_map::iterator optIter = options.find(*argIter);
if (optIter != options.end())
{
insideValues = NONE;
optIter->second = true;
continue;
}
const single_map::iterator singleIter = single.find(*argIter);
if (singleIter != single.end())
{
insideValues = SINGLE;
currentArgName = *argIter;
continue;
}
const multi_map::iterator multiIter = multi.find(*argIter);
if (multiIter != multi.end())
{
insideValues = MULTI;
currentArgName = *argIter;
continue;
}
switch(insideValues)
{
case SINGLE:
single[currentArgName] = *argIter;
insideValues = NONE;
break;
case MULTI:
multi[currentArgName].push_back(*argIter);
break;
default:
unparsed.push_back(*argIter);
break;
}
}
// now iterate over the collected values and update their definition
// within the current scope. undefine if necessary.
for (options_map::const_iterator iter = options.begin(), end = options.end();
iter != end; ++iter)
{
this->Makefile->AddDefinition(prefix + iter->first,
iter->second? "TRUE": "FALSE");
}
for (single_map::const_iterator iter = single.begin(), end = single.end();
iter != end; ++iter)
{
if (!iter->second.empty())
{
this->Makefile->AddDefinition(prefix + iter->first,
iter->second.c_str());
}
else
{
this->Makefile->RemoveDefinition(prefix + iter->first);
}
}
for (multi_map::const_iterator iter = multi.begin(), end = multi.end();
iter != end; ++iter)
{
if (!iter->second.empty())
{
this->Makefile->AddDefinition(prefix + iter->first,
cmJoin(cmMakeRange(iter->second), ";")
.c_str());
}
else
{
this->Makefile->RemoveDefinition(prefix + iter->first);
}
}
if (!unparsed.empty())
{
this->Makefile->AddDefinition(prefix + "UNPARSED_ARGUMENTS",
cmJoin(cmMakeRange(unparsed), ";").c_str());
}
else
{
this->Makefile->RemoveDefinition(prefix + "UNPARSED_ARGUMENTS");
}
return true;
}

View File

@ -0,0 +1,54 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2015 Matthias Maennich <matthias@maennich.net>
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmParseArgumentsCommand_h
#define cmParseArgumentsCommand_h
#include "cmCommand.h"
/** \class cmParseArgumentsCommand
*
*/
class cmParseArgumentsCommand : public cmCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmParseArgumentsCommand;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
/**
* This determines if the command is invoked when in script mode.
*/
virtual bool IsScriptable() const { return true; }
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual std::string GetName() const { return "cmake_parse_arguments";}
cmTypeMacro(cmParseArgumentsCommand, cmCommand);
};
#endif

View File

@ -177,6 +177,7 @@ add_RunCMake_test(build_command)
add_RunCMake_test(execute_process)
add_RunCMake_test(export)
add_RunCMake_test(cmake_minimum_required)
add_RunCMake_test(cmake_parse_arguments)
add_RunCMake_test(continue)
add_RunCMake_test(ctest_build)
add_RunCMake_test(ctest_configure)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.4)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,15 @@
include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
# example from the documentation
# OPTIONAL is a keyword and therefore terminates the definition of
# the multi-value DEFINITION before even a single value has been added
set(options OPTIONAL FAST)
set(oneValueArgs DESTINATION RENAME)
set(multiValueArgs TARGETS CONFIGURATIONS)
cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
"${multiValueArgs}"
TARGETS foo DESTINATION OPTIONAL)
TEST(MY_INSTALL_DESTINATION UNDEFINED)
TEST(MY_INSTALL_OPTIONAL TRUE)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,44 @@
CMake Error at Errors\.cmake:2 \(cmake_parse_arguments\):
cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
CMake Error at Errors\.cmake:3 \(cmake_parse_arguments\):
cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
CMake Error at Errors\.cmake:4 \(cmake_parse_arguments\):
cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
CMake Warning at Errors\.cmake:8 \(cmake_parse_arguments\):
keyword defined more than once: OPT
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
CMake Warning at Errors\.cmake:9 \(cmake_parse_arguments\):
keyword defined more than once: OPT
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
CMake Warning at Errors\.cmake:10 \(cmake_parse_arguments\):
keyword defined more than once: OPT
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
CMake Warning at Errors\.cmake:12 \(cmake_parse_arguments\):
keyword defined more than once: OPT
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
CMake Warning at Errors\.cmake:13 \(cmake_parse_arguments\):
keyword defined more than once: OPT
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
CMake Warning at Errors\.cmake:14 \(cmake_parse_arguments\):
keyword defined more than once: OPT
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)

View File

@ -0,0 +1,14 @@
# wrong argument count
cmake_parse_arguments()
cmake_parse_arguments(prefix OPT)
cmake_parse_arguments(prefix OPT SINGLE)
cmake_parse_arguments(prefix OPT SINGLE MULTI) # not an error
# duplicate keywords
cmake_parse_arguments(prefix "OPT;OPT" "" "")
cmake_parse_arguments(prefix "" "OPT;OPT" "")
cmake_parse_arguments(prefix "" "" "OPT;OPT")
cmake_parse_arguments(prefix "OPT" "OPT" "")
cmake_parse_arguments(prefix "" "OPT" "OPT")
cmake_parse_arguments(prefix "OPT" "" "OPT")

View File

@ -0,0 +1,68 @@
include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
# unparsed arguments
cmake_parse_arguments(pref "" "" "")
TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
cmake_parse_arguments(pref "" "" "" FOO)
TEST(pref_UNPARSED_ARGUMENTS "FOO")
cmake_parse_arguments(pref "" "" "" FOO BAR)
TEST(pref_UNPARSED_ARGUMENTS "FOO;BAR")
cmake_parse_arguments(pref "" "" "")
TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
# options
cmake_parse_arguments(pref "OPT1" "" "")
TEST(pref_OPT1 FALSE)
cmake_parse_arguments(pref "OPT1;OPT2" "" "")
TEST(pref_OPT1 FALSE)
TEST(pref_OPT2 FALSE)
cmake_parse_arguments(pref "OPT1" "" "" OPT1)
TEST(pref_OPT1 TRUE)
cmake_parse_arguments(pref "OPT1;OPT2" "" "" OPT1 OPT2)
TEST(pref_OPT1 TRUE)
TEST(pref_OPT2 TRUE)
cmake_parse_arguments(pref "OPT1;OPT2" "" "")
TEST(pref_OPT1 FALSE)
TEST(pref_OPT2 FALSE)
# single arguments
cmake_parse_arguments(pref "" "SINGLE1" "")
TEST(pref_SINGLE1 UNDEFINED)
cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "")
TEST(pref_SINGLE1 UNDEFINED)
TEST(pref_SINGLE2 UNDEFINED)
cmake_parse_arguments(pref "" "SINGLE1" "" SINGLE1 foo)
TEST(pref_SINGLE1 foo)
cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "" SINGLE1 foo SINGLE2 bar)
TEST(pref_SINGLE1 foo)
TEST(pref_SINGLE2 bar)
cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "")
TEST(pref_SINGLE1 UNDEFINED)
TEST(pref_SINGLE2 UNDEFINED)
# multi arguments
cmake_parse_arguments(pref "" "" "MULTI1")
TEST(pref_MULTI1 UNDEFINED)
cmake_parse_arguments(pref "" "" "MULTI1;MULTI2")
TEST(pref_MULTI1 UNDEFINED)
TEST(pref_MULTI2 UNDEFINED)
cmake_parse_arguments(pref "" "" "MULTI1" MULTI1 foo)
TEST(pref_MULTI1 foo)
cmake_parse_arguments(pref "" "" "MULTI1;MULTI2" MULTI1 foo bar MULTI2 bar foo)
TEST(pref_MULTI1 foo bar)
TEST(pref_MULTI2 bar foo)
cmake_parse_arguments(pref "" "" "MULTI1;MULTI2")
TEST(pref_MULTI1 UNDEFINED)
TEST(pref_MULTI2 UNDEFINED)

View File

@ -0,0 +1,24 @@
include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
# specify two keywords for each category and set the first keyword of each
# within ARGN
cmake_parse_arguments(pref "OPT1;OPT2" "SINGLE1;SINGLE2" "MULTI1;MULTI2"
OPT1 SINGLE1 foo MULTI1 bar foo bar)
TEST(pref_OPT1 TRUE)
TEST(pref_OPT2 FALSE)
TEST(pref_SINGLE1 foo)
TEST(pref_SINGLE2 UNDEFINED)
TEST(pref_MULTI1 bar foo bar)
TEST(pref_MULTI2 UNDEFINED)
TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
# same as above but reversed ARGN
cmake_parse_arguments(pref "OPT1;OPT2" "SINGLE1;SINGLE2" "MULTI1;MULTI2"
MULTI1 bar foo bar SINGLE1 foo OPT1)
TEST(pref_OPT1 TRUE)
TEST(pref_OPT2 FALSE)
TEST(pref_SINGLE1 foo)
TEST(pref_SINGLE2 UNDEFINED)
TEST(pref_MULTI1 bar foo bar)
TEST(pref_MULTI2 UNDEFINED)
TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)

View File

@ -0,0 +1,7 @@
include(RunCMake)
run_cmake(Utils)
run_cmake(Initialization)
run_cmake(Mix)
run_cmake(CornerCases)
run_cmake(Errors)

View File

@ -0,0 +1,20 @@
include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
# test the TEST macro itself
TEST(asdf UNDEFINED)
SET (asdf FALSE)
TEST(asdf FALSE)
SET (asdf TRUE)
TEST(asdf TRUE)
SET (asdf TRUE)
TEST(asdf TRUE)
SET (asdf "some value")
TEST(asdf "some value")
SET (asdf some list)
TEST(asdf "some;list")

View File

@ -0,0 +1,20 @@
macro(TEST variable)
SET(expected "${ARGN}")
if ( "${expected}" STREQUAL "UNDEFINED" )
if (DEFINED ${variable})
message(FATAL_ERROR "'${variable}' shall be undefined but has value '${${variable}}'")
endif()
elseif( "${expected}" STREQUAL "FALSE" )
if (NOT ${variable} STREQUAL "FALSE")
message(FATAL_ERROR "'${variable}' shall be FALSE")
endif()
elseif( "${expected}" STREQUAL "TRUE" )
if (NOT ${variable} STREQUAL "TRUE")
message(FATAL_ERROR "'${variable}' shall be TRUE")
endif()
else()
if (NOT ${variable} STREQUAL "${expected}")
message(FATAL_ERROR "'${variable}' shall be '${expected}'")
endif()
endif()
endmacro()