|
| 1 | +# Code generation |
| 2 | + |
| 3 | +## Code generation inputs (`*.zap` files) |
| 4 | + |
| 5 | +Matter code relies on code generation for cluster-specific data types and |
| 6 | +callbacks. Generally this is split into: |
| 7 | + |
| 8 | +- Data serialization for structures/lists/commands. This applies to both |
| 9 | + client-side and server-side structures and objects |
| 10 | +- Callback setup using the Ember-based framework. This generally applies to |
| 11 | + server-side processing and the code generation defines what processing needs |
| 12 | + to be done when a specific command is received or an attribute is read and |
| 13 | + what memory should be allocated for storing cluster attributes |
| 14 | + |
| 15 | +Code generation depends on the clusters that are needed by an application. Every |
| 16 | +application configures the specific set of endpoints and clusters it needs based |
| 17 | +on the device type it supports. The selection of the supported clusters and |
| 18 | +attributes (as optional attributes may be omitted to save memory) is generally |
| 19 | +stored in `*.zap` files. |
| 20 | + |
| 21 | +The selection of enabled clusters and files is done using |
| 22 | +[ZAP](https://github.com/project-chip/zap). You can download a recent release of |
| 23 | +zap from its [releases page](https://github.com/project-chip/zap/releases). It |
| 24 | +is recommended to download a release that is in sync with the currently in use |
| 25 | +version by the SDK (see `integrations/docker/images/chip-build/Dockerfile` and |
| 26 | +check the `ZAP_VERSION` setting). |
| 27 | + |
| 28 | +Beyond basic zap file selection, there are also `.json` zap settings that define |
| 29 | +additional cluster info: source XML files, sdk-access methods and data types. |
| 30 | +There are only two such files currently in use: |
| 31 | + |
| 32 | +- `src/app/zap-templates/zcl/zcl.json` is the **default** one |
| 33 | +- `src/app/zap-templates/zcl/zcl-with-test-extensions.json` is used by |
| 34 | + `all-clusters-app` to show how a cluster extension may be configured with |
| 35 | + minimal changes from `zcl.json` (but it is different) |
| 36 | + |
| 37 | +### Installing zap and environment variables |
| 38 | + |
| 39 | +Matter scripts may need to invoke `zap-cli` (for code generation) or `zap` (to |
| 40 | +start the UI tool). For this, scrips need to know where to find the commands. In |
| 41 | +the following order, the scripts process these environment variables: |
| 42 | + |
| 43 | +- if `$ZAP_DEVELOPMENT_PATH` is set, code assumes you are running zap from |
| 44 | + source. Use this if you develop zap. Zap has to be bootstrapped (generally |
| 45 | + `npm ci` but check zap documentation for this. Some scripts have a |
| 46 | + `--run-bootstrap` command line argument to do this for you) |
| 47 | + |
| 48 | +- if `$ZAP_INSTALL_PATH` is set, code assumes that `zap` or `zap-cli` is |
| 49 | + available in the given path. This is generally an unpacked release. |
| 50 | + |
| 51 | +- otherwise, scripts will assume `zap`/`zap-cli` is in `$PATH` |
| 52 | + |
| 53 | +### Using a UI to edit `.zap` files |
| 54 | + |
| 55 | +Generally you need to invoke zap with appropriate zcl and generate arguments. |
| 56 | +Most of code generation is app specific, so you generally want something of the |
| 57 | +form |
| 58 | +`--gen src/app/zap-templates/app-templates.json --zcl $ZCL_JSON_FILE $ZAP_FILE_TO_EDIT` |
| 59 | + |
| 60 | +Since this is tedious to type, the SDK provides a |
| 61 | +`scripts/tools/zap/run_zaptool.sh` script to automate this: |
| 62 | + |
| 63 | +```bash |
| 64 | +# Ensure zap is in $PATH or set $ZAP_INSTALL_PATH or $ZAP_DEVELOPMENT_PATH |
| 65 | +./scripts/tools/zap/run_zaptool.sh examples/lighting-app/lighting-common/lighting-app.zap |
| 66 | +``` |
| 67 | + |
| 68 | +### Human-readable code generation inputs (`*.matter`) |
| 69 | + |
| 70 | +`.zap` files are large json files that are generally not human readable. As a |
| 71 | +result, the Matter SDK also keeps an equivalent `*.matter` file along side |
| 72 | +`.zap` files that contain the same data as `.zap` files, targeted specifically |
| 73 | +for matter: |
| 74 | + |
| 75 | +- They are designed to be human readable, looking like a IDL (think protobuf |
| 76 | + or android `aidl`, thrift idl etc.) |
| 77 | + |
| 78 | +- We strive to make them contain only Matter-specific data (`.zap` files |
| 79 | + contain more generic data and is designed to be ZigBee backwards compatible) |
| 80 | + |
| 81 | +Currently `.matter` files are generated from `.zap` files during the application |
| 82 | +specific codegen. |
| 83 | + |
| 84 | +### `*.matter` parsing and codegen |
| 85 | + |
| 86 | +`*.matter` files are both human and machine readable. Code that can process |
| 87 | +these files is available at `scripts/idl` and `scripts/codegen.py`. You can read |
| 88 | +the [scripts/idl/README.md](../scripts/idl/README.md) for details of how things |
| 89 | +work. |
| 90 | + |
| 91 | +`scripts/codegen.py` can generate various outputs based on an input `*.matter` |
| 92 | +file. |
| 93 | + |
| 94 | +The split between `.zap` and `.matter` currently exists as an experiment of code |
| 95 | +generation technologies. Currently `.matter`-based Python code generation: |
| 96 | + |
| 97 | +- has fewer third party dependencies than `zap`, which installs a significant |
| 98 | + number of `npm` packages. |
| 99 | +- runs significantly faster than zap |
| 100 | +- offers more flexible code generation (can generate multiple files per |
| 101 | + cluster for example, without which some compiles would run out of RAM on |
| 102 | + large compilations) |
| 103 | +- has a more flexible templating language |
| 104 | +- has human readable (and potentially editable) input |
| 105 | +- is more easily provable deterministic (`zap` uses an underlying sqlite |
| 106 | + database and some legacy assumptions from zigbee have historically caused |
| 107 | + non-determinism) |
| 108 | +- uses a synchronous processing model which is potentially easier to develop |
| 109 | + for |
| 110 | +- has lower complexity, is unit tested and uses typing extensively |
| 111 | + |
| 112 | +Ideally, the project would be to have a single code generation method in the |
| 113 | +long term that has all the benefits and none of the drawbacks. We are not there |
| 114 | +yet, however we likely want: |
| 115 | + |
| 116 | +- Flexible codegen (we will need to split output by clusters or other rules) |
| 117 | +- Human-readable inputs that enable code reviews and audits |
| 118 | +- Rules that a script can validate based on CSA data model (ensure mandatory |
| 119 | + attribute settings are followed, ensure proper device type adherence, ensure |
| 120 | + correct cluster and data type definitions) |
| 121 | +- Easy to maintain and develop for chosen languages/templates/codegen in |
| 122 | + general |
| 123 | + |
| 124 | +## Code generation outputs and templates |
| 125 | + |
| 126 | +Code that is generated: |
| 127 | + |
| 128 | +- **Application-specific**: |
| 129 | + |
| 130 | + - ZAP generation is based on `.zap` files in `examples/` and generates |
| 131 | + server-side processing data: what cluster callbacks to set up, what RAM |
| 132 | + to reserve for attribute storage etc. |
| 133 | + |
| 134 | + - `Codegen.py` will also generate a subset of application-specific files |
| 135 | + |
| 136 | +- **Automated tests**: embedded client-side tools (`chip-tool` and |
| 137 | + `darwin-framework-tool`) generate test-definition data. Each use their own |
| 138 | + `examples/${TOOL}/templates/tests/templates.json` to drive what gets |
| 139 | + generated. |
| 140 | + |
| 141 | +- **Controller clusters** target: the file |
| 142 | + `src/controller/data_model/controller-clusters.zap` contains a set of |
| 143 | + cluster selections to which all applications would potentially have access. |
| 144 | + These are generally used as `all clusters selection` and the intent is to |
| 145 | + allow any application to access any cluster as a `client side`. |
| 146 | + |
| 147 | + Client/controllers will codegen based on this, like **tools**, **tests**, |
| 148 | + **java**, **python** etc. |
| 149 | + |
| 150 | +## Running codegen |
| 151 | + |
| 152 | +### ZAP file generation |
| 153 | + |
| 154 | +Generating all possible code (all categories above) using zap tool can be done |
| 155 | +via: |
| 156 | + |
| 157 | +```bash |
| 158 | +./scripts/tools/zap_regen_all.py |
| 159 | +``` |
| 160 | + |
| 161 | +This can be slow (several minutes). The regen tool allows selection of only |
| 162 | +tests so that yaml test development goes faster. |
| 163 | + |
| 164 | +```bash |
| 165 | +./scripts/tools/zap_regen_all.py --type tests |
| 166 | +./scripts/tools/zap_regen_all.py --type tests --tests chip-tool |
| 167 | +``` |
| 168 | + |
| 169 | +Additionally, individual code regeneration can be done using |
| 170 | +`./scripts/tools/zap/generate.py`: |
| 171 | + |
| 172 | +```bash |
| 173 | +/scripts/tools/zap/generate.py examples/bridge-app/bridge-common/bridge-app.zap -o zzz_generated/bridge-app/zap-g |
| 174 | +enerated |
| 175 | +``` |
| 176 | + |
| 177 | +### `*.matter` code generation |
| 178 | + |
| 179 | +Currently `*.matter` code generation is done at compile time. |
| 180 | + |
| 181 | +Rules for how `codegen.py` is invoked and how includes/sources are set are |
| 182 | +defined at: |
| 183 | + |
| 184 | +- `src/app/chip_data_model.cmake` |
| 185 | +- `build/chip/esp32/esp32_codegen.cmake` (support for 2-pass cmake builds used |
| 186 | + by the Espressif `idf.py` build system) |
| 187 | +- `src/app/chip_data_model.gni` |
0 commit comments