nnvg¶
Usage¶
Generate code from Cyphal DSDL using pydsdl and jinja2
usage: nnvg [-h] [--no-target-namespaces] [--lookup-dir LOOKUP_DIR]
[--outdir OUTDIR] [--target-language TARGET_LANGUAGE]
[--templates-dir TEMPLATES_DIR]
[--support-templates-dir SUPPORT_TEMPLATES_DIR]
[--fallback-to-builtin-templates] [--index-file INDEX_FILE]
[--include-experimental-languages]
[--output-extension OUTPUT_EXTENSION]
[--generate-support {always,never,as-needed,only}]
[--generate-namespace-types] [--omit-serialization-support]
[--namespace-output-stem NAMESPACE_OUTPUT_STEM] [--no-overwrite]
[--file-mode FILE_MODE] [--allow-unregulated-fixed-port-id]
[--embed-auditing-info] [--omit-dependencies] [--verbose]
[--version] [--dry-run] [--jobs JOBS] [--list-outputs]
[--list-inputs] [--list-configuration]
[--list-format {csv,scsv,json,json-pretty}]
[--list-to-file LIST_TO_FILE] [--trim-blocks] [--lstrip-blocks]
[--pp-max-emptylines PP_MAX_EMPTYLINES]
[--pp-trim-trailing-whitespace] [-pp-rp PP_RUN_PROGRAM]
[-pp-rpa PP_RUN_PROGRAM_ARG]
[--target-endianness {any,big,little}]
[--omit-float-serialization-support]
[--enable-serialization-asserts]
[--enable-override-variable-array-capacity]
[--language-standard {c11,c17,c23,c++14,cetl++14-17,c++17,c++17-pmr,c++20,c++20-pmr}]
[--configuration [CONFIGURATION ...]] [--option [OPTION ...]]
[target_files_or_root_namespace ...]
Positional Arguments¶
- target_files_or_root_namespace
One or more dsdl files to generate from.
All dependent types found in the target dsdl files will be generated and must be available either as another target or as a dsdl file under one of the –lookup-dir directories.
A –lookup-dir argument for each unique root path among the list of files is required if not using the colon syntax.
Colon Syntax¶
The standard syntax allows the path to the root to be specified at the same time as the type
path/to/root:name/space/Type.1.0.dsdl
This also adds the path to a list of valid paths. You can continue to specify it (duplicates are ignored) or you can specify it once
path/to/root:name/space/Type.1.0.dsdl name/space/Type.1.0.dsdl ...is the same as... path/to/root:name/space/Type.1.0.dsdl path/to/root:name/space/Type.1.0.dsdl
Globular Expansion¶
Any target paths that are folders will be considered to be root namespaces. nnvg will then search for all dsdl files under that folder and generate target paths for all .dsdl files found. To disable this behavior use the –no-target-namespaces argument which will cause an error if a folder is provided as a target.
Named Arguments¶
- --no-target-namespaces
If provided then all target paths must be to individual DSDL files and not folders. If set and a folder is provided as a target an error will be raised.
Normally, if a folder is provided as a target path, nnvg will search for all dsdl files under that folder and generate target paths for all .dsdl files found using the path itself as the root namespace.
see target_files_or_root_namespace for more information.
- --lookup-dir, -I
List of other namespace directories containing data type definitions that are referred to from the target root namespace. For example, if you are reading a vendor-specific namespace, the list of lookup directories should always include a path to the standard root namespace “uavcan”, otherwise the types defined in the vendor-specific namespace won’t be able to use data types from the standard namespace.
For a given target set of dsdl files this argument is required to specify a set of valid paths to or folder names of root namespaces. For example
nnvg types/animals/felines/Tabby.1.0.dsdl types/animals/canines/Boxer.1.0.dsdl
will fail unless the path describing the root is provided
nnvg --lookup-dir types/animals types/animals/cats/Tabby.1.0.dsdl \ types/animals/dogs/Boxer.1.0.dsdl
If multiple roots are targeted then each root path will need to be enabled
nnvg -I types/animals -I types/plants types/animals/cats/Tabby.1.0.dsdl \ types/plants/trees/Fir.1.0.dsdl
For target files this argument is required to specify a set of valid paths to or folder names of root namespaces, however; an additional syntax is supported where the root for a target file can be specified as part of the target path using a colon to separate the two
nnvg types/animals:cats/Tabby.1.0.dsdl types/plants:trees/Fir.1.0.dsdl
This is the recommended syntax as it allows all target files to be specified as relative paths and reserves this argument to specify concrete lookup directories
nnvg --lookup-dir /path/to/types types/animals:mammals/cats/Tabby.1.0.dsdl \ types/plants:trees/conifers/Fir.1.0.dsdl
Additional directories can also be specified through an environment variable DSDL_INCLUDE_PATH where the path entries are separated by colons “:” on posix systems and “;” on Windows
DSDL_INCLUDE_PATH=/path/to/types/animals:/path/to/types/plants \ nnvg animals:mammals/cats/Tabby.1.0.dsdl \ plants:trees/conifers/Fir.1.0.dsdl
CYPHAL_PATH is similarly used (and formatted) but the paths in this variable are listed and each folder under each path will be a lookup directory
CYPHAL_PATH=/path/to/types nnvg animals:mammals/cats/Tabby.1.0.dsdl \ plants:trees/conifers/Fir.1.0.dsdl
- --outdir, -O
output directory
Default:
'nunavut_out'
- --target-language, -l
Language support to install into the templates.
If provided then the output extension (-e) can be inferred otherwise the output extension must be provided.
extended options¶
Additional options to control output generation.
- --templates-dir, --templates
Paths to a directory containing templates to use when generating code.
Templates found under these paths will override the built-in templates for a given language.
- --support-templates-dir, --support-templates
Paths to a directory containing templates to use when generating support code.
Templates found under these paths will override the built-in support templates for a given language.
- --fallback-to-builtin-templates, -tfb
Normally, if providing a custom templates directory, the built-in templates are not searched for. This option will cause the built-in templates to be searched for if a template is not found in the custom templates directory first.
- --index-file
Index-files are generated from special templates that are given access to all types in all namespaces. This is useful for generating files that are not specific to a single type like dependency files, manifests, or aggregate headers.
The template lookup paths are the same as for DSDL types but the template is selected based on the filename of the all-file first and falls back to index.j2 if no specific template is found. Note that the DSDL type hierarchy will be searched first so you cannot name your index-file the same as a DSDL data type like StructureType.j2.
Example
# looks for all_types.j2 in the c_jinja template directory and generates # generated/include/all_types.h from all types in all DSDL namespaces. nnvg --index-file all_types.h --outdir generated/include --templates c_jinja \ path/to/types/animal:cat.1.0.dsdl \ path/to/types/animal:dog.1.0.dsdl # looks for manifest.j2 in the json_jinja template directory and generates # generated/include/manifest.json from all types in all DSDL namespaces. nnvg --index-file include/manifest.json --outdir generated --templates json_jinja \ path/to/types/animal:cat.1.0.dsdl \ path/to/types/animal:dog.1.0.dsdl
- --include-experimental-languages, --experimental-languages, -Xlang
Activate languages with unstable, experimental support.
By default, target languages where support is not finalized are not enabled when running nunavut, to make it clear that the code output may change in a non-backwards-compatible way in future versions, or that it might not even work yet.
- --output-extension, -e
The output extension for generated files. If target language is provided an extension is inferred based on language configuration. This option allows overriding this inference.
Note that, if –target-language is omitted and this argument is provided the program will attempt to infer the language based on the file extension. This may lead to unexpected results (e.g. –output-extension .h generating C instead of C++).
If a dot (.) is omitted one will be added, therefore; -e h and -e .h will both result in an extension of .h.
- --generate-support
Possible choices: always, never, as-needed, only
Change the criteria used to enable or disable support code generation.
as-needed (default) - generate support if it is needed. always - always generate support code. never - never generate support code. only - only generate support code.
Note that serialization logic is only one type of support code. This option covers all types of support code. Where –omit-serialization-support is set different types of support code may still be generated unless this option is set to never.
Default:
'as-needed'
- --generate-namespace-types
If enabled this script will generate source for namespaces. All namespaces including and under the root namespace will be treated as a pseudo-type and the appropriate template will be used. The generator will first look for a template with the stem “Namespace” and will then use the “Any” template if that is available. The name of the output file will be the default value for the –namespace-output-stem argument and can be changed using that argument.
- --omit-serialization-support, -pod
If provided then the types generated will be POD datatypes with no additional logic. By default types generated include serialization routines and additional support libraries, headers, or methods as needed. These additional support artifacts can be suppressed using the –generate-support option.
- --namespace-output-stem
The name of the file generated when –generate-namespace-types is provided.
- --no-overwrite
By default, generated files will be silently overwritten by subsequent invocations of the generator. If this argument is specified an error will be raised instead preventing overwrites.
- --file-mode
The file-mode each generated file is set to after it is created. Note that this value is interpreted using python auto base detection. Because of this, to provide an octal value, you’ll need to prefix your literal with ‘0o’ (e.g. –file-mode 0o664).
Default:
292
- --allow-unregulated-fixed-port-id
Do not reject unregulated fixed port identifiers. This is a dangerous feature that must not be used unless you understand the risks. The background information is provided in the Cyphal specification.
- --embed-auditing-info
If set, generators are instructed to add additional information in the form of language-specific comments or meta-data to use when auditing source code generated by Nunavut. This data may change based on the environment in use which may interfere with the reproducibility of your builds. For example, paths to input files used to generate a type may be included with this option where these paths will be different depending on the server used to run nnvg.
- --omit-dependencies
Disables the generation of dependent types. This is useful when setting up build rules for a project where the dependent types are generated separately.
run mode options¶
Options that control the operation mode of the script.
- --verbose, -v
verbosity level (-v, -vv)
- --version
show program’s version number and exit
- --dry-run, -d
If True then no files will be generated.
- --jobs, -j
Limits the number of subprocesses nnvg can use to parallelize type discovery and code generation.
If set to 0 then the number of jobs will be set to the number of CPUs available on the system.
If set to 1 then no subprocesses will be used and all work will be done in th main process.
Default:
0
- --list-outputs
Emit a semicolon-separated list of files. (implies –dry-run) Emits files that would be generated if invoked without –dry-run. This command is useful for integrating with CMake and other build systems that need a list of targets to determine if a rebuild is necessary.
If used with –list-inputs the list of inputs will be emitted first followed by the list of outputs. A single empty value will separate the two lists when using value-delimited formats. Use –list-format to control the output format including using json to avoid the need for an empty-value delimiter.
- --list-inputs
Emit a semicolon-separated list of files. (implies –dry-run) A list of files that are resolved given input arguments like templates. This command is useful for integrating with CMake and other build systems that need a list of inputs to determine if a rebuild is necessary.
If used with –list-outputs the list of inputs will be emitted first followed by the list of outputs. A single empty value will separate the two lists. Use –list-format to control the output format including using json to avoid the need for an empty-value delimiter.
- --list-configuration, -lc
Lists all configuration values resolved for the given arguments. Unlike –list-inputs and –list-outputs this command does not imply –dry-run but can be used in conjunction with it.
This option is only available if –list-format is set to json.
- --list-format
Possible choices: csv, scsv, json, json-pretty
For commands that emit lists of files this option controls the format of the output.
csv - comma separated values scsv - semicolon separated values json - json formatted results json-pretty - json formatted results with indentation
Default:
'scsv'
- --list-to-file
If provided then the output of –list-outputs, –list-inputs, or –list-configuration will also be written to the file specified. If the file exists it will be overwritten. This utf-8-encoded file will be written in the format specified by –list-format even if –dry-run is set.
language options¶
Options passed through to templates as options on the target language.
Note that these arguments are passed though without validation, have no effect on the Nunavut library, and may or may not be appropriate based on the target language and generator templates in use.
- --target-endianness
Possible choices: any, big, little
Specify the endianness of the target hardware. This allows serialization logic to be optimized for different CPU architectures.
- --omit-float-serialization-support
Instruct support header generators to omit support for floating point operations in serialization routines. This will result in errors if floating point types are used, however; if you are working on a platform without IEEE754 support and do not use floating point types in your message definitions this option will avoid dead code or compiler errors in generated serialization logic.
- --enable-serialization-asserts
Instruct support header generators to generate language-specific assert statements as part of serialization routines. By default the serialization logic generated may make assumptions based on documented requirements for calling logic that could expose a system to undefined behavior. The alternative, for languages that do not support exception handling, is to use assertions designed to halt a program rather than execute undefined logic.
- --enable-override-variable-array-capacity
Instruct support header generators to add the possibility to override max capacity of a variable length array in serialization routines. This option will disable serialization buffer checks and add conditional compilation statements which violates MISRA.
- --language-standard, -std
Possible choices: c11, c17, c23, c++14, cetl++14-17, c++17, c++17-pmr, c++20, c++20-pmr
For language generators that support different standards of their core language this option can be used to optimize the output. For example, C templates may generate slightly different code for the the c99 standard then for c11. For available support in Nunavut see the documentation for built-in templates (https://nunavut.readthedocs.io/en/latest/docs/templates.html#built-in-template-guide).
- --configuration, -c
There is a set of built-in configuration for Nunavut that provides default values for known languages as documented in the template guide. This argument lets you specify an override configuration json file where any value provided will override the built-in defaults. To see the built-in defaults you can use:
nnvg --list-configuration --list-format json-pretty > built-in.json
This will generate a json file with all the built-in configuration values as the “configuration.sections” value. If you have jq installed you can use this to filter the output to just the configuration:
nnvg --list-configuration --list-format json-pretty | jq '.configuration.sections' > my-config.json
Then you can edit the my-config.json file to provide overrides for the built-in defaults and use this option to provide the file to nnvg:
nnvg --configuration my-config.json ...
Also see
--list-to-file
which writes this configuration to disk if combined with--list-configuration
.- --option, -o
Passes a key=value pair to the template as a language option overriding default options where they are specified. This is useful for passing options to the template that are not available as command-line arguments. For example, if you have a template that uses the “foo” variable you can pass a value to it using this argument:
nnvg -o foo=value ...
where “foo” is then available in the template as {{ options.foo }}.
This option is similar to the –configuration option but only applies to the options section of the target language and doesn’t require a file to be created.
Copyright (C) OpenCyphal Development Team <opencyphal.org> Copyright Amazon.com Inc. or its affiliates. Released under SPDX-License-Identifier: MIT
Example Usage
# This would include j2 templates for a folder named 'c_jinja'
# and generate .h files into a directory named 'include' for
# the uavcan.node.Heartbeat.1.0 data type and its dependencies
nnvg --outdir include --templates c_jinja -e .h dsdl/uavcan:node/7509.Heartbeat.1.0.dsdl
ᓄᓇᕗᑦ