Automated Code Generation#
Caution
The sourcegen utility is an experimental part of Cantera and may be changed without notice.
Cantera’s sourcegen utility is a Python based source generator for creating Cantera interfaces for other languages. The following output options are supported:
clib
: Generated CLib API; used to generate the CLib API.csharp
: Generated .NET API; used to implement the .NET API.yaml
: Generated YAML Output; simple illustration that summarizes the CLib interface in YAML format.
Usage#
The sourcegen utility is a command-line tool that is used for code generation. It can be invoked without installation as
python -m interfaces.sourcegen.src.sourcegen <list-of-options>
from the root folder of the Cantera source code. For frequent usage, it is recommended to install sourcegen into the same virtual environment as used by SCons (for example the Conda environment used to compile Cantera from source) via:
python -m pip install -e interfaces/sourcegen
where the -e
(or --editable
) option ensures that changes to the sourcegen utility
take effect without a need to re-install. Running:
% sourcegen --help
displays the following help text:
usage: sourcegen [-h] [-v] [--api {clib,csharp,yaml}] [--output OUTPUT] [--root ROOT]
Source generator for creating Cantera interface code.
options:
-h, --help show this help message and exit
-v, --verbose show additional logging output
--api {clib,csharp,yaml}
language of generated Cantera API code
--output OUTPUT specifies the OUTPUT folder name
--root ROOT specifies the Cantera source ROOT folder (default is '.')
Overview#
The sourcegen utility parses the XML tree generated by Doxygen, using YAML configuration files that provide instructions for constructing CLib interface functions from underlying C++ functions and methods. For more information, see Generated CLib Headers.
The utility is used to generate the CLib API itself, as well as generated language interfaces built on top of it, such as the .NET interface and others.
Details#
Automatic code generation involves initialization steps to resolve CLib interface information using Generated CLib Headers. A subsequent scaffolding step delegates the source generation to a language-specific sub-package.
Parse Header File Specifications:
The commandline utility relies on a
HeaderFileParser
object that parses Header Specification Files and generates intermediateHeaderFile
objects that represent individual CLib modules. TheHeaderFile
dataclass contains the following information:path
: Output folder.funcs
: List of functions to be scaffolded (initially empty).prefix
: Prefix used for CLib function names.base
: Base class of C++ methods (if applicable).parents
: List of C++ parent class(es).derived
: Dictionary of derived C++ class(es) and alternative prefixes.recipes
: List of header recipes read from YAML.docstring
: Lines representing docstring of YAML file.
Each YAML specification file results in exactly one
HeaderFile
object.Resolve Recipes:
As a minimum, a YAML Recipe specifies a
name
that either corresponds to a function within theCantera
namespace or a method or variable of the implemented base class. TheCLibSourceGenerator.resolve_tags
method is used to cross-reference individual recipes with known Doxygen tags. The information is used to detect the CLib Function Type of a recipe and to generate a correspondingCFunc
object that holds relevant CLib interface information used for subsequent scaffolding:ret_type
: Return type of CLib function.name
: Name of CLib function.arglist
: CLib function argument list.brief
: Brief description.wraps
: Implemented C++ function/method (if applicable).returns
: Description of returned value.base
: Qualified scope of function/method (if applicable).uses
: List of auxiliary C++ methods (if applicable).
The information is used to update
recipe
list entries and build thefuncs
list for eachHeaderFile
object.Language-Specific Source Generation:
Each language-specific sub-package is required to export a class that derives from
SourceGenerator
and implement agenerate_source
method that takes a list ofHeaderFile
objects with their resolved recipes as an argument. Thegenerate_source
method uses this information to generate syntactically correct source code in the destination language.Each sub-package can contain a yaml-based config file named
config.yaml
. The core script recognizes two special keys:ignore_files
: a list of YAML specification file names
These files will be ignored entirely from source generation, for example because they cannot be parsed directly or contain functionality that is not planned for implementation in the destination language.ignore_funcs
: a mapping of YAML specification file names to lists of recipe names
The listed recipes contained within those files will not be scaffolded, for example because they cannot be translated automatically and need to be written by hand in the destination language.
The config file may contain additional values for use by the language-specific sub-package.
Further processing of generated code depends on the build process of the destination language.
Tip
The YAML Source Generator serves as an example to illustrate
code generation based on HeaderFile
contents.