Files
qt6-migration-pipeline/prompts/migrate-nmeamanagement.prompt.md
berrux-dev b3e86c364c
Qt6 Migration CI / migrate (push) Waiting to run
Service migration documentation
2026-09-23 12:16:59 +02:00

18 KiB

Strict Qt6 Migration Prompt: NmeaManagement Service

This prompt is binding task context. Keep changes minimal, scoped, and reproducible.

Required base prompt

Before making changes, read and apply:

  • ./prompts/combined-migration-subfolder-rti-compact.prompt.md

If that prompt is stricter, follow it. This prompt overrides it only for build variants: use ON variants only. Do not pursue OFF variants.

Service in scope

Migrate only:

  • Lts/Services/NmeaManagement

All rules below apply exactly to this service and its direct build, generation, and test dependencies. Do not touch other services or unrelated modules.

Status of this service

The NmeaManagement service directory already exists in the Qt6 tree (qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/NmeaManagement/) and its source files have been migrated from Qt5 to Qt6:

  • Include paths modernized (#include <QX> → #include <QtCore/QX>, #include <QtWidgets/QX>, #include <QtGui/QX>)
  • QRegExp → QRegularExpression (nmea_handler.cpp)
  • Signal/slot macros → type-safe connections (connect(m_reconnectTimer, SIGNAL(timeout()), ...) → connect(m_reconnectTimer, &QTimer::timeout, ...))
  • QDesktopWidget → QScreen (nme_battery_info_dialog.cpp in the plugin)
  • QT5_WRAP_UI → no-op shim (NGLMacros.cmake, AUTOUIC handles .ui files)
  • CMakeLists.txt migrated: Qt5:: → Qt6::, codegen steps wrapped in IF(BUILD_RTI)
  • ddscore and ddsconnector → conditional $<IF:$<TARGET_EXISTS:...>>

The only thing preventing the service from building is that ADD_SUBDIRECTORY(NmeaManagement) is commented out in Lts/Services/CMakeLists.txt (line 28).

From / To

From:

  • ./qt-migration-legatus/qt5-before/qt5-legatus-legacy/Lts/Services/NmeaManagement/

To:

  • ./qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/NmeaManagement/

Do not migrate sibling services, sibling plugins, or unrelated modules.

Mandatory build variants

Only these variants are valid:

  • BUILD_RTI=ON
  • BUILD_GRANTLEE=ON

Forbidden:

  • BUILD_RTI=OFF
  • BUILD_GRANTLEE=OFF

Rules:

  • Do not implement, fix, preserve, test, or validate OFF variants.
  • Do not add CMake logic, tests, stubs, or fallbacks for OFF variants.
  • Do not report OFF variants as supported or partially supported.
  • Validation must use BUILD_RTI=ON and BUILD_GRANTLEE=ON.

Branches and trees

Qt6 target branch:

  • feature/qt6-migration-basis-modules

Qt5 legacy branch, if comparison is needed:

  • story/qt6-migration

Legacy source tree:

  • ./qt-migration-legatus/qt5-before/qt5-legatus-legacy

Qt6 target tree:

  • ./qt-migration-legatus/qt6-after/qt6-migrated-legatus

Work in the Qt6 target tree only. Do not modify the Qt5 legacy tree.

Scope rules

Touch files outside Lts/Services/NmeaManagement/ only when directly required to configure, generate, build, link, test, or validate this service.

Allowed outside-scope changes:

  • Lts/Services/CMakeLists.txt — uncommenting ADD_SUBDIRECTORY(NmeaManagement)
  • central CMake helper fixes required by this service
  • shared include path fixes required by this service
  • RTI, codegen, ndsgen, KTextTemplate, or Grantlee integration fixes required by this service
  • test infrastructure needed by tests for this service
  • docker_build.sh changes needed to run those tests
  • minimal Jenkins CI discovery or policy updates needed for those tests
  • relocation of required stubs or forward declarations to allowed directories

Not allowed:

  • restoring removed modules (commit 92ad7d468)
  • reintroducing stale dependencies on removed modules
  • removing or disabling active modules to hide failures
  • disabling targets instead of fixing root causes
  • broad refactoring, cleanup, renaming, or modernization
  • warning suppression instead of fixing causes
  • committing generated files
  • consuming generated outputs from the source tree
  • fake success, dummy files, handwritten generated replacements, mocks, placeholders, or generated-output stubs

Preservation rules

Preserve module removals from commit:

  • 92ad7d468, "remove all unneeded module listed from Niklas"

Do not restore removed modules, files, targets, directories, or dependencies.

Preserve LogViewer reinsert from commit:

  • 1fa789767, "Added LogViewer again"

Do not remove, disable, or break LogViewer integration.

Preserve prior IDL warning fixes from commit:

  • be912de9d, "Removes .IDL warnings: multiple enum definitons and builtin-type collisions"

Do not blindly replay that commit. Use it only as reference. Do not reintroduce removed modules.

IDL regressions to avoid:

  • multiple enum definitions
  • duplicate enumerators
  • builtin type or keyword collisions

Check first for duplicate inputs, stale paths, removed-module references, source-tree generated outputs, source/build-tree confusion, and repeated IDL definitions before treating an issue as semantic IDL conflict.

Stubs and forward declarations

Any required existing stub, compatibility declaration, or forward declaration must live only under:

  • ./qt-migration-legatus/qt6-after/qt6-migrated-legatus/forward-declarations/
  • ./qt-migration-legatus/qt6-after/qt6-migrated-legatus/.forward-declarations/include/

Rules:

  • Do not leave such files in service directories unless they are real service source files.
  • Do not create or keep stubs for forbidden OFF variants.
  • Do not use stubs or forward declarations as replacements for real RTI, ndsgen, KTextTemplate, or Grantlee outputs in ON builds.
  • Report every moved, removed, or newly referenced stub/forward declaration.

Migration checks

Inspect and migrate only as needed:

  • source and header files in Lts/Services/NmeaManagement/
  • CMakeLists.txt and parent CMake registration
  • RTI IDL (nme_service.xml), ndsgen, KTextTemplate, and Grantlee inputs/templates
  • tests directly tied to this service

The source files are already migrated. Focus on:

  1. Uncommenting ADD_SUBDIRECTORY(NmeaManagement) in Lts/Services/CMakeLists.txt
  2. Fixing any compile errors that surface after the service is added to the build
  3. Verifying codegen (nme_service.xml → .idl → .hpp/.cpp) produces expected outputs
  4. Verifying Qt module links (the executable links Qt6::Core, Qt6::Network, svcCoreClient, etc.)

Fix only real Qt6/C++17 build issues. No opportunistic refactoring or style cleanup.

No active target in the Qt6 tree may link Qt5 imported targets.

Search for and fix active uses of:

  • Qt5::
  • find_package(Qt5
  • QT5_
  • Qt5Core
  • Qt5Widgets
  • Qt5Network

Use Qt6 equivalents. Prefer central CMake helper fixes when the issue is central.

Code generation rules

The NmeaManagement service uses the standard RTI/Grantlee codegen pipeline:

  1. CODEGEN_IDL_SVC — generates nme_enums.idl and nme.idl from nme_service.xml
  2. RTIDDSGEN — compiles .idl files into .hpp, .cpp, .cxx, .Plugin outputs
  3. CODEGEN_TOPIC_TYPEDEFS — generates nme_dt[s,c]_types.h / nme_ft[s,c]_types.h
  4. CODEGEN_CLIENT_TOPICS_IFC — generates nme_[d|f]tc.h
  5. CODEGEN_CLIENT_TOPICS_IMPL — generates nme_[d|f]tc_impl.[cpp|h]
  6. CODEGEN_SERVER_TOPICS — generates nme_[d|f]ts.h, nme_[d|f]ts_impl.[cpp|h]
  7. CODEGEN_DATABASE — generates nme_db_impl.cpp/.h, nme_db.h
  8. CODEGEN_SQL — generates nme.sql, nme.xml
  9. CREATE_TOPIC_TYPE_PLUGIN — generates topic type plugin files

If generated files are required:

  • generate into the build tree
  • consume from the build tree
  • list complete OUTPUT and BYPRODUCTS
  • set correct DEPENDS and MAIN_DEPENDENCY where useful
  • use deterministic WORKING_DIRECTORY
  • use VERBATIM
  • wire generated sources with target_sources
  • wire generated include dirs with target_include_directories
  • ensure compilation depends on generation
  • ensure incremental rebuilds trigger on input/template changes

Never commit generated .idl, .h, .hpp, or .cpp outputs. Never consume generated outputs from the source tree. Never fabricate generated outputs.

Known pitfalls from the FileManagement/FilterManagement run

Apply these rules before debugging from scratch; skipping them repeats known problems.

rtiddsgen 7.7 generated API shape

RTI Connext 7.7 rtiddsgen with -language C++11 -stl generates:

  • plain public data members with no getters or setters: use data.id and data.id = value, not data.id() or data.id(value)
  • no *_def::type wrapper types: use enums directly in the service namespace
  • renamed enums when the generated name collides with a framework type
  • omg::types::optional and omg::types::sequence members

When a compile error looks like old getter/setter syntax ("expression cannot be used as a function") or a missing *_def type, read the generated header in the build tree for the real member and type names. Check every call site in the service, its handlers, and its WebSocket interfaces.

Grantlee templates generate the service impl files

Service *_impl.[ch] files are generated from Lts/Common/CodeGen/*.grantlee templates. If the fix belongs in generated code, fix the template; codegen reruns automatically. Never hand-edit generated outputs.

NGL_ADD_LIBRARY2 does not define the compile guard

NGL_ADD_LIBRARY defines MAKE_<SYMBOL>_LIB for the target; NGL_ADD_LIBRARY2 does not. A target consuming generated *_impl.h headers that carry an include guard fails with #error "You are not allowed to include this file in your code!" unless the guard is defined explicitly:

TARGET_COMPILE_DEFINITIONS(<target> PRIVATE MAKE_<SYMBOL>_LIB)

Stub copies racing the codegen

An unconditional CONFIGURE_FILE(... COPYONLY) that copies a stub header to a build-dir path that codegen also writes overwrites the generated file on every cmake re-configure. Guard such copies with IF(NOT BUILD_RTI) or IF(NOT BUILD_GRANTLEE).

Qt6 discovery in the container takes the minimal path

find_package(Qt6 ... COMPONENTS ...) always fails in the validation container. The tree takes the "Found Qt6 (minimal)" path and every Qt6 component target is a manual IMPORTED target in the root CMakeLists. When a migrated service needs a Qt6 module the container does not discover (for example WebSockets):

  • add the matching qt6-<module>-dev package to docker_build.sh
  • create a manual IMPORTED target in the root CMakeLists following the existing pattern
  • define the availability macro via add_compile_definitions when the real module is present
  • link the target by name in the service CMakeLists
  • gate the compile macro and the link on the same condition

Flipping a compile macro on an existing build dir leaves stale AUTOMOC caches. A clean build dir is required after flipping such macros.

Include shadowing between the stub tree and real generated headers

An include like <Core/core_dtc.h> can resolve into the migration stub tree (wrong namespaces) instead of the real generated header in the build tree. Use the full path from the build-tree include root (<DDS/Core/core_dtc.h>), add include_directories(BEFORE ${CMAKE_SOURCE_DIR}/Lts) when stub trees shadow Lts headers, and verify forward declarations name the same namespace as the real header.

Compare with the Qt5 original before inventing fixes

Several "missing field" or "unknown template" errors in the first run came from includes or members the Qt5 original had and the Qt6 copy had silently dropped. When a class fails to compile over a missing member or unknown base, diff against the Qt5 original first; restore the dropped piece rather than designing around it.

Export-header macro names

Generated export headers uppercase the whole target name, merging adjacent word letters: target LtsSessionData defines LTSSESSIONDATA_EXPORT. When writing tests that assert export macros, derive the expected prefix from the generated header, not from visual expectation.

Build orchestration

  • docker_build.sh must keep set -eo pipefail in the container script
  • When a migrated service adds a test executable, add it to the fixed make target list in docker_build.sh so ctest actually runs it
  • build4 is root-owned and wiped by every docker_build.sh run

Tests

For every C++ code change, add three meaningful CTest tests where feasible.

Rules:

  • tests must validate changed behavior, not only compilation
  • tests must be registered with CTest
  • tests must run with BUILD_RTI=ON and BUILD_GRANTLEE=ON
  • do not add OFF-variant tests
  • use deterministic tests without host-local paths

Preferred location:

  • ./qt-migration-legatus/qt6-after/qt6-migrated-legatus/tests

Use policy-compatible names, for example:

  • test_<name>.cpp
  • <name>_test.cpp
  • <name>test.cpp
  • <name>gtest.cpp

Docker and CI

Authoritative migration Dockerfile:

  • ./app/Dockerfile

Authoritative validation script:

  • ./qt-migration-legatus/qt6-after/qt6-migrated-legatus/docker_build.sh

Do not use other Dockerfiles as task authority.

Validation container expectations:

  • repository root at /repo, or the script's documented mount path
  • external dependencies under /repo/external, or the script's documented equivalent
  • RTI 7.7 at /repo/external/rti_connext_dds-7.7.0, or documented equivalent
  • ./rti_license.dat mounted read-only if RTI requires it
  • no developer-local paths

Jenkins CI must be able to discover and run the new tests, or verify that docker_build.sh runs them. Inspect and minimally update only if needed:

  • ./qt-migration-legatus/ci/Dockerfile.*
  • ./qt-migration-legatus/ci/check_pr_policies.py

Required procedure

  1. Inspect repository state, branch, working tree, and forward-declaration directories.
  2. Compare Qt5 source with Qt6 target for NmeaManagement. Classify files as already migrated, missing, stale, generated, or needing adaptation.
  3. Identify dependencies: svcCoreClient, ProjectConfig, LtsCommandLineParser, nglcoreapplication, Qt6 modules, and any service-level interdependencies.
  4. Uncomment ADD_SUBDIRECTORY(NmeaManagement) in parent Lts/Services/CMakeLists.txt.
  5. Apply the smallest valid migration changes to fix compile/link errors.
  6. Add required CTest tests for C++ changes (if applicable).
  7. Review RTI/codegen paths for nme_service.xml.
  8. Check regressions: Qt5 links, removed modules, LogViewer, IDL warnings.
  9. Validate in Docker with BUILD_RTI=ON and BUILD_GRANTLEE=ON.
  10. Run CTest in the validated build directory.
  11. Check Jenkins/policy compatibility.
  12. Report factual status.

Do not overwrite uncommitted user changes. If they block safe work, report the blocker.

Required validation

From:

  • ./qt-migration-legatus/qt6-after/qt6-migrated-legatus

Run:

BUILD_RTI=ON BUILD_GRANTLEE=ON ./docker_build.sh

CTest must run as part of validation.

Expected CTest baseline: ctest exits with code 8 when tests are "Not Run". A pre-existing set of Not Run tests (for example nglcomp_test, aes/avm/exm/scm/bld suites, GrantleeParserSmoke) belongs to sibling targets outside the docker_build.sh make list; that set existed before this migration series and is not a failure. Treat only ***Failed entries as failures. Do not widen this exception to skip or filter real failures, and do not add the missing sibling targets to fix the exit code. If a previously passing test becomes Not Run or Failed, that is a regression of this run.

If a direct clean build is useful, use:

cmake -S /repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus -B /repo/build-rti-on-grantlee-on -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_RTI=ON -DBUILD_GRANTLEE=ON
cmake --build /repo/build-rti-on-grantlee-on --parallel
ctest --test-dir /repo/build-rti-on-grantlee-on --output-on-failure

Also check whether this file exists and run it only if present:

./docker-build.h

If it is absent or a typo, report that. Do not invent a replacement.

Do not run or validate OFF variants.

Success criteria

Success requires:

  • NmeaManagement migrated and confirmed buildable
  • NmeaManagement included in the Qt6 build (uncommented in parent CMakeLists.txt)
  • configure, build, and CTest pass with BUILD_RTI=ON and BUILD_GRANTLEE=ON
  • docker_build.sh runs the relevant tests and fails on test failure
  • Jenkins/policy discovery accepts any new tests and validation changes
  • no active Qt5 imported target links remain for this service
  • generated outputs are build-tree only and freshly produced when required
  • no generated outputs are committed or consumed from the source tree
  • no fake generated files, dummy files, mocks, placeholders, or stubbed generated outputs exist
  • required stubs/forward declarations are only in allowed directories
  • removed modules remain removed
  • LogViewer remains preserved
  • RTI/codegen and Grantlee/KTextTemplate success is real, not stale or faked

If blocked

Do not fake success. Report:

  • failing command
  • key error output
  • affected service
  • category: project, path, merge, CMake, Qt API, codegen, Docker, RTI/license, Grantlee/KTextTemplate, test, CTest, Jenkins CI, stub relocation, or environment
  • what was fixed safely
  • what remains blocked
  • whether stale artifacts were ruled out
  • whether generated files were involved
  • exact missing files, targets, or generator step
  • whether tests and CTest integration succeeded
  • whether Docker validation and Jenkins discovery succeeded

Final report

Keep it short. Include:

  • status: validated, partially validated, or blocked
  • service migrated or already correct
  • files changed
  • C++ files changed
  • tests added per C++ change
  • CTest registration changes
  • CMake and generator changes
  • stub/forward-declaration moves or removals
  • Docker and Jenkins CI changes
  • Qt5 references removed or remaining
  • confirmation that removed modules were not restored
  • confirmation that LogViewer was preserved
  • exact validation commands and results
  • result of ./docker-build.h if present
  • remaining blockers or risks