docs: document the code generation scripts (#7604)
Co-authored-by: Peter Feerick <5500713+pfeerick@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Peter Feerick
Claude Opus 5
parent
b6e52f5ee3
commit
4822400fe2
@@ -0,0 +1,143 @@
|
||||
# Code Generation
|
||||
|
||||
Several source files in the EdgeTX tree are not written by hand — they are produced
|
||||
by generator scripts and then **committed to git**. The build does not run these
|
||||
generators, so if you change one of their inputs you must re-run the generator and
|
||||
commit the regenerated output alongside your change.
|
||||
|
||||
| Generator | Produces | Re-run when you change |
|
||||
|---|---|---|
|
||||
| `radio/src/fonts/lvgl/make_fonts.sh` | `radio/src/fonts/lvgl/{std,sml,lrg}/lv_font_*.c` | a font source, or add a character to the `cn`/`tw`/`jp`/`he`/`ko`/`ru`/`ua` translations |
|
||||
| `tools/cfn_sorter.sh` | `radio/src/cfn_sort.cpp` | a special function name (`TR_SF_*`) in any translation, or `radio/src/dataconstants.h` |
|
||||
| `tools/generate-yaml.sh` | `radio/src/storage/yaml/yaml_datastructs_*.cpp` | `ModelData`/`RadioData` structures |
|
||||
|
||||
!!! note
|
||||
Both translation-driven generators are narrower than they look. `cfn_sorter.cpp`
|
||||
reads only the 25 `TR_SF_*` special function names, so editing any other string
|
||||
leaves `cfn_sort.cpp` untouched. The fonts only change if a translation
|
||||
introduces a character the font does not already contain, and only for the seven
|
||||
languages listed above — the Latin-script translations never affect them.
|
||||
|
||||
If you are unsure, just run the generator: it rewrites its output in place, so
|
||||
`git status` afterwards tells you whether anything actually moved.
|
||||
|
||||
## Using the development container
|
||||
|
||||
All three generators need tooling that is awkward to install by hand — a set of
|
||||
system locales, the `lv_font_conv` npm package, and a specific `libclang` version.
|
||||
The [EdgeTX development container](https://github.com/EdgeTX/build-edgetx) has all
|
||||
of it preinstalled, and is the reference environment:
|
||||
|
||||
```shell
|
||||
docker run -it --rm -v $(pwd):/src -w /src \
|
||||
ghcr.io/edgetx/edgetx-dev \
|
||||
bash
|
||||
```
|
||||
|
||||
Everything below can then be run from `/src` inside that container. If you use the
|
||||
[dev container](https://containers.dev/) integration in VS Code, the same image is
|
||||
picked up automatically from `.devcontainer/devcontainer.json`.
|
||||
|
||||
## LVGL fonts
|
||||
|
||||
`radio/src/fonts/lvgl/make_fonts.sh` regenerates the LVGL font tables for the colour
|
||||
LCD radios, in three sizes (`std`, `sml` and `lrg` — selected at build time by the
|
||||
radio's screen resolution).
|
||||
|
||||
```shell
|
||||
radio/src/fonts/lvgl/make_fonts.sh
|
||||
```
|
||||
|
||||
It reads the TrueType/OpenType sources under `radio/src/fonts/` (Roboto, Noto, Arimo
|
||||
and Nanum), the EdgeTX symbol fonts in `radio/src/fonts/lvgl/EdgeTX/`, and the
|
||||
FontAwesome set that ships inside the LVGL submodule. For the non-Latin languages it
|
||||
also scans the translation headers to work out which glyphs are actually needed, via
|
||||
the `get_char_*.py` helpers in the same directory.
|
||||
|
||||
Requirements:
|
||||
|
||||
- `lv_font_conv` — `npm install -g lv_font_conv`
|
||||
- `python3` and `gcc` (the script compiles a small LZ4 compression helper on the fly)
|
||||
- the LVGL submodule — `git submodule update --init --recursive`
|
||||
|
||||
A full run takes a few minutes and rewrites around 150 files.
|
||||
|
||||
!!! warning
|
||||
If a translation header cannot be read, the script prints
|
||||
`WARNING: No characters found ... Skipping` and carries on rather than failing.
|
||||
Check the output for that message — an otherwise clean run may simply have
|
||||
skipped a language.
|
||||
|
||||
## Custom function sort order
|
||||
|
||||
`tools/cfn_sorter.sh` generates `radio/src/cfn_sort.cpp`, the table that puts the
|
||||
custom function list into alphabetical order *for each translated language*.
|
||||
|
||||
```shell
|
||||
tools/cfn_sorter.sh
|
||||
```
|
||||
|
||||
It compiles `tools/cfn_sorter.cpp` once per language (selecting the language with a
|
||||
`-DLNG_xx` define) and concatenates the results. Sorting uses `std::locale`, so the
|
||||
matching system locale must exist, or the program aborts at runtime with
|
||||
`locale::facet::_S_create_c_locale name not valid`.
|
||||
|
||||
The dev container and the `tools/setup_buildenv_ubuntu*.sh` scripts install these
|
||||
already. On any other system, generate them by hand:
|
||||
|
||||
```shell
|
||||
apt update && apt install locales
|
||||
locale-gen zh_CN.UTF-8 cs_CZ.UTF-8 da_DK.UTF-8 de_DE.UTF-8 es_ES.UTF-8 en_US.UTF-8 \
|
||||
fi_FI.UTF-8 fr_FR.UTF-8 he_IL.UTF-8 it_IT.UTF-8 ja_JP.UTF-8 ko_KR.UTF-8 \
|
||||
nl_NL.UTF-8 pl_PL.UTF-8 pt_PT.UTF-8 ru_RU.UTF-8 sv_SE.UTF-8 zh_TW.UTF-8 uk_UA.UTF-8
|
||||
```
|
||||
|
||||
The full list is repeated in the comments at the top of the script. Only a C++
|
||||
compiler and those locales are needed; a run takes a few seconds.
|
||||
|
||||
## YAML parsers
|
||||
|
||||
`tools/generate-yaml.sh` regenerates the YAML storage parsers. Because it depends on
|
||||
a particular `libclang` version, it should always be run in the development
|
||||
container:
|
||||
|
||||
```shell
|
||||
docker run -it --rm -v $(pwd):/src \
|
||||
ghcr.io/edgetx/edgetx-dev \
|
||||
/src/tools/generate-yaml.sh
|
||||
```
|
||||
|
||||
Set `FLAVOR` to a semicolon-separated list to limit which radios are generated:
|
||||
|
||||
```shell
|
||||
docker run -it --rm -v $(pwd):/src \
|
||||
-e "FLAVOR=tx16s;nv14;x7;x9d" \
|
||||
ghcr.io/edgetx/edgetx-dev \
|
||||
/src/tools/generate-yaml.sh
|
||||
```
|
||||
|
||||
!!! warning
|
||||
The script deletes and recreates a `build` directory in the current working
|
||||
directory, so run it from the repository root and expect any existing `build/`
|
||||
to be removed.
|
||||
|
||||
See [YAML Parser/Generator](yaml-parser-generator.md) for how the parsers work, and
|
||||
for what to do when adding a new radio.
|
||||
|
||||
## Checking your regenerated output
|
||||
|
||||
After running a generator, review what changed before committing:
|
||||
|
||||
```shell
|
||||
git status --porcelain -- radio/src/fonts/lvgl radio/src/cfn_sort.cpp radio/src/storage/yaml
|
||||
git diff --stat
|
||||
```
|
||||
|
||||
An empty result means the committed files were already up to date and there is
|
||||
nothing to commit. Otherwise, commit the regenerated files together with the change
|
||||
that caused them to move.
|
||||
|
||||
!!! tip
|
||||
Both `make_fonts.sh` and `cfn_sorter.sh` leave intermediate files behind
|
||||
(`lv_font.inc`, `lz4_font` and `tools/a.out`) if they are interrupted. They are
|
||||
removed automatically on a successful run, but are safe to delete by hand.
|
||||
Reference in New Issue
Block a user