Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus
berrux-dev 5183c9419c Restore the external/ArcGIS symlink (build wiring, not pruneable)
FindArcGIS.cmake resolves the ArcGIS SDK via hardcoded hints rooted at
${CMAKE_SOURCE_DIR}/external/ArcGIS/MapsSDK_Qt_300.0.0/... ; in the
container that only resolves through this symlink to the pipeline-root
external/ mount. Its removal broke configure (Could NOT find ArcGIS,
missing ARCGIS_LIBRARY). No kept source references ArcGIS headers — the
include/ArcGIS tree stays removed; only the symlink is restored.
2026-11-13 23:42:23 +01:00
..
2026-08-13 16:59:32 +00:00

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

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

./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):

    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:

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

Tests registered by out-of-scope modules show up as ***Not Run (nglcomp_test, ddsGenericDataTests, ddsDataTopicTests, ddsFunctionTopicTests, coordTransTests_gtest, GrantleeParserSmoke, utils_test, exmDtUnitTest, migration_tests_NOT_BUILT) — that is expected and the driver continues.

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

See jenkins-ci-rme/README.md for the pipeline details.

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-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.