Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/new_docker_build.sh
T

1017 lines
29 KiB
Bash
Executable File

#!/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 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
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
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_GROUP1=ON|OFF
BUILD_GROUP2=ON|OFF
BUILD_GROUP3=ON|OFF
BUILD_GROUP4=ON|OFF
BUILD_GROUP5=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=<image-name>
Required .envrc variable:
MIGRATE_PIPELINE_ROOT=<absolute-path>
Expected file:
${MIGRATE_PIPELINE_ROOT}/rti_license.dat
Defaults:
BUILD_RTI=ON
BUILD_GRANTLEE=ON
BUILD_ARCGIS=OFF
BUILD_GROUP1=ON
BUILD_GROUP2=ON
BUILD_GROUP3=ON
BUILD_GROUP4=OFF
BUILD_GROUP5=OFF
RUN_CTEST=ON
TESTS_ONLY=OFF
INTEGRATION_TEST=OFF
USE_PREBUILT_IMAGE=OFF
BUILD_PREBUILT_IMAGE=OFF
DELETE_PREBUILT_IMAGE=OFF
DOCKER_IMAGE=qt-migration-builder: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 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
}
log_info() {
printf 'INFO: %s\n' "$*"
}
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
)
# 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
# <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
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
TmsIfAdapterInterface
TmsIfAdapter
tabPluginUAS
TabUASTest3
TabUASTest4_2
TabUASTest6
# Proxies module - TrainingAreaBaseOC
svcTabocCommon
svcTabocClient
svcTabocServer
svcTrainingAreaBaseOC
serialtest
# Proxies module - WirelessLocationSystem
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" <<EOF
FROM ubuntu:26.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -qq && \
apt-get install -y -qq \
${APT_PACKAGES_STRING} \
libqt6svg6-dev \
libgtest-dev \
libgmock-dev \
python3-pip && \
rm -rf /var/lib/apt/lists/*
# Install Qt6 packages via aqtinstall
# Note: QtWebKit is deprecated in Qt6, use QtWebEngine instead
# KDReports is installed via aqtinstall or built from source if needed
# Note: qtsvg is NOT available via aqtinstall - it's provided by libqt6svg6-dev apt package
RUN pip3 install --break-system-packages --quiet aqtinstall && \
aqt install-qt linux desktop ${QT_VERSION} ${QT_ARCH} \
-m qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine \
qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors \
--outputdir ${QT_BASE_DIR} && \
rm -rf /root/.cache/Aqt
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_RTI="${BUILD_RTI:-ON}"
BUILD_GRANTLEE="${BUILD_GRANTLEE:-ON}"
BUILD_ARCGIS="${BUILD_ARCGIS:-OFF}"
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}"
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}"
if [[ "${USE_PREBUILT_IMAGE}" == "ON" ]]; then
DOCKER_IMAGE="${DOCKER_IMAGE:-qt-migration-builder:latest}"
else
DOCKER_IMAGE="${DOCKER_IMAGE:-ubuntu:26.04}"
fi
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
;;
--grantlee)
BUILD_GRANTLEE=ON
;;
--no-grantlee)
BUILD_GRANTLEE=OFF
;;
--arcgis)
BUILD_ARCGIS=ON
;;
--no-arcgis)
BUILD_ARCGIS=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"
;;
-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}"
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_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")"
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")"
# Export variables for Docker container
export BUILD_ALL BUILD_RTI BUILD_GRANTLEE BUILD_ARCGIS BUILD_GROUP1 BUILD_GROUP2 BUILD_GROUP3 BUILD_GROUP4 BUILD_GROUP5 RUN_CTEST TESTS_ONLY INTEGRATION_TEST USE_PREBUILT_IMAGE BUILD_PREBUILT_IMAGE DELETE_PREBUILT_IMAGE DOCKER_IMAGE
# Group 5: Viewer module targets (conditional on BUILD_ARCGIS)
if [[ "${BUILD_ARCGIS}" == "ON" ]]; then
GROUP5_TARGETS=(
# Viewer module with ArcGIS
situationMapCommon
advancedSymbology
advancedSymbologyXML
LtsDataView
LtsFileDialog
LtsReportDisplay
)
else
GROUP5_TARGETS=(
# Viewer module without ArcGIS (advancedSymbology requires ArcGIS)
situationMapCommon
advancedSymbologyXML
LtsDataView
LtsFileDialog
LtsReportDisplay
)
fi
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_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[@]}")"
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_RTI="${BUILD_RTI:-ON}"
BUILD_GRANTLEE="${BUILD_GRANTLEE:-ON}"
BUILD_ARCGIS="${BUILD_ARCGIS:-OFF}"
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}"
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' "$*"
}
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
}
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
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
cd /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus
rm -rf build4
mkdir -p build4
cd build4
cmake .. \
-DBUILD_TESTING=ON \
-DBUILD_RTI="${BUILD_RTI}" \
-DBUILD_GRANTLEE="${BUILD_GRANTLEE}" \
-DBUILD_ARCGIS="${BUILD_ARCGIS}" \
-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}"
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}"
if [[ "${TESTS_ONLY}" != "ON" ]]; then
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[@]}"
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_RTI \
-e BUILD_GRANTLEE \
-e BUILD_ARCGIS \
-e BUILD_GROUP1 \
-e BUILD_GROUP2 \
-e BUILD_GROUP3 \
-e BUILD_GROUP4 \
-e BUILD_GROUP5 \
-e RUN_CTEST \
-e TESTS_ONLY \
-e INTEGRATION_TEST \
-e USE_PREBUILT_IMAGE \
-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}" \
-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