diff --git a/qt6-after/qt6-migrated-legatus/README.md b/qt6-after/qt6-migrated-legatus/README.md new file mode 100644 index 000000000..abf764924 --- /dev/null +++ b/qt6-after/qt6-migrated-legatus/README.md @@ -0,0 +1,243 @@ +# qt6-migrated-legatus — compile and run (step by step) + +Build guide for the Qt6-migrated legatus tree on the release +**validation-scope** branch. Everything runs inside a prebuilt Docker +image; the host only needs Docker. + +## Scope and layout + +The release scope built by `new_docker_build.sh` is: + +| Area | Contents | +|---|---| +| `TetraIF/` | `CoPrtCnv`, `LogView`, `PrtCnv` (+ `unit-test/` — see below) | +| `Z/src/` | NGL application/core library stack (NGLLogger, nglcoreapplication, …) | +| `Lts/Common/` | LTS common libraries (LtsCoordTrans, LtsLicence, …) | +| `Lts/Proxies/TrainingAreaBase` | built as a dependency of TetraIF | + +Useful entries at the tree root: + +- `new_docker_build.sh` — the 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.py` — in-tree DEB package producer (self-contained) +- `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. + +## Prerequisites + +1. **Docker** available on the host. +2. **License file** `rti_license.dat` at the *pipeline root* — the + directory **three levels above** this tree + (`/rti_license.dat`). `new_docker_build.sh` derives the + pipeline root from its own location (override with the exported + `MIGRATE_PIPELINE_ROOT` or the `.envrc` in this directory). +3. 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.sh` invokes Docker, so running the driver as-is + satisfies this. + +All commands below are run **from this directory** (`qt6-migrated-legatus/`). + +## Step 1 — Build the prebuilt Docker image (once) + +```bash +./new_docker_build.sh --build-prebuilt-image --docker-image legatus-qt6:1.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.sh`. + +To remove it later: + +```bash +./new_docker_build.sh --delete-prebuilt-image --docker-image legatus-qt6:1.0 +``` + +## Step 2 — Compile the release scope + +```bash +./new_docker_build.sh --docker-image legatus-qt6:1.0 +``` + +What the driver does inside the container: + +1. `rm -rf build4 && mkdir build4 && cd build4` (fresh build tree) +2. Configure with CMake — the mandatory flags: + + ```bash + cmake .. \ + -DBUILD_TESTING=ON \ + -DBUILD_ARCGIS=OFF \ + -DRELEASE_BUILD=ON \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64:/usr/local + ``` + + (`BUILD_ARCGIS` and `RELEASE_BUILD` override CMake defaults that do + not match this branch.) +3. `make -j8` the release-scope targets (TetraIF modules, Z stack, + Lts/Common libs, all test executables — the list is + `RELEASE_BUILD_TARGETS` in `new_docker_build.sh`). +4. Run **ctest** (see Step 3). + +Output to inspect after the run: + +- `build4/release_build.log` — full make output (the build must end with + **0 warnings**) +- `build4/bin/` — executables (apps + test binaries) +- `build4/lib/` — shared libraries + +To rebuild incrementally without a fresh tree, run `make` directly in an +interactive container (Step 4). + +## 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 (8 tests): + +| # | Test | Result | +|---|---|---| +| 1 | `coprtcnv_unit_test` | Passed | +| 2 | `logview_unit_test` | Passed | +| 3 | `prtcnv_unit_test` | Passed | +| 4 | `nglcomp_test` | **Not Run** (pre-existing: compression "Unknown error" in Qt6) | +| 5 | `NGLToolsQtSmoke` | Passed | +| 6 | `test_nglpdfwidget` | Passed | +| 7 | `lts_coord_trans_unit_test` | Passed | +| 8 | `aes_crypt_test` | Passed | + +`nglcomp_test` being *Not Run* is the expected baseline — the pipeline +logs a ctest failure for it but continues. + +### 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 (this tree, `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 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.sh --docker-image legatus-qt6:1.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 scope, runs ctest, then stages the tree +and runs the in-tree `rpmbuild/make_rpm_ubuntu26.py`, which produces 5 +DEBs in `${WORKSPACE}/rpms/${PROJECT}/${OS_VERSION}/`: + +| DEB | Contents | +|---|---| +| `qt6-release-runtime_*` | runtime libraries + the release-scope executables | +| `qt6-release-sources_*` | release-scope sources | +| `qt6-release-ctest-runtime_*` | test executables under `/usr/lib/ctest/` (incl. the TetraIF unit tests) | +| `qt6-release-ctest-sources_*` | test sources (files with "test" in the name under the release dirs, incl. `TetraIF/unit-test/*.cpp`) | +| `qt6-release-build-pipeline_*` | the in-tree pipeline files (`new_docker_build.sh`, `Dockerfile`, `rpmbuild/`, `jenkins-ci-rme/`) under `/usr/src/pipeline/` | + +Verify a package: + +```bash +dpkg -c "${WORKSPACE}/rpms/guez/26.04/qt6-release-ctest-runtime_1.0-1_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. + +## Options reference + +`./new_docker_build.sh --help` prints the full option list. The main +ones: + +| Option | Default | Purpose | +|---|---|---| +| `--docker-image IMAGE` | `legatus-qt6-prebuilt:latest` | 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` | `1.0` / `guez` / `1` / `manual-build` | package metadata | + +Environment overrides: `DOCKER_IMAGE`, `RUN_JENKINS_BUILDER`, +`PACKAGE_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`. +- **ctest fails with `nglcomp_test (Not Run)`** → expected baseline + (pre-existing Qt6 compression issue); the pipeline continues. +- **License error at startup** → `rti_license.dat` must exist at + `/rti_license.dat` and be visible in the container at + `/workspace/rti_license.dat`. +- **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.