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
@@ -71,7 +71,7 @@ set CXX=clang++.exe
|
||||
|
||||
set NSIS_EXE=c:\Program Files (x86)\NSIS\makensis.exe
|
||||
set SDL2=%EDGETX_BUILD_TOOLS%\SDL2\cmake
|
||||
set QT_DIR=%EDGETX_BUILD_TOOLS%\Qt\6.9.0\msvc2022_64
|
||||
set QT_DIR=%EDGETX_BUILD_TOOLS%\Qt\6.9.3\msvc2022_64
|
||||
set PATHS="-DSDL2_DIR=%SDL2%"
|
||||
set CMAKE_PREFIX_PATH="-DCMAKE_PREFIX_PATH=%QT_DIR%"
|
||||
set LANGUAGE="-DTRANSLATIONS=%BUILD_LANGUAGE%"
|
||||
@@ -168,12 +168,12 @@ uv pip install clang lz4 jinja2 pillow pyelftools aqtinstall pydantic
|
||||
|
||||
### Qt development framework
|
||||
|
||||
Continue on the command prompt at `C:\edgetx\build-tools` to install Qt 6.9.0 into the Python virtual environment:
|
||||
Continue on the command prompt at `C:\edgetx\build-tools` to install Qt 6.9.3 into the Python virtual environment:
|
||||
```
|
||||
mkdir Qt
|
||||
cd Qt
|
||||
call "C:\edgetx\build-tools\.venv\Scripts\activate.bat"
|
||||
aqt install-qt windows desktop 6.9.0 win64_msvc2022_64 -m qtmultimedia qtserialport
|
||||
aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -m qtmultimedia qtserialport
|
||||
call "C:\edgetx\build-tools\.venv\Scripts\deactivate.bat"
|
||||
```
|
||||
Reboot your computer.
|
||||
|
||||
@@ -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.
|
||||
@@ -7,6 +7,11 @@ determine a precise mapping `attribute -> [bit address, bit length]`.
|
||||
This is done by using `libclang` Python bindings to parse `ModelData` and `RadioData`
|
||||
as well as related structures to compute precise bit-offsets for each attribute.
|
||||
|
||||
!!! note
|
||||
This page covers the YAML parser generator in detail. See
|
||||
[Code Generation](code-generation.md) for an overview of every generated file in
|
||||
the tree and when each one needs regenerating.
|
||||
|
||||
## Generating YAML parsers for existing radios
|
||||
|
||||
As the Python script used only works for now with certain versions of libclang,
|
||||
|
||||
@@ -91,6 +91,7 @@ nav:
|
||||
- Unbrick Your Radio: troubleshooting/unbrick.md
|
||||
- Development:
|
||||
- CLI Commands: development/cli-commands.md
|
||||
- Code Generation: development/code-generation.md
|
||||
- Control Inputs: development/control-inputs.md
|
||||
- External Module Protocols: development/external-module-protocols.md
|
||||
- YAML Parser/Generator: development/yaml-parser-generator.md
|
||||
|
||||
Reference in New Issue
Block a user