diff --git a/prompts/migrate-lts-services.prompt.md b/prompts/migrate-lts-services.prompt.md new file mode 100644 index 000000000..28345707c --- /dev/null +++ b/prompts/migrate-lts-services.prompt.md @@ -0,0 +1,492 @@ +# Strict Qt6 Migration Prompt: Lts/Services + +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. + +## Services in scope + +Migrate only: + +- Lts/Services/ + +Name the concrete services for this run (for example FileManagement and +FilterManagement). All rules below apply to exactly those services and their +direct build, generation, and test dependencies. Previous runs already +migrated FileManagement and FilterManagement; do not remigrate or refactor +them, and treat their green validation state as a baseline that must not +regress. + +From: + +- ./qt-migration-legatus/qt5-before/qt5-legatus-legacy/Lts/Services/ + +To: + +- ./qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/ + +Do not migrate sibling services 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 the two target service directories only when directly required to configure, generate, build, link, test, or validate these services. + +Allowed outside-scope changes: + +- parent CMakeLists.txt entries for these services +- central CMake helper fixes required by these services +- shared include path fixes required by these services +- RTI, codegen, ndsgen, KTextTemplate, or Grantlee integration fixes required by these services +- test infrastructure needed by tests for these services +- 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 +- 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 + +For each service, inspect and migrate only as needed: + +- source and header files +- CMakeLists.txt and parent CMake registration +- ui, qrc, resource, plugin, and service metadata +- RTI IDL, ndsgen, KTextTemplate, and Grantlee inputs/templates +- tests directly tied to these services + +Fix only real Qt6/C++17 build issues, such as: + +- Qt module imports and target links +- moc, uic, and rcc handling +- QRegExp to QRegularExpression when required +- QTextCodec replacement when required +- QDesktopWidget or QApplication::desktop() replacement when required +- QString, QVariant, QMetaType, QDateTime, QAction, QMenu, signal/slot, enum, plugin, or metadata compatibility issues when required + +No opportunistic refactoring or style cleanup. + +## Qt link rules + +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 + +If generated files are required: + +- reconstruct the real legacy generation flow +- 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 + +These rules encode failures already diagnosed and fixed during the first +migrated services. Apply them 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, for example `FileManagement::FileCategory`, not + `FileManagement::FileCategory_def::type` +- renamed enums when the generated name collides with a framework type, for + example `Core::PortType` is now `Core::CorePortType` +- `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 instead of +inventing helpers. Check every call site in the service, its handlers, and +its WebSocket interfaces, not only the first hit. + +### 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 because the custom +commands depend on the templates. Never hand-edit generated outputs. Check +templates for old setter syntax such as +`data.{{ dt.key.name }}({{ dt.key.name }})` and convert them to plain +member assignment. + +### NGL_ADD_LIBRARY2 does not define the compile guard + +NGL_ADD_LIBRARY defines `MAKE__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: + +```cmake +TARGET_COMPILE_DEFINITIONS( PRIVATE MAKE__LIB) +``` + +Example: svcCoreClient defines MAKE_SVCCORECLIENT_LIB, mirroring how ddscore +defines MAKE_DDSCORE_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, then looks like a phantom failure that appears +only in reconfigured builds. Guard such copies with `IF(NOT BUILD_RTI)` or +`IF(NOT BUILD_GRANTLEE)` when the generator produces the same output path, +and state in a comment which codegen writes the real file. Stub copies for +paths no generator writes are fine as they are. + +### Retriggering codegen + +Makefile touch_nocreate rules for secondary codegen outputs do not retrigger +generation. To force regeneration after deleting or guarding an output, +delete the primary output (for example the generated .idl), not only the +secondary headers. + +### Qt6 discovery in the container takes the minimal path + +`find_package(Qt6 ... COMPONENTS ...)` always fails in the validation +container (Multimedia/Svg/SerialPort dev packages are absent), so 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--dev` package to docker_build.sh +- create a manual IMPORTED target in the root CMakeLists following the + existing pattern there; do not extend the find_package component list, + it cannot succeed in the container +- define the availability macro (for example + `QT6_WEBSOCKETS_AVAILABLE`) via `add_compile_definitions` when the real + module is present +- link the target by name, for example `Qt6::WebSockets`, in the service + CMakeLists +- gate the compile macro and the link on the same condition. Beware legacy + gates such as `QT6_GUI_AVAILABLE AND TARGET Qt6::WebSockets`: GUI + availability never holds in the container, and the variable read + (`Qt6_WebSockets`) may never be defined, so code compiles against a + module that is not on the link line and fails only at shared-library + link time with undefined references + +Flipping a compile macro on an existing build dir leaves stale AUTOMOC +caches (moc files with void* signatures). A clean build dir is required +after flipping such macros; docker_build.sh does this by wiping build4. + +### Include shadowing between the stub tree and real generated headers + +An include like `` can resolve into the migration stub +tree (wrong namespaces, for example `DDS::Core::Interface`) instead of the +real generated header in the build tree. Use the full path from the +build-tree include root (``), add +`include_directories(BEFORE ${CMAKE_SOURCE_DIR}/Lts)` in the service +CMakeLists when stub trees shadow Lts headers, and verify forward +declarations name the same namespace as the real header +(`Core::Interface::Dtc`). + +### 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 (for example `#include "generic_fts.h"` in generic_fts_internal.h +or the `m_logger` member of DataManagerBaseDl). 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` +(LTS + SESSIONDATA). 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 so + a failing make piped through tee cannot be reported as success. +- 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. For + incremental builds before the full validation, replicate the container + setup manually (same /workspace mount, RTI_LICENSE_FILE, + QT_QPA_PLATFORM=offscreen) instead of editing docker_build.sh. + +## 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 +- if three meaningful tests are impossible, add the maximum meaningful set and explain why + +Preferred location: + +- ./qt-migration-legatus/qt6-after/qt6-migrated-legatus/tests + +Use policy-compatible names, for example: + +- test_.cpp +- _test.cpp +- test.cpp +- 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, submodules, required prompts, service paths, and forward-declaration directories. +2. Compare Qt5 source services with Qt6 targets. Classify files as already migrated, missing, stale, generated, intentionally removed, build-only, or needing Qt6 adaptation. +3. Identify dependencies, generated inputs, Qt modules, parent CMake entries, removed-module references, LogViewer interactions, and required stub/forward-declaration relocations. +4. Apply the smallest valid migration changes. +5. Add required CTest tests for C++ changes. +6. Review RTI, ndsgen, KTextTemplate, and Grantlee generation paths. +7. Check regressions: Qt5 links, removed modules, LogViewer, IDL warnings, source-tree generated consumption, stale artifacts, and misplaced stubs. +8. Validate in Docker with BUILD_RTI=ON and BUILD_GRANTLEE=ON. +9. Run CTest in the validated build directory. +10. Check Jenkins/policy compatibility. +11. 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: + +```bash +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 (currently 27, 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 — they are out +of migration scope. 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: + +```bash +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: + +```bash +./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: + +- all services named for this run migrated or confirmed already correct +- all named services included in the Qt6 build +- 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 the new tests and validation changes +- no active Qt5 imported target links remain for these services +- 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 +- RoutingServiceNG prompt rules are followed +- 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 +- services 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 +- confirmation that RoutingServiceNG prompt rules were followed +- exact validation commands and results +- result of ./docker-build.h if present +- remaining blockers or risks