Drop the 13 leftover documents (12 migration/validation reports at the tree root, 2 plugin ICD docs under Lts/Proxies/TrainingAreaBase, and jenkins-ci-rme/README.md); README.md is the only .md in the tree. The two README pointers at jenkins-ci-rme/README.md now describe the pipeline files inline.
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 (Jenkinsfile, builder, publisher, local dry run)build4_<timestamp>_<pid>/— per-run build tree, created by the driver (git-ignored viabuild4_*)
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
- Docker available on the host.
- A prebuilt build image. The driver default is
qt6-migrated-legatus-release2; any equivalent prebuilt image can be selected with--docker-image(orDOCKER_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
./new_docker_build_release2.sh --use-prebuilt-image --docker-image <image>
What the driver does inside the container:
-
Creates a fresh build tree
build4_<timestamp>_<pid>(unique per run). -
Configures with CMake (Ninja generator):
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=ONis required: RTI codegen consumers (e.g.svcPdmCommon) need the generated headers, and theBUILD_RTI=OFFstubs are not part of this tree. The scope is selected by theBUILD_GROUP*flags. -
Builds the 46 scope targets with
cmake --build ... --target <t>(Ninja, per target, in group order). -
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:
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:
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
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:
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
./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:
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:
jenkins-ci-rme/release-16-10-2026.sh
The pipeline files: jenkins-ci-rme/Jenkinsfile (job entry point),
jenkins-ci-rme/jenkins/Jenkinsfile (build body: install the prebuilt
image when missing, run the builder, coverage, publish),
jenkins-ci-rme/jenkins_builder_ubuntu26.sh (in-container DEB build),
jenkins-ci-rme/jenkins_publisher_ubuntu26.sh (upload to the artifact
repository).
Step 5 — Code coverage (lcov)
./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-dirargument and therpms/<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.datmust be present at the source tree root; the driver exportsRTI_LICENSEfor in-container use.