#!/usr/bin/env bash set -euo pipefail # ----------------------------------------------------------------------------- # Build helper for qt-migrated-legatus inside Docker # # Features: # - Loads environment from .envrc # - Validates MIGRATE_PIPELINE_ROOT and rti_license.dat # - BUILD_RTI controllable via first positional argument: ON|OFF # - BUILD_GRANTLEE controllable via --grantlee/--no-grantlee options # - 5 separately switchable make build groups # - Optional usage of a prebuilt Docker image with installed dependencies # - Optional creation of that prebuilt Docker image via --build-prebuilt-image # - Optional deletion of that prebuilt Docker image via --delete-prebuilt-image # - 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: ./new_docker_build.sh [ON|OFF] [options] BUILD_RTI: First positional argument may be: ON Enable BUILD_RTI OFF Disable BUILD_RTI BUILD_GRANTLEE: --grantlee / --no-grantlee Enable/disable BUILD_GRANTLEE (default: ON) BUILD_ARCGIS: --arcgis / --no-arcgis Enable/disable BUILD_ARCGIS (default: OFF) BUILD_CODIFICATION: --codification / --no-codification Enable/disable BUILD_CODIFICATION (default: ON, requires KDReports) BUILD_WLS: --wls / --no-wls Enable/disable BUILD_WLS (default: ON; the GROUP4 targets svcWirelessLocationSystem / wlsJsonClientTest only exist when it is ON) BUILD_FILTERMANAGEMENT: --filtermanagement / --no-filtermanagement Enable/disable BUILD_FILTERMANAGEMENT (default: ON) BUILD_PLUGINS_SERVICEMONITOR: --servicemonitor / --no-servicemonitor Enable/disable BUILD_PLUGINS_SERVICEMONITOR (default: ON) BUILD_WEBENGINE_PLUGINS: --webengine-plugins / --no-webengine-plugins Enable/disable the WebEngine-based plugins (PlanEditor, OnlineHelp, ParticipantOrgChart). PlanEditor links situationMap, so ON promotes BUILD_ARCGIS to ON. (default: ON) BUILD_XMLPATTERNS_PLUGINS: --xmlpatterns-plugins / --no-xmlpatterns-plugins Enable/disable the MSDL/Saab plugins. They no longer require Qt XmlPatterns (removed in Qt 6.0, not re-introduced): their import logic was re-implemented with Qt6::Xml (QDomDocument) + the existing xmllint step, and MSDL additionally links XercesC + uses xsdc++-generated tree classes (needs xsdcxx + libxerces-c-dev, both in APT_PACKAGES). With the prerequisites present these build by default. (default: ON) 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 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 --group6 / --no-group6 Enable/disable LTS Tools (Qt6 migration) build --group7 / --no-group7 Enable/disable LTS Tools Group 7 (A,B,C,E,I) build --group8 / --no-group8 Enable/disable LTS Tools Group 8 (J,M,N,P,Q) build --group9 / --no-group9 Enable/disable LTS Tools Group 9 (R,S,T,V,W) build --group10 / --no-group10 Enable/disable LTS Projects build --group11 / --no-group11 Enable/disable LTS Application build --group12 / --no-group12 Enable/disable runtime GUI/Data plugin build (OperatorApplication runtime deps) --build-viewer-only Build only Viewer module targets (skip Groups 1-4, implies --group5 --codification; ctest runs) Test execution: --no-ctest Skip ctest execution --tests-only Run only ctest, skip all make build groups --integration-test Run only integration tests (test_z_*, bld_*, tab_*, wls_*) Prebuilt Docker image usage: --use-prebuilt-image Use a Docker image with dependencies already installed --no-prebuilt-image Use base image and run apt-get install inside the container --docker-image IMAGE Docker image name to use/build/delete --cmake_build_flags FLAGS Extra CMake flags passed to the in-container configure (space-separated -D flags, e.g. "-DBUILD_WLS=ON -DGUEZ_MODE=ON") Prebuilt Docker image management: --build-prebuilt-image Build the prebuilt Docker image before running the build If used alone, the script builds the image and exits If combined with --use-prebuilt-image, the built image is used immediately --delete-prebuilt-image Delete the configured Docker image and exit Environment variable overrides: BUILD_RTI=ON|OFF BUILD_GRANTLEE=ON|OFF BUILD_ARCGIS=ON|OFF BUILD_CODIFICATION=ON|OFF BUILD_FILTERMANAGEMENT=ON|OFF BUILD_WLS=ON|OFF BUILD_PLUGINS_SERVICEMONITOR=ON|OFF BUILD_WEBENGINE_PLUGINS=ON|OFF BUILD_XMLPATTERNS_PLUGINS=ON|OFF BUILD_GROUP1=ON|OFF BUILD_GROUP2=ON|OFF BUILD_GROUP3=ON|OFF BUILD_GROUP4=ON|OFF BUILD_GROUP5=ON|OFF BUILD_GROUP6=ON|OFF BUILD_GROUP7=ON|OFF BUILD_GROUP8=ON|OFF BUILD_GROUP9=ON|OFF BUILD_GROUP10=ON|OFF BUILD_GROUP11=ON|OFF BUILD_GROUP12=ON|OFF RUN_CTEST=ON|OFF TESTS_ONLY=ON|OFF INTEGRATION_TEST=ON|OFF USE_PREBUILT_IMAGE=ON|OFF BUILD_PREBUILT_IMAGE=ON|OFF DELETE_PREBUILT_IMAGE=ON|OFF DOCKER_IMAGE= Required .envrc variable: MIGRATE_PIPELINE_ROOT= Expected file: ${MIGRATE_PIPELINE_ROOT}/rti_license.dat Defaults: BUILD_RTI=ON BUILD_GRANTLEE=ON BUILD_ARCGIS=OFF BUILD_CODIFICATION=ON BUILD_FILTERMANAGEMENT=ON BUILD_WLS=ON BUILD_PLUGINS_SERVICEMONITOR=ON BUILD_WEBENGINE_PLUGINS=ON BUILD_XMLPATTERNS_PLUGINS=ON BUILD_GROUP1=ON BUILD_GROUP2=ON BUILD_GROUP3=ON BUILD_GROUP4=OFF BUILD_GROUP5=OFF BUILD_GROUP6=OFF BUILD_GROUP7=OFF BUILD_GROUP8=OFF BUILD_GROUP9=OFF BUILD_GROUP10=OFF BUILD_GROUP11=OFF BUILD_GROUP12=OFF RUN_CTEST=ON TESTS_ONLY=OFF INTEGRATION_TEST=OFF USE_PREBUILT_IMAGE=OFF BUILD_PREBUILT_IMAGE=OFF DELETE_PREBUILT_IMAGE=OFF DOCKER_IMAGE=legatus-qt6-prebuilt:latest Examples: ./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 legatus-qt6-prebuilt:latest ./new_docker_build.sh --use-prebuilt-image --docker-image legatus-qt6-prebuilt:latest ./new_docker_build.sh --build-prebuilt-image --use-prebuilt-image --docker-image legatus-qt6-prebuilt:latest ./new_docker_build.sh --delete-prebuilt-image --docker-image legatus-qt6-prebuilt:latest ./new_docker_build.sh --use-prebuilt-image --no-group1 --no-group3 --integration-test EOF } log_info() { printf 'INFO: %s\n' "$*" } log_warn() { printf 'WARNING: %s\n' "$*" >&2 } log_error() { printf 'ERROR: %s\n' "$*" >&2 } die() { log_error "$*" exit 1 } require_command() { local cmd="$1" command -v "$cmd" >/dev/null 2>&1 || die "Required command not found: ${cmd}" } require_file() { local path="$1" local label="$2" [[ -f "$path" ]] || die "${label} not found: ${path}" } require_directory() { local path="$1" local label="$2" [[ -d "$path" ]] || die "${label} directory not found: ${path}" } require_non_empty() { local value="$1" local name="$2" [[ -n "$value" ]] || die "Required variable ${name} is not set or empty" } normalize_on_off() { local value="$1" local name="$2" case "${value^^}" in ON|OFF) printf '%s\n' "${value^^}" ;; *) die "Invalid value for ${name}: ${value}. Expected ON or OFF" ;; esac } log_group() { local group_name="$1" local enabled="$2" if [[ "$enabled" == "ON" ]]; then log_info "${group_name} enabled" else log_info "${group_name} disabled - skipping" fi } join_by() { local delimiter="$1" shift || true local first=1 local arg for arg in "$@"; do if [[ $first -eq 1 ]]; then printf '%s' "$arg" first=0 else printf '%s%s' "$delimiter" "$arg" fi done } cleanup_temp_dir() { local dir="${1:-}" if [[ -n "$dir" && -d "$dir" ]]; then rm -rf "$dir" fi } delete_prebuilt_image() { local image_name="$1" if docker image inspect "$image_name" >/dev/null 2>&1; then log_info "Deleting Docker image: ${image_name}" docker rmi "$image_name" log_info "Docker image deleted successfully: ${image_name}" else log_info "Docker image does not exist, nothing to delete: ${image_name}" fi } 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-websockets-dev libgtest-dev libpq-dev postgresql-server-dev-all libvlc-dev vlc-plugin-base git python3-pip # Poppler-Qt6 (PDF support): Z/src/nglwidgets detects it via # pkg_check_modules(POPPLER_QT6 poppler-qt6) - pkg-config must be present for # the probe to run at all. FlmExplorerGuiPlugin's flm_preview_playback.cpp # uses Poppler types unconditionally, so a green Group 12 build requires it. pkg-config libpoppler-qt6-dev # MSDL/Saab no longer require Qt XmlPatterns (removed in Qt 6.0): their import # logic was re-implemented with Qt6::Xml (QDomDocument) + the existing xmllint # schema-validation step. MSDL additionally links XercesC and uses xsdc++- # generated tree classes, so it needs libxerces-c-dev (XercesC C++ parser) and # xsdcxx (the xsdc++ code generator, XSD_GENERATE_TREE). Saab only needs # Qt6::Xml; both are installed together so the two plugins build from the same # image. xsdcxx libxerces-c-dev # xmllint (libxml2-utils): the MSDL import validates the incoming document against # its XSD via an external `xmllint --schema` step (QProcess) - pre-existing in the # legacy (msdl_import.cpp). Provision it so that runtime schema check can run. libxml2-utils ) # INTERFACE libraries (header-only) are built automatically as dependencies # Only list actual buildable targets (SHARED/STATIC libraries, executables) GROUP1_TARGETS=( ddscore svcCoreClient ddsftccore ddsfts ddsgen ddsQoS ddsconnector ) 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 # ). # 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 nglcompression nglcoreapplication ngldb nglguiapplication nglsettings nglsingleapplication nglsinglecoreapplication ngltools ngltranslator nglwidgets qtsingleapplication qtsinglecoreapplication wms_json_ds tcpserver # ProjectDataManagement svcPdmCommon svcPdmClient 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 BuildingControlTestBsm BuildingControlVwm BuildingControlTestVwm BuildingControlTestVwmXml # BuildingControlJson - requires Qt6WebSockets (not available) # ControlEffects - may depend on BuildingControlJson # ControlEffectsTest # BuildingControlUnit - depends on BuildingControlJson svcBldServer svcBuildings # Proxies module - TrainingAreaBase tabTelegrams svcTabCommon svcTabClient svcTabServer svcTrainingAreaBase # tabPluginInterface - defined in the CMake but no make rule is generated (base state) # TmsIfAdapterInterface/TmsIfAdapter/tabPluginUAS/TabUASTest3/TabUASTest4_2/TabUASTest6 # - only built with BUILD_UAS_PROXY=ON (default OFF, not exposed by this script) # tabPluginInterface # TmsIfAdapterInterface # TmsIfAdapter # tabPluginUAS # TabUASTest3 # TabUASTest4_2 # TabUASTest6 # Proxies module - TrainingAreaBaseOC svcTabocCommon svcTabocClient svcTabocServer svcTrainingAreaBaseOC serialtest # Proxies module - WirelessLocationSystem (only exists when BUILD_WLS=ON, # script default; see the --wls flag) svcWirelessLocationSystem wlsJsonClientTest # Proxies module - Other svcCmoCommon svcCmoClient svcCmoServer svcComponentMonitor svcCnrHelper svcCombatNetRadio svcDifferentialGPS svcGnaCommon svcGnaClient svcGnaServer svcWarehouseManagement Tetra_dgps_simulator ) APT_PACKAGES_STRING="$(join_by ' ' "${APT_PACKAGES[@]}")" build_prebuilt_image() { local image_name="$1" local tmp_dir tmp_dir="$(mktemp -d)" trap 'cleanup_temp_dir "$tmp_dir"' RETURN cat > "${tmp_dir}/Dockerfile" </dev/null || \ (git clone --depth 1 https://github.com/KDAB/KDReports.git /tmp/KDReports && \ cd /tmp/KDReports && \ mkdir build && cd build && \ cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_PREFIX_PATH=${QT_BASE_DIR} .. && \ make -j$(nproc) && \ make install && \ cd / && rm -rf /tmp/KDReports) # Legacy sources include but the Qt6 package installs headers flat # under /usr/local/include/KDReports-qt6 - alias the directory so the prefixed # includes resolve through the default /usr/local/include search path. RUN ln -sfn KDReports-qt6 /usr/local/include/KDReports # KDChart (KDAB, MIT) from source: FindKDChart RETURN()s without it, which skips # OreOnlineReportsGuiPlugin (app requirement iid ore.onlinereports). The legacy # env had a KDChart 2.6.0 Qt5 RPM; the Qt6 build needs a Qt6-compatible release. # Pinned to the verified kdchart-3.0.0 tag (KDChart_QT6=true; needs the # Gui/Widgets/PrintSupport/Svg Qt6 components above). ECM # (extra-cmake-modules) is required: KDChart plain-include()s ECMGeneratePriFile # for Qt > 6.2 and never find_package(ECM)s. RUN apt-get update -qq && \ apt-get install -y -qq extra-cmake-modules && \ rm -rf /var/lib/apt/lists/* && \ git clone --depth 1 --branch kdchart-3.0.0 https://github.com/KDAB/KDChart.git /tmp/KDChart && \ cmake -S /tmp/KDChart -B /tmp/KDChart/build \ -DKDChart_QT6=true -DKDChart_EXAMPLES=false -DKDChart_TESTS=false -DKDChart_DOCS=false \ -DCMAKE_PREFIX_PATH=${QT_BASE_DIR}/${QT_VERSION}/${QT_ARCH_DIR} \ -DCMAKE_MODULE_PATH=/usr/share/ECM/modules \ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local && \ cmake --build /tmp/KDChart/build -j$(nproc) && \ cmake --install /tmp/KDChart/build && \ ldconfig && \ rm -rf /tmp/KDChart # KDChart's Qt6 build installs headers under KDChart-qt6 (same -qt6 suffix # pattern as KDReports); legacy sources include the prefix. RUN ln -sfn KDChart-qt6 /usr/local/include/KDChart CMD ["/bin/bash"] EOF log_info "Building prebuilt Docker image: ${image_name}" docker build -t "${image_name}" "${tmp_dir}" log_info "Prebuilt Docker image created successfully: ${image_name}" } install_qt6_packages() { log_info "Installing Qt6 packages via aqtinstall" # Install aqtinstall if not available if ! command -v aqt &> /dev/null; then log_info "Installing aqtinstall via pip3" pip3 install --break-system-packages --quiet aqtinstall fi # Install Qt6 modules (same as app/Dockerfile) # Modules: qtmultimedia, qtserialport, qtimageformats, qtwebsockets, qtwebengine, # qtpdf, qtwebview, qt5compat, qtwebchannel, qtpositioning, qtlocation, qtsensors # Note: qtsvg is NOT available via aqtinstall - it's provided by libqt6svg6-dev apt package aqt install-qt linux desktop "${QT_VERSION:-6.10.2}" "${QT_ARCH:-linux_gcc_64}" \ -m qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine \ qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors \ --outputdir "${QT_BASE_DIR:-/opt/Qt}" log_info "Qt6 packages installed successfully" } require_command docker if [[ ! -f ".envrc" ]]; then die ".envrc not found in current directory. Please create .envrc with required environment variables (e.g., MIGRATE_PIPELINE_ROOT)" fi set -a # shellcheck disable=SC1091 source ".envrc" set +a BUILD_ALL="${BUILD_ALL:-ON}" BUILD_SV="${BUILD_SV:-ON}" BUILD_WS="${BUILD_WS:-ON}" BUILD_AAR="${BUILD_AAR:-ON}" BUILD_RTI="${BUILD_RTI:-ON}" BUILD_GRANTLEE="${BUILD_GRANTLEE:-ON}" BUILD_ARCGIS="${BUILD_ARCGIS:-OFF}" BUILD_CODIFICATION="${BUILD_CODIFICATION:-ON}" BUILD_FILTERMANAGEMENT="${BUILD_FILTERMANAGEMENT:-ON}" BUILD_WLS="${BUILD_WLS:-ON}" BUILD_PLUGINS_SERVICEMONITOR="${BUILD_PLUGINS_SERVICEMONITOR:-ON}" BUILD_WEBENGINE_PLUGINS="${BUILD_WEBENGINE_PLUGINS:-ON}" BUILD_XMLPATTERNS_PLUGINS="${BUILD_XMLPATTERNS_PLUGINS:-ON}" BUILD_GROUP1="${BUILD_GROUP1:-ON}" BUILD_GROUP2="${BUILD_GROUP2:-ON}" BUILD_GROUP3="${BUILD_GROUP3:-ON}" BUILD_GROUP4="${BUILD_GROUP4:-OFF}" BUILD_GROUP5="${BUILD_GROUP5:-OFF}" BUILD_GROUP6="${BUILD_GROUP6:-OFF}" BUILD_GROUP7="${BUILD_GROUP7:-OFF}" BUILD_GROUP8="${BUILD_GROUP8:-OFF}" BUILD_GROUP9="${BUILD_GROUP9:-OFF}" BUILD_GROUP10="${BUILD_GROUP10:-OFF}" BUILD_GROUP11="${BUILD_GROUP11:-OFF}" BUILD_VIEWER_ONLY="${BUILD_VIEWER_ONLY:-OFF}" RUN_CTEST="${RUN_CTEST:-ON}" TESTS_ONLY="${TESTS_ONLY:-OFF}" INTEGRATION_TEST="${INTEGRATION_TEST:-OFF}" USE_PREBUILT_IMAGE="${USE_PREBUILT_IMAGE:-OFF}" BUILD_PREBUILT_IMAGE="${BUILD_PREBUILT_IMAGE:-OFF}" DELETE_PREBUILT_IMAGE="${DELETE_PREBUILT_IMAGE:-OFF}" export QT_VERSION="${QT_VERSION:-6.10.2}" export QT_ARCH="${QT_ARCH:-linux_gcc_64}" # aqtinstall uses 'linux_gcc_64' but creates directory 'gcc_64' export QT_ARCH_DIR="${QT_ARCH_DIR:-gcc_64}" export QT_BASE_DIR="${QT_BASE_DIR:-/opt/Qt}" if [[ $# -gt 0 ]]; then case "$1" in ON|OFF) BUILD_RTI="$1" shift ;; esac fi while [[ $# -gt 0 ]]; do case "$1" in --group1) BUILD_GROUP1=ON ;; --no-group1) BUILD_GROUP1=OFF ;; --group2) BUILD_GROUP2=ON ;; --no-group2) BUILD_GROUP2=OFF ;; --group3) BUILD_GROUP3=ON ;; --no-group3) BUILD_GROUP3=OFF ;; --group4) BUILD_GROUP4=ON ;; --no-group4) BUILD_GROUP4=OFF ;; --group5) BUILD_GROUP5=ON ;; --no-group5) BUILD_GROUP5=OFF ;; --group6) BUILD_GROUP6=ON ;; --no-group6) BUILD_GROUP6=OFF ;; --group7) BUILD_GROUP7=ON ;; --no-group7) BUILD_GROUP7=OFF ;; --group8) BUILD_GROUP8=ON ;; --no-group8) BUILD_GROUP8=OFF ;; --group9) BUILD_GROUP9=ON ;; --no-group9) BUILD_GROUP9=OFF ;; --group10) BUILD_GROUP10=ON ;; --no-group10) BUILD_GROUP10=OFF ;; --group11) BUILD_GROUP11=ON ;; --no-group11) BUILD_GROUP11=OFF ;; --group12) BUILD_GROUP12=ON ;; --no-group12) BUILD_GROUP12=OFF ;; --build-viewer-only) BUILD_VIEWER_ONLY=ON BUILD_GROUP5=ON BUILD_CODIFICATION=ON RUN_CTEST=ON ;; --grantlee) BUILD_GRANTLEE=ON ;; --no-grantlee) BUILD_GRANTLEE=OFF ;; --arcgis) BUILD_ARCGIS=ON ;; --no-arcgis) BUILD_ARCGIS=OFF ;; --codification) BUILD_CODIFICATION=ON ;; --no-codification) BUILD_CODIFICATION=OFF ;; --wls) BUILD_WLS=ON ;; --no-wls) BUILD_WLS=OFF ;; --filtermanagement) BUILD_FILTERMANAGEMENT=ON ;; --no-filtermanagement) BUILD_FILTERMANAGEMENT=OFF ;; --servicemonitor) BUILD_PLUGINS_SERVICEMONITOR=ON ;; --no-servicemonitor) BUILD_PLUGINS_SERVICEMONITOR=OFF ;; --webengine-plugins) BUILD_WEBENGINE_PLUGINS=ON ;; --no-webengine-plugins) BUILD_WEBENGINE_PLUGINS=OFF ;; --xmlpatterns-plugins) BUILD_XMLPATTERNS_PLUGINS=ON ;; --no-xmlpatterns-plugins) BUILD_XMLPATTERNS_PLUGINS=OFF ;; --no-ctest) RUN_CTEST=OFF ;; --tests-only) TESTS_ONLY=ON ;; --integration-test) INTEGRATION_TEST=ON ;; --use-prebuilt-image) USE_PREBUILT_IMAGE=ON ;; --no-prebuilt-image) USE_PREBUILT_IMAGE=OFF ;; --build-prebuilt-image) BUILD_PREBUILT_IMAGE=ON ;; --delete-prebuilt-image) DELETE_PREBUILT_IMAGE=ON ;; --docker-image) shift [[ $# -gt 0 ]] || die "--docker-image requires an image name" DOCKER_IMAGE="$1" ;; --cmake_build_flags) shift [[ $# -gt 0 ]] || die "--cmake_build_flags requires a flag string" CMAKE_BUILD_FLAGS="$1" ;; -h|--help) usage exit 0 ;; *) usage die "Unknown option: $1" ;; esac shift done # Set defaults for variables not set by command-line arguments BUILD_RTI="${BUILD_RTI:-ON}" BUILD_GROUP1="${BUILD_GROUP1:-ON}" BUILD_GROUP2="${BUILD_GROUP2:-ON}" BUILD_GROUP3="${BUILD_GROUP3:-ON}" BUILD_GROUP4="${BUILD_GROUP4:-OFF}" BUILD_GROUP5="${BUILD_GROUP5:-OFF}" BUILD_GROUP6="${BUILD_GROUP6:-OFF}" BUILD_GROUP7="${BUILD_GROUP7:-OFF}" BUILD_GROUP8="${BUILD_GROUP8:-OFF}" BUILD_GROUP9="${BUILD_GROUP9:-OFF}" BUILD_GROUP10="${BUILD_GROUP10:-OFF}" BUILD_GROUP11="${BUILD_GROUP11:-OFF}" RUN_CTEST="${RUN_CTEST:-ON}" TESTS_ONLY="${TESTS_ONLY:-OFF}" INTEGRATION_TEST="${INTEGRATION_TEST:-OFF}" USE_PREBUILT_IMAGE="${USE_PREBUILT_IMAGE:-OFF}" BUILD_PREBUILT_IMAGE="${BUILD_PREBUILT_IMAGE:-OFF}" DELETE_PREBUILT_IMAGE="${DELETE_PREBUILT_IMAGE:-OFF}" BUILD_ALL="$(normalize_on_off "$BUILD_ALL" "BUILD_ALL")" BUILD_RTI="$(normalize_on_off "$BUILD_RTI" "BUILD_RTI")" BUILD_GRANTLEE="$(normalize_on_off "$BUILD_GRANTLEE" "BUILD_GRANTLEE")" BUILD_ARCGIS="$(normalize_on_off "$BUILD_ARCGIS" "BUILD_ARCGIS")" BUILD_CODIFICATION="$(normalize_on_off "$BUILD_CODIFICATION" "BUILD_CODIFICATION")" BUILD_FILTERMANAGEMENT="$(normalize_on_off "$BUILD_FILTERMANAGEMENT" "BUILD_FILTERMANAGEMENT")" BUILD_WLS="$(normalize_on_off "$BUILD_WLS" "BUILD_WLS")" BUILD_PLUGINS_SERVICEMONITOR="$(normalize_on_off "$BUILD_PLUGINS_SERVICEMONITOR" "BUILD_PLUGINS_SERVICEMONITOR")" BUILD_WEBENGINE_PLUGINS="$(normalize_on_off "$BUILD_WEBENGINE_PLUGINS" "BUILD_WEBENGINE_PLUGINS")" BUILD_XMLPATTERNS_PLUGINS="$(normalize_on_off "$BUILD_XMLPATTERNS_PLUGINS" "BUILD_XMLPATTERNS_PLUGINS")" # PlanEditorGuiPlugin links situationMap (ArcGIS scope), so the WebEngine plugin # set cannot configure without ArcGIS: promote BUILD_ARCGIS when it is enabled. if [[ "${BUILD_WEBENGINE_PLUGINS}" == "ON" && "${BUILD_ARCGIS}" == "OFF" ]]; then log_info "BUILD_WEBENGINE_PLUGINS=ON implies ArcGIS-scope targets (PlanEditorGuiPlugin -> situationMap): promoting BUILD_ARCGIS=ON" BUILD_ARCGIS=ON fi BUILD_GROUP1="$(normalize_on_off "$BUILD_GROUP1" "BUILD_GROUP1")" BUILD_GROUP2="$(normalize_on_off "$BUILD_GROUP2" "BUILD_GROUP2")" BUILD_GROUP3="$(normalize_on_off "$BUILD_GROUP3" "BUILD_GROUP3")" BUILD_GROUP4="$(normalize_on_off "$BUILD_GROUP4" "BUILD_GROUP4")" BUILD_GROUP5="$(normalize_on_off "$BUILD_GROUP5" "BUILD_GROUP5")" BUILD_GROUP6="$(normalize_on_off "$BUILD_GROUP6" "BUILD_GROUP6")" BUILD_GROUP7="$(normalize_on_off "$BUILD_GROUP7" "BUILD_GROUP7")" BUILD_GROUP8="$(normalize_on_off "$BUILD_GROUP8" "BUILD_GROUP8")" BUILD_GROUP9="$(normalize_on_off "$BUILD_GROUP9" "BUILD_GROUP9")" BUILD_GROUP10="$(normalize_on_off "$BUILD_GROUP10" "BUILD_GROUP10")" BUILD_GROUP11="$(normalize_on_off "$BUILD_GROUP11" "BUILD_GROUP11")" BUILD_VIEWER_ONLY="$(normalize_on_off "$BUILD_VIEWER_ONLY" "BUILD_VIEWER_ONLY")" RUN_CTEST="$(normalize_on_off "$RUN_CTEST" "RUN_CTEST")" TESTS_ONLY="$(normalize_on_off "$TESTS_ONLY" "TESTS_ONLY")" INTEGRATION_TEST="$(normalize_on_off "$INTEGRATION_TEST" "INTEGRATION_TEST")" USE_PREBUILT_IMAGE="$(normalize_on_off "$USE_PREBUILT_IMAGE" "USE_PREBUILT_IMAGE")" BUILD_PREBUILT_IMAGE="$(normalize_on_off "$BUILD_PREBUILT_IMAGE" "BUILD_PREBUILT_IMAGE")" DELETE_PREBUILT_IMAGE="$(normalize_on_off "$DELETE_PREBUILT_IMAGE" "DELETE_PREBUILT_IMAGE")" # Set DOCKER_IMAGE default after argument parsing if [[ "${USE_PREBUILT_IMAGE}" == "ON" ]]; then DOCKER_IMAGE="${DOCKER_IMAGE:-legatus-qt6-prebuilt:latest}" else DOCKER_IMAGE="${DOCKER_IMAGE:-ubuntu:26.04}" fi # Default for extra CMake flags (set via --cmake_build_flags or environment) CMAKE_BUILD_FLAGS="${CMAKE_BUILD_FLAGS:-}" # Export variables for Docker container export BUILD_ALL BUILD_RTI BUILD_GRANTLEE BUILD_ARCGIS BUILD_CODIFICATION BUILD_FILTERMANAGEMENT BUILD_WLS BUILD_PLUGINS_SERVICEMONITOR BUILD_WEBENGINE_PLUGINS BUILD_XMLPATTERNS_PLUGINS BUILD_GROUP1 BUILD_GROUP2 BUILD_GROUP3 BUILD_GROUP4 BUILD_GROUP5 BUILD_GROUP6 BUILD_GROUP7 BUILD_GROUP8 BUILD_GROUP9 BUILD_GROUP10 BUILD_GROUP11 BUILD_GROUP12 BUILD_VIEWER_ONLY RUN_CTEST TESTS_ONLY INTEGRATION_TEST USE_PREBUILT_IMAGE BUILD_PREBUILT_IMAGE DELETE_PREBUILT_IMAGE DOCKER_IMAGE CMAKE_BUILD_FLAGS # Group 5: Viewer module targets (conditional on BUILD_ARCGIS) # Note: LtsFileDialog excluded from viewer-only builds due to Group 4 dependencies (svcExmCommon, svcOpmCommon, svcFlmCommon) if [[ "${BUILD_ARCGIS}" == "ON" ]]; then if [[ "${BUILD_VIEWER_ONLY}" == "ON" ]]; then # Viewer-only build: exclude LtsFileDialog (requires Group 4 services) GROUP5_TARGETS=( # Viewer module with ArcGIS (viewer-only subset) situationMapCommon advancedSymbology advancedSymbologyXML LtsDataView LtsDataViewTest ) else GROUP5_TARGETS=( # Viewer module with ArcGIS (full build) situationMapCommon advancedSymbology advancedSymbologyXML LtsDataView LtsDataViewTest LtsFileDialog LtsFileDialogTest ) fi else if [[ "${BUILD_VIEWER_ONLY}" == "ON" ]]; then # Viewer-only build: exclude LtsFileDialog (requires Group 4 services) GROUP5_TARGETS=( # Viewer module without ArcGIS (viewer-only subset, advancedSymbology requires ArcGIS) situationMapCommon advancedSymbologyXML LtsDataView LtsDataViewTest ) else GROUP5_TARGETS=( # Viewer module without ArcGIS (full build) situationMapCommon advancedSymbologyXML LtsDataView LtsDataViewTest LtsFileDialog LtsFileDialogTest ) fi fi # LtsReportDisplay only exists when BUILD_CODIFICATION=ON (the module # RETURN()s otherwise); requesting the target unconditionally aborts make # with "No rule to make target" if [[ "${BUILD_CODIFICATION}" == "ON" ]]; then GROUP5_TARGETS+=("LtsReportDisplay") fi # Group 6: LTS Tools (Qt6 migration targets) # These tools require RTI DDS for DataSampleGenerator, DataSampleReceiver, and DdsView GROUP6_TARGETS=( dbAdministration SettingsRemover dbUpdate tDataSampleGenerator tDataSampleReceiver DateTimeSyncer ddsview # ddsview runtime topic-type plugins (39 *TopicTypePlugin.so). Not CMake link deps of # ddsview (loaded at runtime via LtsPluginLoader), so `make ddsview` alone skips them and # ddsview shows empty Data/Function topic lists. Built here alongside ddsview. aesTopicTypePlugin almTopicTypePlugin asmTopicTypePlugin avmTopicTypePlugin bldTopicTypePlugin cesTopicTypePlugin cmoTopicTypePlugin codTopicTypePlugin coreTopicTypePlugin eemTopicTypePlugin escTopicTypePlugin esmTopicTypePlugin evlTopicTypePlugin exmTopicTypePlugin flmTopicTypePlugin fltTopicTypePlugin gimTopicTypePlugin gnaTopicTypePlugin ismTopicTypePlugin mdmTopicTypePlugin mrkTopicTypePlugin msgTopicTypePlugin nmeTopicTypePlugin nomTopicTypePlugin obdTopicTypePlugin opmTopicTypePlugin oscTopicTypePlugin ossTopicTypePlugin pdmTopicTypePlugin ppmTopicTypePlugin preTopicTypePlugin repTopicTypePlugin scmTopicTypePlugin somTopicTypePlugin srpTopicTypePlugin tabTopicTypePlugin tabocTopicTypePlugin tgtTopicTypePlugin whgTopicTypePlugin displayPanelSimulator LicenceEditor localDomainFinder LogView LogViewer CoPrtCnv PrtCnvLib PrtCnv ) # Group 7: LTS Tools A,B,C,E,I directories (Qt6 migration targets) GROUP7_TARGETS=( AdlerWebSocketSimulator # AsmWorkstationCertifier - requires botan2 (not available in prebuilt image); target not generated CnrProxyTester ConfigX EEMFakeServer egcuSimulator ) # Group 8: LTS Tools J,M,N,P,Q directories (Qt6 migration targets) GROUP8_TARGETS=( ParticipantDataGenerator ProjectSettingsEditor qledline qledmatrix ) # Group 9: LTS Tools R,S,T,V,W directories (Qt6 migration targets) GROUP9_TARGETS=( RestClientUi ScreenIdShow SerialToTcpConverter Splash sqlbrowser textEditorTest ctime stime topicdiscover topicdiscoverexe # TrajectoryWidget - standalone sub-project (own project()/find_package), not part of the main build vapixconfig # VideoImport - subdir commented out in Lts/Tools/CMakeLists.txt wlsRandomPositions ) # Group 10: LTS Projects (Qt6 migration targets) GROUP10_TARGETS=( ProjectGuezPlugin ProjectQatarMOUTPlugin ProjectQatarPlugin ProjectLegatusPlugin ProjectDemoTabletPlugin ProjectL400P2Plugin ProjectComMasterPlugin ProjectAhtcPlugin ProjectEtsPlugin ) # Group 11: LTS Application (Qt6 migration targets) GROUP11_TARGETS=( OperatorApplication # thp_viewer - Lts/Application/THP subdir commented out (VLC dependency unavailable) aarApp ) # Group 12: runtime GUI/Data plugins. OperatorApplication's plugin loader # (Lts/Common/LtsPluginManager/lts_plugin_loader.cpp) scans /../lib for # *Plugin*.so and matches the IID metadata against apps.json plugin requirements; # without these the app reports "App Requirements check failed" at startup. # Plugin outputs land in build4/lib, the directory the loader scans. # Excluded (environmental floors, not migration regressions): # cesPluginGeoPairing - needs the external Schusstafel package (prebuilt # Schusstafel.h + libSchusstafel.so) at # external/Schusstafel (see resolve_schusstafel); it is # built when the package is present # OreOnlineReportsGuiPlugin - needs KDChart (open-source, KDAB) under # /usr/local; built from github.com/KDAB/KDChart tag # kdchart-3.0.0 with -DKDChart_QT6=true (see # resolve_kdchart), built when present # BldInfoGuiPlugin - links BuildingViewerCommon (dtEntity/OSG SDK absent) # BdvViewerGuiPlugin - links BuildingViewerCommon (same floor; CMake skips its # subdirectory when BuildingViewerCommon is not built) # PpmMSDLGuiPlugin / - former XmlPatterns floor, now CLOSED: re-implemented without # PpmSAABGuiPlugin - Qt XmlPatterns (removed in Qt 6.0) using Qt6::Xml (QDomDocument) # + the existing xmllint step; MSDL also needs xsdcxx + # libxerces-c-dev (both in APT_PACKAGES). Now in GROUP12 and built # by default when the prerequisites are present (see # resolve_xmlpatterns) # The Flt*/Smo* targets only exist when BUILD_FILTERMANAGEMENT / # BUILD_PLUGINS_SERVICEMONITOR are ON (script defaults; see the cmake call). # With them OFF the five unconditional GUI plugins (EvlEdit, PpmParticipantInfo, # Pws, SrmReplayManagement, OpmSettings) also fail to link (they need the # FilterManagement interface libs) - so these defaults are load-bearing. # The PlanEditorGuiPlugin/OhpOnlineHelpViewerGuiPlugin/PpmOrgChartGuiPlugin # targets only exist when BUILD_WEBENGINE_PLUGINS=ON (script default; ON also # promotes BUILD_ARCGIS=ON because PlanEditorGuiPlugin links situationMap), # and the Cod*/codTopicTypePlugin targets when BUILD_CODIFICATION=ON (script # default; requires KDReports). GROUP12_TARGETS=( AesAirSupportGuiPlugin AesBcContaminationGuiPlugin AesBorderlineGuiPlugin AesChargeAdministrationGuiPlugin AesChargeEffectGuiPlugin AesDangerAreaGuiPlugin AesDataPlugin AesExplosionGuiPlugin AesFunctionalAreaGuiPlugin AesGasPipeGuiPlugin AesInfoGuiPlugin AesMineAreaGuiPlugin AesMineCorridorGuiPlugin AesMineSingleVirtualGuiPlugin AesNContaminationGuiPlugin AesTechnicalAreaGuiPlugin AlmConfigAlarmGuiPlugin AlmDataPlugin AlmEmergencyCallGuiPlugin AlmOnlineReportsGuiPlugin AppStarterGuiPlugin AsbDataPlugin AsbForeignDataPluginThp AsbSymEditGuiPlugin AsbSymbolProxyGuiPlugin AsmDataPlugin AsmGuiPlugin AvmDataPlugin AvmElokaGuiPlugin BatGuiPlugin BldDataPlugin CdsSimulationGuiPlugin CesDataPlugin CesParticipantMoveGuiPlugin CesParticipantUASGuiPlugin CmoDataPlugin CodCodificationDataGuiPlugin CodDataPlugin DevGuiPlugin EfmDataPlugin EfmSoundAreaGuiPlugin EscDataPlugin EscEffectShowGuiPlugin EsmComboBoxGuiPlugin EsmDataPlugin EsmEffectShowGuiPlugin EvlDataPlugin EvlEditGuiPlugin EvlSanNineLinerEditGuiPlugin ExmDataPlugin ExmEditGuiPlugin ExmWatchGuiPlugin FlmComboBoxGuiPlugin FlmDataPlugin FlmExplorerGuiPlugin FltAesGuiPlugin FltDataPlugin FltParticipantGuiPlugin Fltbldg_cmpntGuiPlugin FspGuiPlugin GimDataPlugin GimInfoGuiPlugin GimPairingGuiPlugin GnaDataPlugin GnaNasatGuiPlugin GnaNasatPartGuiPlugin GuiElementPlugin IsmAvcGuiPlugin IsmComboBoxGuiPlugin IsmDataPlugin IsmDataPluginThp IsmExerciseAssignmentClassicGuiPlugin IsmResGuiPlugin MdmDataPlugin MdmMeteoDataGuiPlugin MrkDataPlugin MrkEditGuiPlugin MsgDataPlugin MsgMessageingGuiPlugin MvsVideoTeamGuiPlugin NmeNotificationGuiPlugin NomDataPlugin NomEditGuiPlugin ObdBaseDownloaderGuiPlugin ObdDataPlugin OhpOnlineHelpViewerGuiPlugin OpmComboBoxGuiPlugin OpmDataPlugin OpmEditGuiPlugin OpmLoginGuiPlugin OpmOverviewGuiPlugin OpmSettingsGuiPlugin OreOnlineReportsGuiPlugin OscDataPlugin OscParticipantInfoGuiPlugin OscSystemGuiPlugin OscTerminalGuiPlugin PdmChargeTableGuiPlugin PdmComboBoxGuiPlugin PdmDataPlugin PlanEditorGuiPlugin PlanOverlaysGuiPlugin PpmComboBoxGuiPlugin PpmDataPlugin PpmMSDLGuiPlugin PpmOperationalPlaningGuiPlugin PpmOrgChartGuiPlugin PpmParticipantEditGuiPlugin PpmParticipantInfoGuiPlugin PpmParticipantTemplatesGuiPlugin PpmPartyEditGuiPlugin PpmSAABGuiPlugin PpmTypeEditGuiPlugin PpmUasGuiPlugin PreDataPlugin PreEditGuiPlugin PreScriptTimelineGuiPlugin ProjectAhtcPlugin ProjectComMasterPlugin ProjectDemoTabletPlugin ProjectEtsPlugin ProjectGuezPlugin ProjectL400P2Plugin ProjectLegatusPlugin ProjectQatarMOUTPlugin ProjectQatarPlugin PwsGuiPlugin RecordReplayPlugin RepDataPlugin RmeDarkStylePlugin RmeLightStylePlugin SaaDataPlugin SaaGuiPlugin ScmDataPlugin ScmEditGuiPlugin ScrScreenRecordingGuiPlugin SitmapGuiPlugin SituationMapScriptFilterGuiPlugin SmoEquipmentErrorRegistrationGuiPlugin SmoHgrAndMineSearchGuiPlugin SmoMonitorsGuiPlugin SmoSystemMonitorGuiPlugin SrmDataPlugin SrmReplayManagementGuiPlugin SrpDataPlugin SrpReplayControlGuiPlugin TabDataPlugin TabNotificationGuiPlugin TabOcSfmMessagingGuiPlugin TabocDataPlugin TabocGuiPlugin TgtDataPlugin TgtTargetGuiPlugin Thp2ManagementGuiPlugin Thp2UsbManagementGuiPlugin TlnDataPlugin TlnEventTimelineGuiPlugin VkbPlugin WhmDataPlugin WhmGuiPlugin aesRecordReplayPlugin aesTopicTypePlugin almRecordReplayPlugin almTopicTypePlugin asmTopicTypePlugin avmCombatNetRadioGuiPlugin avmMenuEditGuiPlugin avmTopicTypePlugin avmTrainingVoiceGuiPlugin bldRecordReplayPlugin bldTopicTypePlugin cesPluginArtillerySound cesPluginBasic cesPluginCES_FunctionalAreas cesPluginCES_Jamming cesPluginCES_MissionPlan cesPluginCES_NBC cesPluginCesBuildings cesPluginExplosions cesPluginGeoPairing cesPluginMineAreas cesPluginMineLayingArtillery cesPluginParticipantBuildings cesPluginVirtualMines cesRecordReplayPlugin cesTopicTypePlugin cmoTopicTypePlugin codTopicTypePlugin coreTopicTypePlugin eemTopicTypePlugin escTopicTypePlugin esmTopicTypePlugin evlTopicTypePlugin exmTopicTypePlugin flmTopicTypePlugin fltTopicTypePlugin gimRecordReplayPlugin gimTopicTypePlugin gnaRecordReplayPlugin gnaTopicTypePlugin ismTopicTypePlugin ltswidgetsplugin mdmTopicTypePlugin mrkTopicTypePlugin msgTopicTypePlugin nmeTopicTypePlugin nomTopicTypePlugin obdTopicTypePlugin opmTopicTypePlugin oscTopicTypePlugin ossRecordReplayPlugin ossTopicTypePlugin pdmTopicTypePlugin ppmRecordReplayPlugin ppmTopicTypePlugin preTopicTypePlugin repTopicTypePlugin scmTopicTypePlugin somTopicTypePlugin srpTopicTypePlugin tabPluginAdler tabPluginDebugJsonDir tabPluginHla tabPluginWlsTetra tabRecordReplayPlugin tabTopicTypePlugin tabocTopicTypePlugin tgtTopicTypePlugin whgTopicTypePlugin ) require_non_empty "${DOCKER_IMAGE}" "DOCKER_IMAGE" if [[ "${DELETE_PREBUILT_IMAGE}" == "ON" ]]; then delete_prebuilt_image "${DOCKER_IMAGE}" exit 0 fi require_non_empty "${MIGRATE_PIPELINE_ROOT:-}" "MIGRATE_PIPELINE_ROOT" require_directory "${MIGRATE_PIPELINE_ROOT}" "MIGRATE_PIPELINE_ROOT" RTI_LICENSE_FILE_HOST="${MIGRATE_PIPELINE_ROOT}/rti_license.dat" WORKSPACE_ROOT_HOST="${MIGRATE_PIPELINE_ROOT}" PROJECT_DIR_HOST="${WORKSPACE_ROOT_HOST}/qt-migration-legatus/qt6-after/qt6-migrated-legatus" require_file "${RTI_LICENSE_FILE_HOST}" "RTI license file" require_directory "${PROJECT_DIR_HOST}" "Project directory" if [[ "$TESTS_ONLY" == "ON" ]]; then BUILD_GROUP1=OFF BUILD_GROUP2=OFF BUILD_GROUP3=OFF RUN_CTEST=ON 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 + service targets)" "$BUILD_GROUP3" log_group "Build Group 4 (DDS tests + Proxies)" "$BUILD_GROUP4" log_group "Build Group 5 (Viewer)" "$BUILD_GROUP5" log_group "Build Group 6 (LTS Tools)" "$BUILD_GROUP6" log_group "Build Group 7 (LTS Tools A,B,C,E,I)" "$BUILD_GROUP7" log_group "Build Group 8 (LTS Tools J,M,N,P,Q)" "$BUILD_GROUP8" log_group "Build Group 9 (LTS Tools R,S,T,V,W)" "$BUILD_GROUP9" log_group "Build Group 10 (LTS Projects)" "$BUILD_GROUP10" log_group "Build Group 11 (LTS Application)" "$BUILD_GROUP11" log_group "Build Group 12 (GUI/Data Plugins)" "$BUILD_GROUP12" log_info "BUILD_VIEWER_ONLY=${BUILD_VIEWER_ONLY}" log_info "RUN_CTEST=${RUN_CTEST}" log_info "TESTS_ONLY=${TESTS_ONLY}" log_info "INTEGRATION_TEST=${INTEGRATION_TEST}" log_info "USE_PREBUILT_IMAGE=${USE_PREBUILT_IMAGE}" log_info "BUILD_PREBUILT_IMAGE=${BUILD_PREBUILT_IMAGE}" log_info "DELETE_PREBUILT_IMAGE=${DELETE_PREBUILT_IMAGE}" log_info "DOCKER_IMAGE=${DOCKER_IMAGE}" log_info "MIGRATE_PIPELINE_ROOT=${MIGRATE_PIPELINE_ROOT}" log_info "RTI_LICENSE_FILE_HOST=${RTI_LICENSE_FILE_HOST}" log_info "PROJECT_DIR_HOST=${PROJECT_DIR_HOST}" if [[ "${BUILD_PREBUILT_IMAGE}" == "ON" ]]; then build_prebuilt_image "${DOCKER_IMAGE}" if [[ "${USE_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 ' ./new_docker_build.sh --use-prebuilt-image --docker-image %q\n' "${DOCKER_IMAGE}" exit 0 fi log_info "Continuing with freshly built prebuilt image: ${DOCKER_IMAGE}" fi GROUP1_TARGETS_STRING="$(join_by ' ' "${GROUP1_TARGETS[@]}")" GROUP2_TARGETS_STRING="$(join_by ' ' "${GROUP2_TARGETS[@]}")" GROUP3_TARGETS_STRING="$(join_by ' ' "${GROUP3_TARGETS[@]}")" GROUP4_TARGETS_STRING="$(join_by ' ' "${GROUP4_TARGETS[@]}")" GROUP5_TARGETS_STRING="$(join_by ' ' "${GROUP5_TARGETS[@]}")" GROUP6_TARGETS_STRING="$(join_by ' ' "${GROUP6_TARGETS[@]}")" GROUP7_TARGETS_STRING="$(join_by ' ' "${GROUP7_TARGETS[@]}")" GROUP8_TARGETS_STRING="$(join_by ' ' "${GROUP8_TARGETS[@]}")" GROUP9_TARGETS_STRING="$(join_by ' ' "${GROUP9_TARGETS[@]}")" GROUP10_TARGETS_STRING="$(join_by ' ' "${GROUP10_TARGETS[@]}")" GROUP11_TARGETS_STRING="$(join_by ' ' "${GROUP11_TARGETS[@]}")" GROUP12_TARGETS_STRING="$(join_by ' ' "${GROUP12_TARGETS[@]}")" HOST_TEMP_DIR="$(mktemp -d)" CONTAINER_SCRIPT_HOST="${HOST_TEMP_DIR}/run-build-inside-container.sh" cleanup_all() { cleanup_temp_dir "${HOST_TEMP_DIR}" } trap cleanup_all EXIT cat > "${CONTAINER_SCRIPT_HOST}" <<'EOF' #!/usr/bin/env bash set -euo pipefail # Default variable assignments to prevent unbound variable errors USE_PREBUILT_IMAGE="${USE_PREBUILT_IMAGE:-OFF}" BUILD_ALL="${BUILD_ALL:-ON}" BUILD_SV="${BUILD_SV:-ON}" BUILD_WS="${BUILD_WS:-ON}" BUILD_AAR="${BUILD_AAR:-ON}" BUILD_RTI="${BUILD_RTI:-ON}" BUILD_GRANTLEE="${BUILD_GRANTLEE:-ON}" BUILD_ARCGIS="${BUILD_ARCGIS:-OFF}" WITH_SCHUSSTAFEL="${WITH_SCHUSSTAFEL:-ON}" BUILD_GROUP1="${BUILD_GROUP1:-ON}" BUILD_GROUP2="${BUILD_GROUP2:-ON}" BUILD_GROUP3="${BUILD_GROUP3:-ON}" BUILD_GROUP4="${BUILD_GROUP4:-OFF}" BUILD_GROUP5="${BUILD_GROUP5:-OFF}" BUILD_GROUP6="${BUILD_GROUP6:-OFF}" BUILD_GROUP7="${BUILD_GROUP7:-OFF}" BUILD_GROUP8="${BUILD_GROUP8:-OFF}" BUILD_GROUP9="${BUILD_GROUP9:-OFF}" BUILD_GROUP10="${BUILD_GROUP10:-OFF}" BUILD_GROUP11="${BUILD_GROUP11:-OFF}" BUILD_VIEWER_ONLY="${BUILD_VIEWER_ONLY:-OFF}" RUN_CTEST="${RUN_CTEST:-ON}" TESTS_ONLY="${TESTS_ONLY:-OFF}" INTEGRATION_TEST="${INTEGRATION_TEST:-OFF}" APT_PACKAGES_STRING="${APT_PACKAGES_STRING:-}" log_info() { printf 'INFO: %s\n' "$*" } log_warn() { printf 'WARNING: %s\n' "$*" >&2 } install_qt6_packages() { log_info "Installing Qt6 packages via aqtinstall" # Install aqtinstall if not available if ! command -v aqt &> /dev/null; then log_info "Installing aqtinstall via pip3" pip3 install --break-system-packages --quiet aqtinstall fi # Install Qt6 modules (same as app/Dockerfile) # Modules: qtmultimedia, qtserialport, qtimageformats, qtwebsockets, qtwebengine, # qtpdf, qtwebview, qt5compat, qtwebchannel, qtpositioning, qtlocation, qtsensors # Note: qtsvg is NOT available via aqtinstall - it's provided by libqt6svg6-dev apt package aqt install-qt linux desktop "${QT_VERSION:-6.10.2}" "${QT_ARCH:-linux_gcc_64}" \ -m qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine \ qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors \ --outputdir "${QT_BASE_DIR:-/opt/Qt}" log_info "Qt6 packages installed successfully" } run_build_group() { local group_id="$1" local enabled="$2" local log_file="$3" shift 3 local targets=("$@") if [[ "${enabled}" == "ON" ]]; then log_info "Building ${group_id}: ${targets[*]}" make -j8 "${targets[@]}" 2>&1 | tee "${log_file}" else log_info "Skipping ${group_id}" fi } # Ensure a local PostgreSQL DB is available for the DB tools (dbUpdate, dbAdministration, ...). # Checks whether the server is pre-installed (baked into the image); if not, installs # postgresql-18. Then maps EXCDBS01/EXCADB01 -> 127.0.0.1 and starts the cluster, seeding # the roles (postgres, ctc_sv) + databases (lts_ets_pro, dbAdmin) the tools connect with. # Entirely non-fatal: a DB problem must never abort the build. ensure_database() { log_info "Checking for a pre-installed PostgreSQL server..." if ls /usr/lib/postgresql/*/bin/postgres >/dev/null 2>&1; then log_info "PostgreSQL server already installed - skipping apt install" else log_info "PostgreSQL server not found - installing postgresql-18" apt-get update -qq || true DEBIAN_FRONTEND=noninteractive apt-get install -y -qq postgresql-18 >/dev/null 2>&1 || true fi # Map the app's DB hostnames to the local server + start the cluster (idempotent). grep -qE 'EXCDBS01' /etc/hosts || echo '127.0.0.1 EXCDBS01 EXCADB01' >> /etc/hosts pg_ctlcluster 18 main start >/dev/null 2>&1 || true sleep 1 # Ensure the roles + databases the DB tools use (idempotent; login password is 'postgres'). su postgres -c "psql -c \"ALTER USER postgres PASSWORD 'postgres'\"" >/dev/null 2>&1 || true if ! su postgres -c "psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname='ctc_sv'\"" 2>/dev/null | grep -q 1; then su postgres -c "psql -c \"CREATE ROLE ctc_sv LOGIN PASSWORD 'postgres' CREATEDB\"" >/dev/null 2>&1 || true fi if ! su postgres -c "psql -tAc \"SELECT 1 FROM pg_database WHERE datname='lts_ets_pro'\"" 2>/dev/null | grep -q 1; then su postgres -c "createdb -O postgres lts_ets_pro" >/dev/null 2>&1 || true fi if ! su postgres -c "psql -tAc \"SELECT 1 FROM pg_database WHERE datname='dbAdmin'\"" 2>/dev/null | grep -q 1; then su postgres -c "createdb -O postgres dbAdmin" >/dev/null 2>&1 || true fi if pg_isready -h 127.0.0.1 -p 5432 >/dev/null 2>&1; then log_info "PostgreSQL ready on 127.0.0.1:5432 (roles postgres/ctc_sv, dbs lts_ets_pro/dbAdmin)" else log_info "WARNING: PostgreSQL not ready on 127.0.0.1:5432 (DB tools may not connect; install may have failed)" fi } if [[ "${USE_PREBUILT_IMAGE}" == "ON" ]]; then log_info "Using prebuilt Docker image - skipping apt-get install and Qt6 package installation" else log_info "Using base image - installing apt packages" apt-get update -qq # shellcheck disable=SC2086 apt-get install -y -qq ${APT_PACKAGES_STRING} > /dev/null 2>&1 # Install Qt6 packages via aqtinstall for non-prebuilt-image builds install_qt6_packages fi # Ensure the local PostgreSQL DB (dbUpdate / dbAdministration, ...) is available before the build. ensure_database export RTI_LICENSE_FILE=/workspace/rti_license.dat export QT_QPA_PLATFORM=offscreen # Setup ArcGIS SDK if enabled if [[ "${BUILD_ARCGIS}" == "ON" ]]; then log_info "Setting up ArcGIS SDK" if [[ -f "/workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus/install_arcgis.sh" ]]; then bash /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus/install_arcgis.sh else log_info "install_arcgis.sh not found, skipping ArcGIS SDK setup" fi fi # The MSDL/Saab plugins no longer require Qt XmlPatterns (removed in Qt 6.0, not # re-introduced). Their import logic was re-implemented with Qt6::Xml # (QDomDocument) plus the existing external xmllint schema-validation step; MSDL # additionally links XercesC and uses xsdc++-generated tree classes. So build # them by default. MSDL needs the xsdcxx code generator + libxerces-c-dev (both # are in APT_PACKAGES); if they are missing here, keep both plugins OFF and flag # the gap. (Saab only needs Qt6::Xml, but is gated together to keep the effective # value a single switch.) resolve_xmlpatterns() { BUILD_XMLPATTERNS_EFFECTIVE="${BUILD_XMLPATTERNS_PLUGINS}" if [[ "${BUILD_XMLPATTERNS_EFFECTIVE}" == "ON" ]]; then if command -v xsdcxx >/dev/null 2>&1 && [ -e /usr/lib/x86_64-linux-gnu/libxerces-c.so ]; then log_info "xsdcxx + XercesC present - MSDL/Saab plugins will be built (re-implemented without Qt XmlPatterns)" else log_warn "xsdcxx / libxerces-c-dev missing - keeping BUILD_PLUGINS_MSDL/BUILD_PLUGINS_SAAB OFF (ppm.msdl / ppm.saab stay unbuilt)" BUILD_XMLPATTERNS_EFFECTIVE=OFF fi fi } resolve_xmlpatterns # Schusstafel is a prebuilt external package (Schusstafel.h + # libSchusstafel.so) provided at external/Schusstafel, mirroring the ArcGIS # symlink pattern. cesPluginGeoPairing #includes Schusstafel.h unconditionally, # so without the package WITH_SCHUSSTAFEL stays OFF and the target is dropped # from Group 12 (environmental floor, not a migration regression). resolve_schusstafel() { WITH_SCHUSSTAFEL_EFFECTIVE="${WITH_SCHUSSTAFEL}" if [[ "${WITH_SCHUSSTAFEL_EFFECTIVE}" == "ON" ]]; then if ls /workspace/external/Schusstafel/Schusstafel.h >/dev/null 2>&1; then log_info "Schusstafel present at /workspace/external/Schusstafel - cesPluginGeoPairing will be built" else log_warn "Schusstafel not present at /workspace/external/Schusstafel - keeping WITH_SCHUSSTAFEL OFF (cesPluginGeoPairing stays unbuilt)" WITH_SCHUSSTAFEL_EFFECTIVE=OFF fi fi } # KDChart (KDAB, MIT) is an open-source Qt charts extension, installed under # /usr/local (header KDChart/kdchart_export.h + libkdchart.so; FindKDChart # searches /usr/local by default). The legacy env had a KDChart 2.6.0 Qt5 RPM; # the Qt6 build needs a Qt6-compatible release (e.g. github.com/KDAB/KDChart # tag kdchart-3.0.0 with -DKDChart_QT6=true). OreOnlineReportsGuiPlugin's # CMake RETURN()s when KDChart is absent, so without it the plugin (iid # ore.onlinereports) stays unbuilt - environmental floor. resolve_kdchart() { KDCHART_PRESENT=OFF if [[ -f /usr/local/include/KDChart/kdchart_export.h ]]; then KDCHART_PRESENT=ON log_info "KDChart present at /usr/local - OreOnlineReportsGuiPlugin will be built" else log_warn "KDChart not present at /usr/local - OreOnlineReportsGuiPlugin stays unbuilt (legacy KDChart 2.6.0 was a Qt5 RPM; build a Qt6-compatible release from source to close this floor)" fi } resolve_schusstafel resolve_kdchart cd /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus rm -rf build4 mkdir -p build4 cd build4 cmake .. \ -DBUILD_TESTING=ON \ -DBUILD_ALL="${BUILD_ALL}" \ -DBUILD_SV="${BUILD_SV}" \ -DBUILD_WS="${BUILD_WS}" \ -DBUILD_AAR="${BUILD_AAR}" \ -DBUILD_RTI="${BUILD_RTI}" \ -DBUILD_VIEWER_ONLY="${BUILD_VIEWER_ONLY}" \ -DBUILD_GRANTLEE="${BUILD_GRANTLEE}" \ -DBUILD_ARCGIS="${BUILD_ARCGIS}" \ -DBUILD_CODIFICATION="${BUILD_CODIFICATION}" \ -DBUILD_FILTERMANAGEMENT="${BUILD_FILTERMANAGEMENT}" \ -DBUILD_WLS="${BUILD_WLS}" \ -DBUILD_PLUGINS_SERVICEMONITOR="${BUILD_PLUGINS_SERVICEMONITOR}" \ -DBUILD_PLUGINS_PLANEDITOR="${BUILD_WEBENGINE_PLUGINS}" \ -DBUILD_PLUGINS_ONLINEHELP="${BUILD_WEBENGINE_PLUGINS}" \ -DBUILD_PLUGINS_PARTICIPANT_ORG_CHART="${BUILD_WEBENGINE_PLUGINS}" \ -DBUILD_PLUGINS_MSDL="${BUILD_XMLPATTERNS_EFFECTIVE}" \ -DBUILD_PLUGINS_SAAB="${BUILD_XMLPATTERNS_EFFECTIVE}" \ -DWITH_SCHUSSTAFEL="${WITH_SCHUSSTAFEL_EFFECTIVE}" \ ${CMAKE_BUILD_FLAGS:-} \ -DCMAKE_CXX_STANDARD=17 \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_PREFIX_PATH="${QT_BASE_DIR}/${QT_VERSION}/${QT_ARCH_DIR}${BUILD_ARCGIS:+;/workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus/external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/qt300.0.0/sdk};/usr/local" read -r -a GROUP1_ARRAY <<< "${GROUP1_TARGETS}" read -r -a GROUP2_ARRAY <<< "${GROUP2_TARGETS}" read -r -a GROUP3_ARRAY <<< "${GROUP3_TARGETS}" read -r -a GROUP4_ARRAY <<< "${GROUP4_TARGETS}" read -r -a GROUP5_ARRAY <<< "${GROUP5_TARGETS}" read -r -a GROUP6_ARRAY <<< "${GROUP6_TARGETS}" read -r -a GROUP7_ARRAY <<< "${GROUP7_TARGETS}" read -r -a GROUP8_ARRAY <<< "${GROUP8_TARGETS}" read -r -a GROUP9_ARRAY <<< "${GROUP9_TARGETS}" read -r -a GROUP10_ARRAY <<< "${GROUP10_TARGETS}" read -r -a GROUP11_ARRAY <<< "${GROUP11_TARGETS}" read -r -a GROUP12_ARRAY <<< "${GROUP12_TARGETS}" # cesPluginGeoPairing #includes Schusstafel.h unconditionally - drop it from # Group 12 when the Schusstafel package is unavailable (environmental floor). if [[ "${WITH_SCHUSSTAFEL_EFFECTIVE}" != "ON" ]]; then _GROUP12_ARRAY=() for _t in "${GROUP12_ARRAY[@]}"; do if [[ "${_t}" != "cesPluginGeoPairing" ]]; then _GROUP12_ARRAY+=("${_t}") fi done GROUP12_ARRAY=("${_GROUP12_ARRAY[@]}") fi # OreOnlineReportsGuiPlugin RETURN()s at configure when KDChart is absent - # drop it from Group 12 in that case (environmental floor, see resolve_kdchart). if [[ "${KDCHART_PRESENT}" != "ON" ]]; then _GROUP12_ARRAY=() for _t in "${GROUP12_ARRAY[@]}"; do if [[ "${_t}" != "OreOnlineReportsGuiPlugin" ]]; then _GROUP12_ARRAY+=("${_t}") fi done GROUP12_ARRAY=("${_GROUP12_ARRAY[@]}") fi if [[ "${TESTS_ONLY}" != "ON" ]]; then if [[ "${BUILD_VIEWER_ONLY}" == "ON" ]]; then log_info "BUILD_VIEWER_ONLY enabled - skipping Groups 1-4, building only Viewer module targets" BUILD_GROUP1=OFF BUILD_GROUP2=OFF BUILD_GROUP3=OFF BUILD_GROUP4=OFF BUILD_GROUP5=ON fi run_build_group "Group 1" "${BUILD_GROUP1}" "group1_build.log" "${GROUP1_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 5 (Viewer)" "${BUILD_GROUP5}" "group5_build.log" "${GROUP5_ARRAY[@]}" run_build_group "Group 6 (LTS Tools)" "${BUILD_GROUP6}" "group6_build.log" "${GROUP6_ARRAY[@]}" run_build_group "Group 7 (LTS Tools A,B,C,E,I)" "${BUILD_GROUP7}" "group7_build.log" "${GROUP7_ARRAY[@]}" run_build_group "Group 8 (LTS Tools J,M,N,P,Q)" "${BUILD_GROUP8}" "group8_build.log" "${GROUP8_ARRAY[@]}" run_build_group "Group 9 (LTS Tools R,S,T,V,W)" "${BUILD_GROUP9}" "group9_build.log" "${GROUP9_ARRAY[@]}" run_build_group "Group 10 (LTS Projects)" "${BUILD_GROUP10}" "group10_build.log" "${GROUP10_ARRAY[@]}" run_build_group "Group 12 (GUI/Data Plugins)" "${BUILD_GROUP12}" "group12_build.log" "${GROUP12_ARRAY[@]}" run_build_group "Group 11 (LTS Application)" "${BUILD_GROUP11}" "group11_build.log" "${GROUP11_ARRAY[@]}" else log_info "TESTS_ONLY enabled - skipping all build groups" fi if [[ "${RUN_CTEST}" == "ON" ]]; then if [[ "${INTEGRATION_TEST}" == "ON" ]]; then log_info "Running integration tests (Z-module + Proxies)" ctest --test-dir . --output-on-failure -R "(test_z_|bld_|tab_|wls_)" else log_info "Running CTest" ctest --test-dir . --output-on-failure fi else log_info "Skipping CTest" fi EOF chmod +x "${CONTAINER_SCRIPT_HOST}" docker run --rm \ -e MIGRATE_PIPELINE_ROOT \ -e LANG \ -e LC_ALL \ -e BUILD_ALL \ -e BUILD_SV \ -e BUILD_WS \ -e BUILD_AAR \ -e BUILD_RTI \ -e BUILD_GRANTLEE \ -e BUILD_ARCGIS \ -e BUILD_CODIFICATION \ -e BUILD_FILTERMANAGEMENT \ -e BUILD_WLS \ -e BUILD_PLUGINS_SERVICEMONITOR \ -e BUILD_WEBENGINE_PLUGINS \ -e BUILD_XMLPATTERNS_PLUGINS \ -e BUILD_GROUP1 \ -e BUILD_GROUP2 \ -e BUILD_GROUP3 \ -e BUILD_GROUP4 \ -e BUILD_GROUP5 \ -e BUILD_GROUP6 \ -e BUILD_GROUP7 \ -e BUILD_GROUP8 \ -e BUILD_GROUP9 \ -e BUILD_GROUP10 \ -e BUILD_GROUP11 \ -e BUILD_GROUP12 \ -e BUILD_VIEWER_ONLY \ -e RUN_CTEST \ -e TESTS_ONLY \ -e INTEGRATION_TEST \ -e USE_PREBUILT_IMAGE \ -e CMAKE_BUILD_FLAGS \ -e QT_VERSION \ -e QT_ARCH \ -e QT_ARCH_DIR \ -e QT_BASE_DIR \ -e APT_PACKAGES_STRING="${APT_PACKAGES_STRING}" \ -e GROUP1_TARGETS="${GROUP1_TARGETS_STRING}" \ -e GROUP2_TARGETS="${GROUP2_TARGETS_STRING}" \ -e GROUP3_TARGETS="${GROUP3_TARGETS_STRING}" \ -e GROUP4_TARGETS="${GROUP4_TARGETS_STRING}" \ -e GROUP5_TARGETS="${GROUP5_TARGETS_STRING}" \ -e GROUP6_TARGETS="${GROUP6_TARGETS_STRING}" \ -e GROUP7_TARGETS="${GROUP7_TARGETS_STRING}" \ -e GROUP8_TARGETS="${GROUP8_TARGETS_STRING}" \ -e GROUP9_TARGETS="${GROUP9_TARGETS_STRING}" \ -e GROUP10_TARGETS="${GROUP10_TARGETS_STRING}" \ -e GROUP11_TARGETS="${GROUP11_TARGETS_STRING}" \ -e GROUP12_TARGETS="${GROUP12_TARGETS_STRING}" \ -v "${WORKSPACE_ROOT_HOST}:/workspace" \ -v "${RTI_LICENSE_FILE_HOST}:/workspace/rti_license.dat" \ -v "${MIGRATE_PIPELINE_ROOT}/external:/workspace/external:ro" \ -v "${CONTAINER_SCRIPT_HOST}:/tmp/run-build-inside-container.sh:ro" \ "${DOCKER_IMAGE}" \ bash /tmp/run-build-inside-container.sh