Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/README.md
T
berrux-dev a62b729577 Keep the plugin ICD docs and jenkins-ci-rme/README.md
Revert part of the markdown cleanup: the two TrainingAreaBase plugin
ICD docs and jenkins-ci-rme/README.md stay in the tree; the root
migration/validation reports remain removed. README.md pointers to
jenkins-ci-rme/README.md are restored.
2026-11-14 01:16:27 +01:00

310 lines
13 KiB
Markdown

# qt6-migrated-legatus — Release 2 Build Guide
Build guide for the Qt6-migrated legatus tree for **Release 2** (guez project).
Everything runs inside a prebuilt Docker image; the host only needs Docker.
The source tree on this branch is pruned to the Release 2 build closure:
only the modules the 46 scope targets compile (plus their transitive
service dependencies, the codegen inputs, and the build-pipeline files)
are present — out-of-scope modules have been removed.
## Release 2 Scope
**46 targets** across 4 build groups (GROUP1, GROUP3, GROUP5, GROUP6):
| Group | Area | Count | Targets |
|---|---|---|---|
| **GROUP1** | AP4 — DDS middleware | 6 | ddscore, ddsftccore, ddsfts, ddsgen, ddsQoS, ddsconnector |
| **GROUP3** | AP3 — shared libraries, TetraIF, Lts/Common, tests | 36 | see breakdown below |
| **GROUP5** | AP9 — viewers | 3 | ddsview, LogViewer, sqlbrowser |
| **GROUP6** | AP9 — tools | 1 | ngl_codegen |
### GROUP3 breakdown
| Area | Targets |
|---|---|
| NGL stack (14) | NGLLogger, nglapplication, nglcompression, nglcoreapplication, ngldb, nglguiapplication, nglsettings, nglsingleapplication, nglsinglecoreapplication, ngltools, ngltranslator, nglwidgets, qtsingleapplication, qtsinglecoreapplication |
| Services (6) | wms_json_ds, tcpserver, LtsCoordinate, LtsCoordTrans, LtsSession, LtsMultiMonitor |
| Plugin interfaces (2) | DataPluginInterface, GuiPluginInterface |
| TetraIF (5) | CoPrtCnv, LogViewLogger, LogView, PrtCnvLib, PrtCnv |
| Additional (2) | LtsLicence, MockCoordTrans |
| Tests (7) | aes_crypt_test, ngltools_qt_smoke, lts_coord_trans_unit_test, test_nglpdfwidget, coprtcnv_unit_test, logview_unit_test, prtcnv_unit_test |
The group target lists are the `GROUP*_TARGETS` arrays in
`new_docker_build_release2.sh`.
## Entries at the tree root
- `new_docker_build_release2.sh` — Release 2 build driver (compile, ctest, DEB packaging, coverage)
- `Dockerfile` — recipe of the build image (Ubuntu 26.04 + Qt 6.10.2 + deps)
- `rpmbuild/make_rpm_ubuntu26_release2.py` — Release 2 DEB package producer (5 packages)
- `jenkins-ci-rme/` — in-tree copy of the Jenkins CI flow (see its own `README.md`)
- `build4_<timestamp>_<pid>/` — per-run build tree, created by the driver (git-ignored via `build4_*`)
**Toolchain inside the image:** Ubuntu 26.04, Qt 6.10.2 (`/opt/Qt/6.10.2/gcc_64`),
Ninja, C++17. Qt is installed via `aqt install-qt` (no apt Qt6 packages).
## Prerequisites
1. **Docker** available on the host.
2. A prebuilt build image. The driver default is `qt6-migrated-legatus-release2`;
any equivalent prebuilt image can be selected with `--docker-image`
(or `DOCKER_IMAGE`).
The driver resolves the pipeline root with this precedence:
exported `MIGRATE_PIPELINE_ROOT` → `MIGRATE_PIPELINE_ROOT` from the `.envrc`
in this directory → derived from the script location. The pipeline root is
mounted in the container at `/repo` (override with `--docker-mount-root`), so
the tree is reachable at
`/repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus`.
All commands below are run **from this directory**
(`qt6-migrated-legatus/`).
## Step 1 — Compile the Release 2 scope
```bash
./new_docker_build_release2.sh --use-prebuilt-image --docker-image <image>
```
What the driver does inside the container:
1. Creates a fresh build tree `build4_<timestamp>_<pid>` (unique per run).
2. Configures with CMake (Ninja generator):
```bash
cmake -B build4_<ts> \
-G Ninja \
-DBUILD_TESTING=ON \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64 \
-DCMAKE_CXX_FLAGS="-DRTI_LINUX -DRTI_UNIX" \
-DCMAKE_C_FLAGS="-DRTI_LINUX -DRTI_UNIX" \
-DBUILD_RTI=ON \
-DBUILD_GROUP1=ON -DBUILD_GROUP3=ON -DBUILD_GROUP5=ON -DBUILD_GROUP6=ON \
.
```
`BUILD_RTI=ON` is required: RTI codegen consumers (e.g. `svcPdmCommon`)
need the generated headers, and the `BUILD_RTI=OFF` stubs are not part of
this tree. The scope is selected by the `BUILD_GROUP*` flags.
3. Builds the 46 scope targets with `cmake --build ... --target <t>`
(Ninja, per target, in group order).
4. Runs **ctest** (see Step 2).
Output to inspect after the run (in the run's `build4_*` dir):
- `bin/` — executables (apps + test binaries)
- `lib/` — shared libraries
To rebuild incrementally without a fresh tree, run `ninja` in an interactive
container against the existing build dir:
```bash
B=$(ls -dt build4_* | head -1)
docker run --rm -it -v "$MIGRATE_PIPELINE_ROOT":/repo <image> \
bash -c "cd /repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus/${B} && ninja -j$(nproc)"
```
## Run an executable directly
To run a built executable interactively — e.g. the GUI apps under
`bin/` (`LogView`, `LogViewer`, `PrtCnv`) against your local display — start a
shell inside the container with X11 forwarding:
```bash
B=$(ls -dt build4_* | head -1)
docker run --rm -it \
-e DISPLAY \
-e LC_ALL=C.UTF-8 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v "$MIGRATE_PIPELINE_ROOT":/repo \
<image> \
bash -c "cd /repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus/${B} && exec bash"
```
## Step 2 — Run the tests
### 2.1 ctest (automatic)
The driver runs `ctest --output-on-failure -j$(nproc)` (with
`QT_QPA_PLATFORM=offscreen` — the container is headless) after the compile.
Expected baseline (7 in-scope tests, all passed):
| # | Test | Result |
|---|---|---|
| 1 | `coprtcnv_unit_test` | Passed |
| 2 | `logview_unit_test` | Passed |
| 3 | `prtcnv_unit_test` | Passed |
| 4 | `NGLToolsQtSmoke` | Passed |
| 5 | `test_nglpdfwidget` | Passed |
| 6 | `lts_coord_trans_unit_test` | Passed |
| 7 | `aes_crypt_test` | Passed |
A few tests registered by in-scope CMakeLists are not part of the 46
built targets and show up as `***Not Run` (`nglcomp_test`,
`GrantleeParserSmoke`, `utils_test`) — that is expected and the driver
continues. (Out-of-scope modules were pruned from this branch, so the
tests they registered are gone with them.)
### 2.2 Build the unit tests only
```bash
B=$(ls -dt build4_* | head -1)
docker run --rm -v "$MIGRATE_PIPELINE_ROOT":/repo <image> \
bash -c "cd /repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus/${B} \
&& ninja coprtcnv_unit_test logview_unit_test prtcnv_unit_test"
```
### 2.3 Run a test executable directly
GUI-free tests need the offscreen Qt platform in a headless container:
```bash
B=$(ls -dt build4_* | head -1)
docker run --rm -it -v "$MIGRATE_PIPELINE_ROOT":/repo <image> \
bash -c "export QT_QPA_PLATFORM=offscreen
cd /repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus/${B}
./bin/coprtcnv_unit_test # CoPrtCnv: telegrams, fragmentation, helpers
./bin/logview_unit_test # LogView: IntegerCalculator
./bin/prtcnv_unit_test # PrtCnv: PrtCnvMember fragmented-telegram handling
./bin/lts_coord_trans_unit_test
./bin/aes_crypt_test
./bin/test_nglpdfwidget
# or everything registered:
ctest --output-on-failure"
```
Each QtTest binary accepts a single slot name to run just one test,
e.g. `./bin/coprtcnv_unit_test radioTelegramFragmentationRoundtrip`.
### 2.4 TetraIF unit tests (`TetraIF/unit-test/`)
| Test | Module covered | Note |
|---|---|---|
| `coprtcnv_unit_test` | `CoPrtCnv` — central & radio telegram header fields, payload access, length checks, fragmentation/reassembly roundtrip, id→string helpers | links `CoPrtCnv` |
| `logview_unit_test` | `LogView` — `IntegerCalculator` (arithmetic, precedence, error codes, variables) | compiles `LogView/IntegerCalculator.cpp` into the test (the class otherwise lives in the LogView executable) |
| `prtcnv_unit_test` | `PrtCnv` — `PrtCnvMember` state + fragmented-telegram add/reassembly | compiles `PrtCnv/PrtCnvMember.cpp` into the test because `PrtCnvLib` is built with hidden visibility (its symbols are not linkable from outside) |
Sources are registered with ctest via `TetraIF/unit-test/CMakeLists.txt`.
## Step 3 — Produce the Release 2 DEB packages
```bash
./new_docker_build_release2.sh --use-prebuilt-image --docker-image <image> \
--run-jenkins-builder \
--package-output-dir ./packages-out \
> /path/to/build.log 2>&1
```
The driver compiles the Release 2 scope (46 targets), runs ctest, then stages
the tree and runs `rpmbuild/make_rpm_ubuntu26_release2.py`, which builds the
scope again (Release configuration, Ninja, scoped target list) and produces
5 DEBs in `${MIGRATE_PIPELINE_ROOT}/rpms/${PROJECT}/${OS_VERSION}/`
(default `rpms/guez/26.04/`). A copy is also placed in `--package-output-dir`
(default `./packages-out`):
| DEB | Contents |
|---|---|
| `qt6-release-runtime_1.0-1_amd64.deb` | Release 2 executables + libraries, staged from the scoped build's `bin/` and `lib/` |
| `qt6-release-sources_1.0-1_amd64.deb` | Release 2 scope sources (source files + CMakeLists under the release dirs) |
| `qt6-release-ctest-runtime_1.0-1_amd64.deb` | Test executables under `/usr/lib/ctest/` (currently empty — the producer looks for a `build4/bin/` dir, which the driver's timestamped `build4_<ts>/` dirs do not match) |
| `qt6-release-ctest-sources_1.0-1_amd64.deb` | Test sources (files with "test" in the name under release dirs) |
| `qt6-release-build-pipeline_1.0-1_amd64.deb` | In-tree pipeline files (the producer's `PIPELINE_FILES`: `new_docker_build_release2.sh`, `Dockerfile`, `jenkins-ci-rme/*`, `rpmbuild/make_rpm_ubuntu26_release2.py`, `CMakeLists.txt`) under `/usr/src/pipeline/` |
(Version string = `--lts-version` + `-` + `--build-number`, default `1.0-1`.)
Verify a package:
```bash
dpkg -c "${MIGRATE_PIPELINE_ROOT}/rpms/guez/26.04/qt6-release-runtime_1.0-1_amd64.deb"
dpkg -i "${MIGRATE_PIPELINE_ROOT}/rpms/guez/26.04/"*.deb # install locally, if wanted
```
## Step 4 — CI / Jenkins flow (optional)
The in-tree `jenkins-ci-rme/` directory contains the full Jenkins
pipeline (`Jenkinsfile`, builder, publisher) adapted to this tree. For a
local dry run of the same flow without Jenkins:
```bash
jenkins-ci-rme/release-16-10-2026.sh
```
See `jenkins-ci-rme/README.md` for the pipeline details.
## Step 5 — Code coverage (lcov)
```bash
./new_docker_build_release2.sh --use-prebuilt-image --docker-image <image> \
--run-coverage \
--coverage-output-dir ./coverage-out \
> /path/to/coverage.log 2>&1
```
The driver builds the Release 2 scope with `-O0 --coverage`, runs the same
ctest suite, then captures the data with lcov: the report covers the Release 2
scope (AP3, AP4, AP9, TetraIF, Z/src, Lts/Common), and test sources are
filtered out of the report, so the percentages reflect the module code.
Artifacts in the coverage output directory:
| File | Contents |
|---|---|
| `html/index.html` | browsable report (line + branch coverage per file) |
| `coverage.info` | machine-readable lcov tracefile |
| `coverage_summary.txt` | whole-scope totals |
`--run-coverage` is mutually exclusive with `--run-jenkins-builder` (different
instrumentation of the same build tree).
The Jenkins pipeline runs the same step on every build (`RunCoverage`
parameter, on by default); the local dry run
(`jenkins-ci-rme/release-16-10-2026.sh`) does the same, with
`DRYRUN_COVERAGE=OFF` to skip coverage there.
## Options reference
`./new_docker_build_release2.sh --help` prints the full option list. The main
ones:
| Option | Default | Purpose |
|---|---|---|
| `--group1 / --group3 / --group5 / --group6` (or `--no-…`) | all on | enable/disable the build groups (AP4 / AP3 / AP9 / AP9) |
| `--no-ctest` | off | skip ctest |
| `--tests-only` | off | run ctest only, skip the build groups |
| `--use-prebuilt-image` / `--no-prebuilt-image` | off | use a prebuilt image vs. apt install in-container |
| `--docker-image IMAGE` | `qt6-migrated-legatus-release2` | image to use |
| `--cmake_build_flags FLAGS` | — | extra `-D` flags for the in-container configure |
| `--run-jenkins-builder` | off | produce the DEB packages (Step 3) |
| `--package-output-dir DIR` | `./packages-out` | host dir that receives the DEB copy |
| `--lts-version VERSION` | `1.0` | package version prefix |
| `--project NAME` | `guez` | project name for package naming |
| `--build-number NUM` / `--build-tag TAG` | `1` / `manual-build` | package metadata |
| `--run-coverage` | off | coverage build + lcov report (Step 5) |
| `--coverage-output-dir DIR` | `./coverage-out` | where the coverage report is written |
| `--docker-mount-root PATH` | `/repo` | container-side mount root |
Environment overrides: `BUILD_GROUP1..6`, `RUN_CTEST`, `TESTS_ONLY`,
`USE_PREBUILT_IMAGE`, `DOCKER_IMAGE`, `CMAKE_BUILD_FLAGS`,
`DOCKER_MOUNT_ROOT`, `RUN_JENKINS_BUILDER`, `PACKAGE_OUTPUT_DIR`,
`LTS_VERSION`, `PROJECT`, `BUILD_NUMBER`, `BUILD_TAG`, `RUN_COVERAGE`,
`COVERAGE_OUTPUT_DIR`, `GUEZ_MODE`, `MIGRATE_PIPELINE_ROOT`.
## Troubleshooting
- **"no Qt platform plugin could be initialized"** when running a test
binary by hand → `export QT_QPA_PLATFORM=offscreen`.
- **Stale build tree** → the driver always creates a fresh
`build4_<timestamp>_<pid>` dir per run; old dirs are git-ignored scratch
areas and can be deleted freely.
- **DEBs not on the host** → the output dir must be a path that exists
*on the host*; check the `--package-output-dir` argument and the
`rpms/<project>/<os>/` dir under the pipeline root.
- **Build fails with missing Qt modules** → the image must be a prebuilt
Release 2 image (Qt 6.10.2 installed via `aqt install-qt`); select it with
`--docker-image`.
- **DDS build fails on the license** → `rti_license.dat` must be present at
the source tree root; the driver exports `RTI_LICENSE` for in-container
use.