Skip to content

Commit 5379598

Browse files
andy31415pull[bot]
authored andcommitted
Add documentation for how codegen works in the sdk (#23742)
* Add documentation for how codegen works in the sdk * Fix some typos after self-code-review * Fix spelling * One more spell fix * More spell fixes from pyspelling * Restyle pass after spell fixes * Apply one round of code review comments * Restyle * One more review pass changes applied * Fix typo
1 parent 884e4f8 commit 5379598

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed

docs/code_generation.md

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
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

Comments
 (0)