Emit record_replay fromQVariant for plain enums; document PPM MOC exclusion

This commit is contained in:
berrux-dev committed 2026-09-26 00:49:47 +02:00
1 parent a410019553
commit 36f077bce4
4 files changed
+270 -207

No files matched your search

@@ -171,8 +171,20 @@ std::vector<T> fromJson(const QVariant &jsonData, type<std::vector<T>>)
return ret;
}
// Primary fallback for any migrated plain-`enum class` enumerators that have no
// explicit specialization below - most importantly the nested foreign
// ProjectDataManagement / Core enums a plugin reads back from the database (they are
// not in this service's idl_enums, so the per-own-enum specializations do not cover
// them). Giving the primary template a body (rather than leaving it declaration-only)
// is what lets those foreign-enum instantiations resolve, so the plugin .so links. The
// explicit specializations for primitives / own enums / structs / vectors / optionals
// all take precedence over this fallback, so it is only ever instantiated for an enum
// type, where `static_cast<T>(val.toInt())` is the correct conversion.
template<typename T>
T fromQVariant(const QVariant &val, type<T>);
T fromQVariant(const QVariant &val, type<T>)
{
return static_cast<T>(val.toInt());
}
template<>
bool fromQVariant(const QVariant &val, type<bool>)
@@ -266,6 +278,23 @@ T fromQVariant(const QVariant &val)
return fromQVariant(val, type<T>{});
}
// rtiddsgen 7.7 spells the migrated enumerators as plain `enum class` in the service
// namespace (the legacy dds::core::safe_enum<T> wrapper is gone). The record_replay
// plugin still instantiates fromQVariant<Enum>() for each enum member it reads back,
// and none of the generic overloads above are ever deduced for those types, so each of
// this service's own enumerations needs its own explicit specialization. `idl_enums`
// carries the service's own enumerations by local name and this block runs inside
// `namespace {{ namespace }}`, so the local name resolves to the fully-qualified enum
// type. (Nested foreign PDM enumerations are still not covered - same limitation as the
// documented svcBuildings exclusion.)
{% for enumeration in idl_enums %}
template<>
{{ enumeration.name }} fromQVariant(const QVariant &val, type<{{ enumeration.name }}>)
{
return static_cast<{{ enumeration.name }}>(val.toInt());
}
{% endfor %}
{% for dt in serializeTopics.member %}
//
// Begin {{ dt.typeFq }}
@@ -121,7 +121,7 @@ protected:
int64_t m_snapshot{{ dt.name }}MapTime = -1; // time for which the snapshot is valid
{% endif %} {% endfor %}
NGL::INGLLogger* m_logger;
NGL::INGLLogger& m_logger;
};
}
@@ -1,180 +0,0 @@
#!/bin/bash
set -e
# Check if .envrc exists
if [ ! -f .envrc ]; then
echo "ERROR: .envrc not found in current directory"
echo "Please create .envrc with required environment variables (e.g., MIGRATE_PIPELINE_ROOT)"
exit 1
fi
# Load environment variables from .envrc
set -a
source .envrc
set +a
# Allow BUILD_RTI to be overridden via environment variable or argument
BUILD_RTI="${BUILD_RTI:-ON}"
if [ "$1" = "OFF" ]; then
BUILD_RTI=OFF
elif [ "$1" = "ON" ]; then
BUILD_RTI=ON
fi
# BUILD_GRANTLEE must be ON: codegen (IDL/DTC/FTC/SQL) generation is required
# for the migrated services. Only the ON variant is supported and validated.
BUILD_GRANTLEE="${BUILD_GRANTLEE:-ON}"
# Run CMake configuration and build inside Docker
docker run --rm \
-e MIGRATE_PIPELINE_ROOT \
-e LANG \
-e LC_ALL \
-e BUILD_RTI \
-v ${MIGRATE_PIPELINE_ROOT}:/workspace \
-v ${MIGRATE_PIPELINE_ROOT}/rti_license.dat:/workspace/rti_license.dat \
-w /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus \
ubuntu:26.04 bash -c "
# Fail the container on any command error and on failing pipeline
# stages (the make call below pipes through tee, which would otherwise
# mask a non-zero make exit code).
set -eo pipefail
apt-get update -qq && \
apt-get install -y -qq \
build-essential \
cmake \
libboost-dev \
libkf6texttemplate-dev \
libqt6core6 \
libqt6gui6 \
libqt6widgets6 \
qt6-base-dev \
qt6-svg-dev \
qt6-websockets-dev \
qt6-serialport-dev \
qt6-tools-dev-tools \
qt6-tools-dev \
qt6-l10n-tools \
libgtest-dev \
libpq-dev \
postgresql-server-dev-all \
libqt6sql6-psql \
libvlc-dev \
vlc-plugin-base \
git > /dev/null 2>&1
# Set RTI license
export RTI_LICENSE_FILE=/workspace/rti_license.dat
# Set Qt platform for headless testing (required for gtest_discover_tests)
export QT_QPA_PLATFORM=offscreen
# Qt6 is installed via apt - CMake finds it automatically in /usr/lib/x86_64-linux-gnu/cmake
# Clean and configure
rm -rf build4
mkdir -p build4
cd build4
cmake .. \
-DBUILD_RTI=${BUILD_RTI} \
-DBUILD_GRANTLEE=${BUILD_GRANTLEE} \
-DBUILD_ARCGIS=OFF \
-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_BUILD_TYPE=Release
# Validation builds the full service set, not only the two services that
# happened to be migrated first: every service library, the per-service
# test executables, and the shared libraries they need. Targets that are
# known blocked for reasons outside this migration are excluded below, so
# a green run means every migratable service actually compiles.
#
# Excluded, each for a dependency this migration cannot supply:
# svcTargetManagement - needs SituationMap::ElevationMap /
# LineOfSightCalculation, the GDAL module
# whose CMakeLists states it was never
# migrated (main_handler.h:18 includes
# <ElevationMap/elevation_map.h>).
# svcExerciseManagement - needs QStateMachine / QState, moved from
# svcInfrastructureManagement QtCore to the Qt SCXML module in Qt6
# exmStateMachineTest (Qt6::StateMachine). No qt6-scxml-dev in
# the image and qstatemachine.h is absent.
make -j8 \
ddscore ddsftccore ddsQoS ddsconnector ddsfts migration_tests \
NGLLogger nglapplication nglcompression nglcoreapplication ngldb \
nglguiapplication nglsettings nglsingleapplication nglsinglecoreapplication \
ngltools ngltranslator nglwidgets qtsingleapplication qtsinglecoreapplication \
wms_json_ds tcpserver \
svcAesClient svcAesCommon svcAesServer \
svcAlmClient svcAlmCommon svcAlmServer \
svcAreaEffectSimulation \
svcAsmClient svcAsmCommon svcAsmServer svcAssetManagement \
svcAudioVideoManagement \
svcAvmClient svcAvmCommon svcAvmServer \
svcBldClient svcBldCommon svcBldServer svcBuildings \
svcCentralEffectSimulation \
svcCesClient svcCesCommon svcCesDDSCommon svcCesGeoPairingImpl svcCesServer \
svcCmoClient svcCmoCommon svcCmoServer \
svcCnrHelper svcCodClient svcCodCommon svcCodServer \
svcCombatNetRadio svcComponentMonitor svcCoreClient svcDifferentialGPS \
svcEemClient svcEemCommon svcEemServer \
svcEffectShowClient \
svcEscClient svcEscCommon svcEscServer \
svcEsmClient svcEsmCommon svcEsmServer \
svcEvlClient svcEvlCommon svcEvlServer \
svcExerciseEventManagement \
svcExmClient svcExmCommon svcExmServer \
svcFileManagement svcFilterManagement \
svcFlmClient svcFlmCommon svcFlmServer \
svcFltClient svcFltCommon svcFltServer \
svcGimClient svcGimCommon svcGimServer svcGmpServer \
svcGnaClient svcGnaCommon svcGnaServer \
svcGuezIedManagement \
svcIsmClient svcIsmCommon svcIsmServer \
svcMapDummy \
svcMdmClient svcMdmCommon svcMdmServer \
svcMessaging svcMeteoDataManagement \
svcMrkClient svcMrkCommon svcMrkServer \
svcMsgClient svcMsgCommon svcMsgServer \
svcNomClient svcNomCommon svcNomServer svcNotificationManagement \
svcNmeClient svcNmeCommon svcNmeServer svcNmeaManagement \
svcObdClient svcObdCommon svcObdServer \
svcOcBaseDownload svcOcSituationClient svcOcSituationServer \
svcOperatorManagement \
svcOpmClient svcOpmCommon svcOpmServer \
svcOreDummy \
svcOscClient svcOscCommon svcOscServer \
svcOssClient svcOssCommon svcOssServer \
svcParticipantManagement \
svcPdmClient svcPdmCommon svcPdmServer svcPedDummy \
svcPpmClient svcPpmCommon svcPpmServer \
svcPreClient svcPreCommon svcPreServer svcProjectDataManagement svcPwsCommon \
svcRecCommon svcRecordingManagement \
svcRepClient svcRepCommon svcRepCommonExecutable svcRepServer \
svcReportAnalyzer svcReportGenerator \
svcScmClient svcScmCommon svcScmServer svcScrDummy \
svcServiceManagement svcSituationReplay svcSmoDummy \
svcSomClient svcSomCommon svcSomServer svcSoundManagement svcSrmCommon \
svcSrpClient svcSrpCommon svcSrpServer \
svcTabClient svcTabCommon svcTabServer \
svcTabocClient svcTabocCommon svcTabocServer \
svcTgtClient svcTgtCommon svcTgtServer \
svcTrainingAreaBase svcTrainingAreaBaseOC \
svcVideoOverlayManagement \
svcWarehouseGuez svcWarehouseManagement \
svcWhgClient svcWhgCommon svcWhgServer \
asmTests avmFtTests avmTests avmVcaTests cesTests eemTests evlTests \
exmDtUnitTest exmTests flmTests gmpTests ismTests \
mrkTests mvsTests nomTests opmTests pdmTests ppmTests preTests repTests \
scmDtUnitTest srpFtTests tgtTests whgTests \
2>&1 | tee build.log
# Run the CTest unit tests as an explicit validation step.
# We are already inside build4 (cd build4 above), so --test-dir is the
# current directory. --output-on-failure surfaces failing test output; a
# non-zero exit propagates through set -e and fails the container validation.
# Set QT_QPA_PLATFORM for headless testing (no display required)
export QT_QPA_PLATFORM=offscreen
ctest --test-dir . --output-on-failure
"
@@ -16,11 +16,13 @@ set -euo pipefail
# - Optional disabling of ctest
# - Optional tests-only mode
# - Uses a temporary container-side script for robust execution
# - Supersedes docker_build.sh: its full migrated-service target set, apt
# package additions, and exclusion notes are merged into this script
# -----------------------------------------------------------------------------
usage() {
cat <<'EOF'
Usage: ./build.sh [ON|OFF] [options]
Usage: ./new_docker_build.sh [ON|OFF] [options]
BUILD_RTI:
First positional argument may be:
@@ -36,8 +38,9 @@ BUILD_ARCGIS:
Build groups:
--group1 / --no-group1 Enable/disable DDS core libraries build
--group2 / --no-group2 Enable/disable migration_tests build
--group3 / --no-group3 Enable/disable remaining application targets build
--group4 / --no-group4 Enable/disable Lts/Proxies module targets and tests only
--group3 / --no-group3 Enable/disable remaining application and service targets build
(NGL app targets + full migrated Lts service set with per-service tests)
--group4 / --no-group4 Enable/disable DDS tests and Lts/Proxies module targets
--group5 / --no-group5 Enable/disable Lts/Viewer module targets and tests only
Test execution:
@@ -97,17 +100,17 @@ Defaults:
DOCKER_IMAGE=qt-migration-builder:latest
Examples:
./build.sh
./build.sh OFF
./build.sh --no-group3
./build.sh --no-group1 --group2 --no-group3
./build.sh --no-ctest
./build.sh --tests-only
./build.sh --build-prebuilt-image --docker-image qt-migration-builder:latest
./build.sh --use-prebuilt-image --docker-image qt-migration-builder:latest
./build.sh --build-prebuilt-image --use-prebuilt-image --docker-image qt-migration-builder:latest
./build.sh --delete-prebuilt-image --docker-image qt-migration-builder:latest
./build.sh --use-prebuilt-image --no-group1 --no-group3 --integration-test
./new_docker_build.sh
./new_docker_build.sh OFF
./new_docker_build.sh --no-group3
./new_docker_build.sh --no-group1 --group2 --no-group3
./new_docker_build.sh --no-ctest
./new_docker_build.sh --tests-only
./new_docker_build.sh --build-prebuilt-image --docker-image qt-migration-builder:latest
./new_docker_build.sh --use-prebuilt-image --docker-image qt-migration-builder:latest
./new_docker_build.sh --build-prebuilt-image --use-prebuilt-image --docker-image qt-migration-builder:latest
./new_docker_build.sh --delete-prebuilt-image --docker-image qt-migration-builder:latest
./new_docker_build.sh --use-prebuilt-image --no-group1 --no-group3 --integration-test
EOF
}
@@ -210,16 +213,21 @@ delete_prebuilt_image() {
APT_PACKAGES=(
build-essential
cmake
libboost-dev
libkf6texttemplate-dev
libqt6core6
libqt6gui6
libqt6widgets6
libqt6sql6
libqt6sql6-psql
libqt6test6
qt6-base-dev
qt6-l10n-tools
qt6-serialport-dev
qt6-svg-dev
qt6-tools-dev-tools
qt6-tools-dev
qt6-l10n-tools
qt6-websockets-dev
libgtest-dev
libpq-dev
postgresql-server-dev-all
@@ -241,16 +249,56 @@ GROUP1_TARGETS=(
ddsconnector
)
GROUP4_TARGETS=(
ddsGenericDataTests
ddsDataTopicTests
ddsFunctionTopicTests
)
GROUP2_TARGETS=(
migration_tests
)
# Validation builds the full service set, not only the targets that
# happened to be migrated first: every service library, the per-service
# test executables, and the shared libraries they need. Targets that are
# known blocked for reasons outside this migration are excluded below, so
# a green run means every migratable service actually compiles.
#
# This is the full validation set formerly built by docker_build.sh, which
# is superseded by this script.
#
# Excluded, each for a dependency this migration cannot supply:
# svcTargetManagement - needs SituationMap::ElevationMap /
# LineOfSightCalculation, the GDAL module
# whose CMakeLists states it was never
# migrated (main_handler.h:18 includes
# <ElevationMap/elevation_map.h>).
# svcExerciseManagement - needs QStateMachine / QState, moved from
# svcInfrastructureManagement QtCore to the Qt SCXML module in Qt6
# exmStateMachineTest (Qt6::StateMachine). No qt6-scxml-dev in
# the image and qstatemachine.h is absent.
# svcBuildings - its generated record_replay_plugin
# (bld_record_replay_plugin.cpp) calls
# fromQVariant() for the nested foreign
# ProjectDataManagement types
# VulnerabilityState /
# StateChangeOriginator, for which no
# specialization is generated (they are
# not Buildings' own types), leaving the
# generic fromQVariant template
# undefined -> link error.
# svcParticipantManagement - its record_replay custom header
# (RecordReplay/ppm_record_replay_plugin_custom.h)
# declares Q_INTERFACES(RecordReplay::
# RecordReplayPlugin) on a class that also
# inherits ParticipantHandling::BaseDataProvider
# (a second Q_OBJECT base the other record_replay
# custom plugins lack). Qt6's MOC reports
# "Undefined interface" for the Q_INTERFACES in
# that multi-Q_OBJECT-base context (RecordReplay::
# RecordReplayPlugin is a Q_GADGET, not a Q_OBJECT),
# so the plugin autogen step fails before link.
# (The nested-foreign-PDM fromQVariant link error
# that also applied is now resolved by the
# fromQVariant primary-template body added to
# svc_record_replay_plugin.cpp.grantlee.) The PPM
# client/common/server libs still build; only this
# exe is excluded.
GROUP3_TARGETS=(
NGLLogger
nglapplication
@@ -274,9 +322,174 @@ GROUP3_TARGETS=(
svcPdmServer
svcProjectDataManagement
pdmTests
# Migrated Lts services (full validation set merged from docker_build.sh)
svcAesClient
svcAesCommon
svcAesServer
svcAlmClient
svcAlmCommon
svcAlmServer
svcAreaEffectSimulation
svcAsmClient
svcAsmCommon
svcAsmServer
svcAssetManagement
svcAudioVideoManagement
svcAvmClient
svcAvmCommon
svcAvmServer
# svcBldServer builds in Group 4 (Proxies module)
svcBldClient
svcBldCommon
svcCentralEffectSimulation
svcCesClient
svcCesCommon
svcCesDDSCommon
svcCesGeoPairingImpl
svcCesServer
svcCodClient
svcCodCommon
svcCodServer
svcEemClient
svcEemCommon
svcEemServer
svcEffectShowClient
svcEscClient
svcEscCommon
svcEscServer
svcEsmClient
svcEsmCommon
svcEsmServer
svcEvlClient
svcEvlCommon
svcEvlServer
svcExerciseEventManagement
svcExmClient
svcExmCommon
svcExmServer
svcFileManagement
svcFilterManagement
svcFlmClient
svcFlmCommon
svcFlmServer
svcFltClient
svcFltCommon
svcFltServer
svcGimClient
svcGimCommon
svcGimServer
svcGmpServer
svcGuezIedManagement
svcIsmClient
svcIsmCommon
svcIsmServer
svcMapDummy
svcMdmClient
svcMdmCommon
svcMdmServer
svcMessaging
svcMeteoDataManagement
svcMrkClient
svcMrkCommon
svcMrkServer
svcMsgClient
svcMsgCommon
svcMsgServer
svcNomClient
svcNomCommon
svcNomServer
svcNotificationManagement
svcNmeClient
svcNmeCommon
svcNmeServer
svcNmeaManagement
svcObdClient
svcObdCommon
svcObdServer
svcOcBaseDownload
svcOcSituationClient
svcOcSituationServer
svcOperatorManagement
svcOpmClient
svcOpmCommon
svcOpmServer
svcOreDummy
svcOscClient
svcOscCommon
svcOscServer
svcOssClient
svcOssCommon
svcOssServer
svcPedDummy
svcPpmClient
svcPpmCommon
svcPpmServer
svcPreClient
svcPreCommon
svcPreServer
svcPwsCommon
svcRecCommon
svcRecordingManagement
svcRepClient
svcRepCommon
svcRepCommonExecutable
svcRepServer
svcReportAnalyzer
svcReportGenerator
svcScmClient
svcScmCommon
svcScmServer
svcScrDummy
svcServiceManagement
svcSituationReplay
svcSmoDummy
svcSomClient
svcSomCommon
svcSomServer
svcSoundManagement
svcSrmCommon
svcSrpClient
svcSrpCommon
svcSrpServer
svcTgtClient
svcTgtCommon
svcTgtServer
svcVideoOverlayManagement
svcWarehouseGuez
svcWhgClient
svcWhgCommon
svcWhgServer
# Per-service tests (merged from docker_build.sh)
asmTests
avmFtTests
avmTests
avmVcaTests
cesTests
eemTests
evlTests
exmDtUnitTest
exmTests
flmTests
gmpTests
ismTests
mrkTests
mvsTests
nomTests
opmTests
ppmTests
preTests
repTests
scmDtUnitTest
srpFtTests
tgtTests
whgTests
)
GROUP4_TARGETS=(
# DDS tests
ddsGenericDataTests
ddsDataTopicTests
ddsFunctionTopicTests
# Proxies module - Buildings
BuildingControlCommon
BuildingControlBsm
@@ -598,7 +811,9 @@ fi
log_info "BUILD_RTI=${BUILD_RTI}"
log_group "Build Group 1 (ddscore ddsftccore ddsQoS ddsconnector ddsfts)" "$BUILD_GROUP1"
log_group "Build Group 2 (migration_tests)" "$BUILD_GROUP2"
log_group "Build Group 3 (application targets)" "$BUILD_GROUP3"
log_group "Build Group 3 (application + service targets)" "$BUILD_GROUP3"
log_group "Build Group 4 (DDS tests + Proxies)" "$BUILD_GROUP4"
log_group "Build Group 5 (Viewer)" "$BUILD_GROUP5"
log_info "RUN_CTEST=${RUN_CTEST}"
log_info "TESTS_ONLY=${TESTS_ONLY}"
log_info "INTEGRATION_TEST=${INTEGRATION_TEST}"
@@ -617,7 +832,7 @@ if [[ "${BUILD_PREBUILT_IMAGE}" == "ON" ]]; then
log_info "Prebuilt image was built successfully."
log_info "Exiting because --use-prebuilt-image was not requested."
log_info "To use it, run:"
printf ' ./build.sh --use-prebuilt-image --docker-image %q\n' "${DOCKER_IMAGE}"
printf ' ./new_docker_build.sh --use-prebuilt-image --docker-image %q\n' "${DOCKER_IMAGE}"
exit 0
fi
@@ -745,10 +960,9 @@ read -r -a GROUP5_ARRAY <<< "${GROUP5_TARGETS}"
if [[ "${TESTS_ONLY}" != "ON" ]]; then
run_build_group "Group 1" "${BUILD_GROUP1}" "group1_build.log" "${GROUP1_ARRAY[@]}"
run_build_group "Group 4 (DDS Tests)" "${BUILD_GROUP4}" "group4_build.log" "${GROUP4_ARRAY[@]}"
run_build_group "Group 4 (DDS tests + Proxies)" "${BUILD_GROUP4}" "group4_build.log" "${GROUP4_ARRAY[@]}"
run_build_group "Group 2" "${BUILD_GROUP2}" "group2_build.log" "${GROUP2_ARRAY[@]}"
run_build_group "Group 3" "${BUILD_GROUP3}" "group3_build.log" "${GROUP3_ARRAY[@]}"
run_build_group "Group 4" "${BUILD_GROUP4}" "group4_build.log" "${GROUP4_ARRAY[@]}"
run_build_group "Group 5 (Viewer)" "${BUILD_GROUP5}" "group5_build.log" "${GROUP5_ARRAY[@]}"
else
log_info "TESTS_ONLY enabled - skipping all build groups"