Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/README.md
T
torstenandCopilot e97806442f Update README for Release 2 delivery
- Update scope section with Release 2 target breakdown (38 targets)
- Update DEB package names from qt6-release-* to guez-*
- Update test suite expectations (13 tests including TetraIF)
- Update build instructions with guez-release2:2.0 Docker image
- Update Steps 4-6 for Release 2 DEB packaging and CI/CD
- Update options reference table with version 2.0
- Add troubleshooting note for Qt modules and build script

Co-authored-by: Copilot <2235566219+Copilot@users.noreply.github.com>
2026-11-13 10:45:33 +00:00

321 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.
## Release 2 Scope
**Release 2 includes all Release 1 packages plus new modules:**
| Area | Contents | Targets |
|---|---|---|
| **Release 1 Packages** | TetraIF, Z module, Lts/Common, Tests | 35 targets |
| **AP3 — Shared Libraries** | LtsUtils, Widgets, Session, Krypto, PluginManager | 6 targets |
| **AP4 — DDS Middleware** | Core, DDSConnector, Routing, QosProfile, RTI DDS compatibility | 6 targets |
| **AP9 — Tools & Translations** | DdsView, LogViewer, SqlBrowser, generators, lupdate toolchain | 4 targets |
**Total: 38 targets** across 4 build groups (GROUP1, GROUP3, GROUP5, GROUP6)
### Target Breakdown
| Group | Area | Targets | Count |
|---|---|---|---|
| **GROUP1** | DDS/AP4 | ddscore, ddsftccore, ddsfts, ddsgen, ddsQoS, ddsconnector | 6 |
| **GROUP3** | Lts/AP3/TetraIF/Tests | NGL (14), Lts (4), Plugin Interfaces (2), AP3 Libraries (4), Release 1 Additions (2), Tests (7) | 28 |
| **GROUP5** | Viewer/AP9 | ddsview, LogViewer, sqlbrowser | 3 |
| **GROUP6** | Tools/AP9 | ngl_codegen | 1 |
### Release 1 Modules Included
| Module | Targets | Description |
|---|---|---|
| **TetraIF** | 5 | CoPrtCnv, LogView, LogViewLogger, PrtCnv, PrtCnvLib |
| **Z Module** | 16 | NGL application/core library stack (NGLLogger, nglapplication, nglcompression, nglcoreapplication, ngldb, nglguiapplication, nglsettings, nglsingleapplication, nglsinglecoreapplication, ngltools, ngltranslator, nglwidgets, qtsingleapplication, qtsinglecoreapplication) |
| **Lts/Common** | 3 | LtsCoordinate, LtsCoordTrans, LtsMultiMonitor |
| **Tests** | 7 | aes_crypt_test, ngltools_qt_smoke, lts_coord_trans_unit_test, test_nglpdfwidget, coprtcnv_unit_test, logview_unit_test, prtcnv_unit_test |
| **Additional** | 2 | LtsLicence, MockCoordTrans |
## Entries at the tree root
- `new_docker_build_release2.sh` — Release 2 build driver (image build, compile, ctest, DEB packaging)
- `Dockerfile` — recipe of the prebuilt 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/` — build tree, created by the driver (git-ignored scratch area)
**Toolchain inside the image:** Ubuntu 26.04, GCC 15.2.0, Qt 6.10.2 (`/opt/Qt/6.10.2/gcc_64`), C++17, Release build.
**Qt Installation:** Qt 6.10.2 installed via `aqt install-qt` (no apt Qt6 packages).
## Prerequisites
1. **Docker** available on the host.
2. The tree must be reachable inside the container at
`/workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus`, i.e.
mount the pipeline root on `/workspace` — this is how
`new_docker_build_release2.sh` invokes Docker, so running the driver as-is
satisfies this.
The driver resolves the pipeline root from its own location (override
with the exported `MIGRATE_PIPELINE_ROOT` or the `.envrc` in this
directory).
All commands below are run **from this directory**
(`qt6-migrated-legatus/`).
## Step 1 — Build the prebuilt Docker image (once)
```bash
./new_docker_build_release2.sh --build-prebuilt-image --docker-image guez-release2:2.0
```
This builds the image from the in-tree `Dockerfile` (Ubuntu 26.04 base,
apt deps, Qt 6.10.2 via `aqtinstall`, KDReports from source). Re-run it
only after changing the `Dockerfile` or the `APT_PACKAGES` list in
`new_docker_build_release2.sh`.
To remove it later:
```bash
./new_docker_build_release2.sh --delete-prebuilt-image --docker-image guez-release2:2.0
```
## Step 2 — Compile the Release 2 scope
```bash
./new_docker_build_release2.sh --docker-image guez-release2:2.0
```
What the driver does inside the container:
1. `rm -rf build4 && mkdir build4 && cd build4` (fresh build tree)
2. Configure with CMake:
```bash
cmake .. \
-DBUILD_TESTING=ON \
-DRELEASE_BUILD=ON \
-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64:/usr/local
```
(`RELEASE_BUILD=ON` selects the Release 2 scope; everything else is at
its CMake default.)
3. `make -j8` the Release 2 scope targets (38 targets across GROUP1, GROUP3, GROUP5, GROUP6 — the list is
`RELEASE_BUILD_TARGETS` in `new_docker_build_release2.sh`).
4. Run **ctest** (see Step 3).
Output to inspect after the run:
- `build4/release_build.log` — full make output
- `build4/bin/` — executables (apps + test binaries)
- `build4/lib/` — shared libraries
To rebuild incrementally without a fresh tree, run `make` directly in an
interactive container against the existing `build4/`:
```bash
docker run --rm -it -v /path/to/pipeline-root:/workspace guez-release2:2.0 \
bash -c 'cd /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus/build4 \
&& make -j8'
```
## Run an executable directly
To run a built executable interactively — e.g. the GUI apps under
`build4/bin/` (`LogView`, `PrtCnv`) against your local display — start a
shell inside the container with X11 forwarding:
```bash
docker run --rm -it \
-e DISPLAY \
-e LC_ALL=C.UTF-8 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v /path/to/pipeline-root:/workspace \
legatus-qt6:1.0 \
bash -c 'cd /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus/build4 && exec bash'
```
## Step 3 — Run the tests
### 3.1 ctest (automatic)
`new_docker_build.sh` already runs `ctest --test-dir build4
--output-on-failure` after the compile. Expected baseline (7 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 |
### 3.2 Build the unit tests only
```bash
docker run --rm -v /path/to/pipeline-root:/workspace legatus-qt6:1.0 \
bash -c 'cd /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus/build4 \
&& make -j8 coprtcnv_unit_test logview_unit_test prtcnv_unit_test'
```
### 3.3 Run a test executable directly
GUI-free tests need the offscreen Qt platform in a headless container:
```bash
docker run --rm -it -v /path/to/pipeline-root:/workspace legatus-qt6:1.0 \
bash -c 'export QT_QPA_PLATFORM=offscreen
cd /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus/build4
./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`.
### 3.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`
and packaged into the ctest DEBs (see Step 4).
## Step 4 — Produce the Release 2 DEB packages
```bash
export WORKSPACE=/path/to/pipeline-root # e.g. ~/release/qt6-migration-pipeline
export PROJECT=guez
export OS_VERSION=26.04
./new_docker_build_release2.sh --docker-image guez-release2:2.0 \
--run-jenkins-builder \
--package-output-dir "${WORKSPACE}/rpms/${PROJECT}/${OS_VERSION}/" \
> /path/to/build.log 2>&1
```
(export the variables *before* the command — command-prefix variables are
not expanded in the same command's arguments.)
The driver compiles the Release 2 scope (38 targets), runs ctest,
then stages the tree and runs the in-tree `rpmbuild/make_rpm_ubuntu26_release2.py`,
which produces 5 DEBs in `${WORKSPACE}/rpms/${PROJECT}/${OS_VERSION}/`:
| DEB | Contents |
|---|---|
| `guez-runtime_2.0_amd64.deb` | Runtime libraries (Lts, AP3, AP4, TetraIF, Z) + executables |
| `guez-sources_2.0_amd64.deb` | Release 2 scope sources |
| `guez-ctest-runtime_2.0_amd64.deb` | Test executables under `/usr/lib/ctest/` (13 tests incl. TetraIF unit tests) |
| `guez-ctest-sources_2.0_amd64.deb` | Test sources (files with "test" in the name under release dirs) |
| `guez-build-pipeline_2.0_amd64.deb` | Pipeline files (`new_docker_build_release2.sh`, `Dockerfile`, `CMakeLists.txt`, `rpmbuild/`, `jenkins-ci-rme/`) under `/usr/src/pipeline/` |
Verify a package:
```bash
dpkg -c "${WORKSPACE}/rpms/guez/26.04/guez-ctest-runtime_2.0_amd64.deb" \
| grep unit_test
dpkg -i "${WORKSPACE}/rpms/guez/26.04/"*.deb # install locally, if wanted
```
A copy of the DEBs is also placed in the container's
`/workspace/packages-out` mount (same-file skip guarded by device:inode).
## Step 5 — 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 6 — Code coverage (lcov)
```bash
export WORKSPACE=/path/to/pipeline-root # e.g. ~/release/qt6-migration-pipeline
export PROJECT=guez
export OS_VERSION=26.04
./new_docker_build_release2.sh --docker-image guez-release2:2.0 \
--run-coverage \
--coverage-output-dir "${WORKSPACE}/coverage/${PROJECT}/${OS_VERSION}/" \
> /path/to/coverage.log 2>&1
```
(export the variables *before* the command — command-prefix variables are
not expanded in the same command's arguments.)
The driver builds the Release 2 scope with `-O0 --coverage`, runs the same ctest
suite (13 tests), then captures the data with lcov: the report covers the Release 2 scope
(AP3, AP4, AP9, TetraIF, Z/src, Lts/Common, Lts/Proxies/TrainingAreaBase), 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) and archives the report as build artifacts under
`coverage/<project>/<os>/`; 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 |
|---|---|---|
| `--docker-image IMAGE` | `guez-release2:2.0` | image to use/build/delete |
| `--build-prebuilt-image` | — | build the image from `./Dockerfile` and exit |
| `--delete-prebuilt-image` | — | delete the image and exit |
| `--run-jenkins-builder` | off | produce the DEB packages (Step 4) |
| `--package-output-dir DIR` | `./packages-out` | where the DEBs are written |
| `--lts-version / --project / --build-number / --build-tag` | `2.0` / `guez` / `1` / `manual-build` | package metadata |
| `--run-coverage` | off | coverage build + lcov report (Step 6) |
| `--coverage-output-dir DIR` | `./coverage-out` | where the coverage report is written |
Environment overrides: `DOCKER_IMAGE`, `RUN_JENKINS_BUILDER`,
`PACKAGE_OUTPUT_DIR`, `RUN_COVERAGE`, `COVERAGE_OUTPUT_DIR`, `PROJECT`,
`LTS_VERSION`, `GUEZ_MODE`, `BUILD_NUMBER`, `BUILD_TAG`,
`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 recreates `build4/`; for
manual builds delete `build4/` and rerun Step 2 if CMake behaves oddly.
- **DEBs not on the host** → the output dir must be a path that exists
*on the host* (it is bind-mounted into the container as
`/workspace/packages-out`); check the `package-output-dir` argument.
- **Build fails with missing Qt modules** → ensure the container uses
`new_docker_build_release2.sh` which installs Qt 6.10.2 via `aqt install-qt`.
The image must be `guez-release2:2.0` (not `legatus-qt6:1.0`).