ci_exec.parsers.cmake_parser¶
Module for CMake focused argument parser CMakeParser
.
- class CMakeParser(*, add_extra_args=True, shared_or_static_required=False, **kwargs)[source]¶
A CMake focused argument parser.
The goal of this parser is to fold some of the more common flags used by many CMake projects and parse them into
cmake_configure_args
andcmake_build_args
automatically. Expected workflow is:from ci_exec import CMakeParser, cd, which parser = CMakeParser(description="Mylib CI Builder") # ... add any extra arguments specific to project ... # parser.add_argument("--foo", ...) # Parse arguments. cmake_{configure,build}_args are parsed for you, and are a # list of strings (possibly empty). args = parser.parse_args() configure_args = args.cmake_configure_args build_args = args.cmake_build_args # Use the configure / build args created for you by CMakeParser. cmake = which("cmake") with cd("build", create=True): cmake("..", *configure_args) cmake("--build", ".", *build_args)
This is helpful for situations where how users are expected to interact with CMake changes depending on the generator chosen. A reputable example being the build type for single-config vs multi-config generators:
Single-config: configure with
-DCMAKE_BUILD_TYPE=<build_type>
Multi-config: build with
--config <build_type>
The command line arguments added here should be appropriate for most projects that obey typical CMake practices, but is as customizable as possible. Command-line argument values such as the
help
string ordefault
value can be changed withset_argument()
. Arguments added by this parser that are not desired can be removed usingremove()
.Note
The documentation makes a distinction between registered and unregistered arguments.
- Registered
A flag that this parser adds in the constructor, and will later use to populate
cmake_configure_args
andcmake_build_args
.- Unregistered
Any arguments that the user adds. This parser does not keep track of them (
parser.add_argument("--foo", ...)
in example above).
The registered command-line arguments added are as follows:
-G
(args.generator
) – default:Ninja
The CMake generator to use. Pass-through configure argument
cmake -G
. Generator choices are validated, however:Extra Generators are not supported.
The now deprecated
Visual Studio XX YYYY Win64
format withWin64
is parsed as an error. Users should take advantage of-A
.
-A
(args.architecture
) – default:None
The CMake architecture to build. Pass-through configure argument
cmake -A
. Not validated, invalid arguments (e.g.,-A
provided when generator does not support it) will result in the cmake configure step failing.-T
(args.toolset
) – default:None
The CMake toolset to use. Pass-through configure argument
cmake -T
. Not validated, invalid arguments (e.g.,-T
provided when generator does not support it) will result in the cmake configure step failing.--shared
(args.shared
) – default:False
Add
-DBUILD_SHARED_LIBS=ON
to configure arguments? Conflicts with--static
flag.See also:
shared_or_static_required
constructor parameter.--static
(args.static
) – default:False
Add
-DBUILD_SHARED_LIBS=OFF
to configure arguments? Conflicts with--shared
flag.See also:
shared_or_static_required
constructor parameter.--cc
(args.cc
) – default: platform dependentThe C compiler to use. If the generator requested is a single-config generator, then the
-DCMAKE_C_COMPILER={args.cc}
configure argument. Multi-config generators such as Visual Studio or Xcode will ignore this flag.Default:
$CC
environment variable if set, otherwise:Platform
Default
Windows
cl.exe
Darwin
clang
Other
gcc
--cxx
(args.cxx
) – default: platform dependentThe C++ compiler to use. Like
--cc
, adds-DCMAKE_CXX_COMPILER={args.cxx}
configure argument for single-config generators.Default:
$CXX
environment variable if set, otherwise:Platform
Default
Windows
cl.exe
Darwin
clang++
Other
g++
--build-type
(args.build_type
) – default:Release
For single-config generators, this will result in a configure argument of
-DCMAKE_BUILD_TYPE={args.build_type}
. For multi-config generators, results in["--config", "{args.build_type}"]
in thecmake_build_args
.Choices:
Release
,Debug
,RelWithDebInfo
, andMinSizeRel
.[extra_args]
(args.extra_args
) – default:[]
By default, a positional argument with
nargs="*"
(meaning 0 or more) will be added. These are parsed as anything after the--
sequence, and will be added directly tocmake_configure_args
. This supports users doing something like:$ python .ci/build.py --shared # args.extra_args = [] $ python .ci/build.py --shared -- -Werror=dev -DMYLIB_DEV=ON # args.extra_args = ["-Werror=dev", "-DMYLIB_DEV=ON"] $ python .ci/build.py --shared -- -DMYLIB_DEV=OFF # args.extra_args = ["-DMYLIB_DEV=OFF"]
Note
This positional argument can be disabled two ways:
# Option 1: at construction. parser = CMakeParser(add_extra_args=False) # Option 2: set attribute to False *BEFORE* calling parse_args() parser = CMakeParser() parser.add_extra_args = False args = parser.parse_args()
Since this is a positional argument consuming
nargs="*"
, it must be added last in order for users to add their own positional arguments. The way this is implemented is by havingparse_args()
actually add the argument, which means:It must be disabled before
parser.parse_args()
is called to prevent.Unlike other arguments, it’s attributes such as default value of
[]
or help string cannot be changed.
- Parameters
add_extra_args (bool) – Default:
True
, support[extra_args]
CMake configure arguments at the end of the command-line, after the--
sequence (see above).shared_or_static_required (bool) –
Default:
False
. The--shared
and--static
flags are added usingadd_mutually_exclusive_group()
, this is a pass-through parameter:shared_or_static = self.add_mutually_exclusive_group( required=shared_or_static_required )
When
False
, if neither--shared
nor--static
are supplied, thenargs.cmake_configure_args
will not contain any-DBUILD_SHARED_LIBS=[val]
entries.When
True
, one of--shared
or--static
must be provided, meaning thatargs.cmake_configure_args
will always contain either-DBUILD_SHARED_LIBS=ON
or-DBUILD_SHARED_LIBS=OFF
.
Typically CMake projects will
option(BUILD_SHARED_LIBS "Build shared libraries?" OFF)
, meaning that if not specified--static
is implied. This is because the default behavior ofadd_library
with no explicitSHARED|STATIC
isSTATIC
. However, if a project defaultsBUILD_SHARED_LIBS
toON
, requiring--shared
or--static
be explicitly provided can help ensure that dependencies etc will all receive the sameBUILD_SHARED_LIBS
arguments.**kwargs – All other parameters are forwarded to
argparse.ArgumentParser
. Note that every parameter to theCMakeParser
class must be specified as a keyword-only argument. Positional arguments are disabled.
- flag_map¶
Mapping of string flag keys (e.g.,
"-G"
, or"--build-type"
) to the actualAction
of all registered arguments. Direct usage discouraged by users, useget_argument()
orset_argument()
instead.- Type
- dest_map¶
Mapping of string
dest
keys (e.g.,"generator"
or"build_type"
) to the actualAction
of all registered arguments. Direct usage discouraged by users, useget_argument()
orset_argument()
instead.- Type
- makefile_generators = {'Borland Makefiles', 'MSYS Makefiles', 'MinGW Makefiles', 'NMake Makefiles', 'NMake Makefiles JOM', 'Unix Makefiles', 'Watcom WMake'}¶
The Makefile Generators.
- ninja_generator = {'Ninja'}¶
The Ninja Generator.
- ninja_multi_generator = {'Ninja Multi-Config'}¶
- visual_studio_generators = {'Visual Studio 10 2010', 'Visual Studio 11 2012', 'Visual Studio 12 2013', 'Visual Studio 14 2015', 'Visual Studio 15 2017', 'Visual Studio 16 2019', 'Visual Studio 17 2022', 'Visual Studio 9 2008'}¶
- other_generators = {'Green Hills MULTI', 'Xcode'}¶
The Other Generators.
- classmethod is_multi_config_generator(generator)[source]¶
Whether or not string
generator
is a multi-config generator.
- classmethod is_single_config_generator(generator)[source]¶
Whether or not string
generator
is a single-config generator.
- add_argument(*args, **kwargs)[source]¶
Add an argument to the parser.
- Parameters
*args – Positional arguments to pass directly to
add_argument()
.**kwargs – Keyword arguments to pass directly to
add_argument()
.
- Returns
The return value of
add_argument()
(return value often not needed).- Return type
- Raises
ValueError – If
cmake_configure_args
orcmake_build_args
are in the positional*args
. These are reserved attribute names that get populated after parsing the arguments.ValueError – If
add_extra_args
isTrue
, thenextra_args
is also reserved and a value error will be raised if it is found in the positional*args
.
- get_argument(arg)[source]¶
Get the
Action
instance for the specified argument.- Parameters
arg (str) – The command-line flag (e.g.,
"-G"
,"--shared"
) or thedest
(e.g.,"generator"
,"shared"
) to look for.- Returns
The argument action instance (created from
add_argument()
). Ifarg
does not describe a command-line flag ordest
,None
is returned.- Return type
- parse_args(args=None, namespace=None)[source]¶
Parse the command-line arguments.
Typically, no arguments are needed:
parser = CMakeParser() # ... add your own arguments ... args = parser.parse_args() # uses sys.argv
- Parameters
args – See
parse_args()
.namespace – See
parse_args()
.
- Returns
The parsed command-line arguments in a wrapper struct. Will also have
cmake_configure_args
andcmake_build_args
(both will be lists of strings) attributes populated.- Return type
- remove(*args)[source]¶
Remove any registered argument(s).
This method may be used to remove any arguments not desired. Only arguments that have been created by instantiating a
CMakeParser
can be removed.Example:
parser = CMakeParser() parser.remove("--shared", "--static") # Remove by flags, or parser.remove("shared", "static") # remove by dest.
- Parameters
*args (str) – Arguments to remove, listed by either flag or dest names. See
CMakeParser
docs for all flags / dest names added.- Raises
ValueError – If
"-G"
or"generator"
inargs
. The generator argument may not be removed.ValueError – If
"extra_args"
inargs
. This is to be prevented from being added, seeparse_args()
.ValueError – If any arguments requested to be removed have not been found. This should only happen if (a) there was a typo, or (b) a user tries to remove an argument that was not registered.
- set_argument(arg, **attrs)[source]¶
Set attributes for
arg
argument.Example:
parser = CMakeParser() # Change default generator from Ninja to Unix Makefiles. parser.set_argument("generator", default="Unix Makefiles") # Change default build type from Release to Debug, only allow Release and # Debug builds (only as demonstration...not useful in practice). parser.set_argument("build_type", choices={"Release", "Debug"}, default="Debug")
- Parameters
arg (str) – May either be the command-line flag (e.g.,
"--shared"
or"-G"
), or thedest
of the argument (e.g.,"shared"
or"generator"
).**attrs –
The attributes to set. Only the following attributes are allowed to be changed via this method:
default: value returned if not specified on command-line.
choices: the list of valid values to validate against.
required: whether user must specify.
help: the help string for the argument.
metavar: how the argument is displayed in usage.
Note
Other values such as
dest
ornargs
are disallowed from being changed as doing so will break all functionality this class provides.
- Raises
ValueError – If the argument described by
arg
cannot be found.ValueError – The keys of
**attrs
are not supported to be changed. E.g.,dest
may not be changed.ValueError –
arg in {"-G", "generator"}
and"choices" in attrs
. The generator choices may not be changed (detection of single vs multi config generators will not be reliable).
Tests¶
Tests for the ci_exec.parsers.cmake_parser
module.
- test_cmake_parser_is_x_config_generator()[source]¶
Validate
is_single_config_generator()
andis_multi_config_generator()
.
- test_cmake_parser_defaults()[source]¶
Validate the
CMakeParser
defaults are as expected.
- test_cmake_parser_add_argument_failues()[source]¶
Validate
add_argument()
fails with expected names.
- test_cmake_parser_get_argument()[source]¶
Validate
get_argument()
finds both flag and dest names.
- test_cmake_parser_remove()[source]¶
Validate
remove()
can remove registered arguments (except for generator).
- test_cmake_parser_set_argument()[source]¶
Validate
set_argument()
can set supported attributes.
- test_cmake_parser_extra_args()[source]¶
Validate
add_extra_args
works as described.
Validate
--shared
and--static
CMakeParser
options.
- test_cmake_parser_parse_args_cmake_configure_args()[source]¶
Validate
parse_args
works as expected.