539 lines
14 KiB
Bash
Executable File
539 lines
14 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
|
|
# - 3 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
|
|
# -----------------------------------------------------------------------------
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: ./build.sh [ON|OFF] [options]
|
|
|
|
BUILD_RTI:
|
|
First positional argument may be:
|
|
ON Enable BUILD_RTI
|
|
OFF Disable BUILD_RTI
|
|
|
|
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
|
|
|
|
Test execution:
|
|
--no-ctest Skip ctest execution
|
|
--tests-only Run only ctest, skip all make build groups
|
|
--integration-test Run only Z-module integration tests (test_z_*)
|
|
|
|
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_GROUP1=ON|OFF
|
|
BUILD_GROUP2=ON|OFF
|
|
BUILD_GROUP3=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_GROUP1=ON
|
|
BUILD_GROUP2=ON
|
|
BUILD_GROUP3=ON
|
|
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:
|
|
./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
|
|
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
|
|
libkf6texttemplate-dev
|
|
libqt6core6
|
|
libqt6gui6
|
|
libqt6widgets6
|
|
qt6-base-dev
|
|
qt6-tools-dev-tools
|
|
qt6-tools-dev
|
|
qt6-l10n-tools
|
|
libgtest-dev
|
|
libpq-dev
|
|
postgresql-server-dev-all
|
|
libvlc-dev
|
|
vlc-plugin-base
|
|
git
|
|
)
|
|
|
|
GROUP1_TARGETS=(
|
|
ddscore
|
|
ddsftccore
|
|
ddsQoS
|
|
ddsconnector
|
|
ddsfts
|
|
)
|
|
|
|
GROUP2_TARGETS=(
|
|
migration_tests
|
|
)
|
|
|
|
GROUP3_TARGETS=(
|
|
NGLLogger
|
|
nglapplication
|
|
nglcompression
|
|
nglcoreapplication
|
|
ngldb
|
|
nglguiapplication
|
|
nglsettings
|
|
nglsingleapplication
|
|
nglsinglecoreapplication
|
|
ngltools
|
|
ngltranslator
|
|
nglwidgets
|
|
qtsingleapplication
|
|
qtsinglecoreapplication
|
|
wms_json_ds
|
|
tcpserver
|
|
)
|
|
|
|
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} && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
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}"
|
|
}
|
|
|
|
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_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}"
|
|
USE_PREBUILT_IMAGE="${USE_PREBUILT_IMAGE:-OFF}"
|
|
BUILD_PREBUILT_IMAGE="${BUILD_PREBUILT_IMAGE:-OFF}"
|
|
DELETE_PREBUILT_IMAGE="${DELETE_PREBUILT_IMAGE:-OFF}"
|
|
DOCKER_IMAGE="${DOCKER_IMAGE:-qt-migration-builder:latest}"
|
|
|
|
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
|
|
;;
|
|
--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
|
|
|
|
BUILD_RTI="$(normalize_on_off "$BUILD_RTI" "BUILD_RTI")"
|
|
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")"
|
|
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")"
|
|
|
|
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 targets)" "$BUILD_GROUP3"
|
|
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 ' ./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[@]}")"
|
|
|
|
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_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}"
|
|
APT_PACKAGES_STRING="${APT_PACKAGES_STRING:-}"
|
|
|
|
log_info() {
|
|
printf 'INFO: %s\n' "$*"
|
|
}
|
|
|
|
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"
|
|
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
|
|
fi
|
|
|
|
export RTI_LICENSE_FILE=/workspace/rti_license.dat
|
|
export QT_QPA_PLATFORM=offscreen
|
|
|
|
cd /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus
|
|
|
|
rm -rf build4
|
|
mkdir -p build4
|
|
cd build4
|
|
|
|
cmake .. \
|
|
-DBUILD_RTI="${BUILD_RTI}" \
|
|
-DBUILD_ARCGIS=OFF \
|
|
-DCMAKE_CXX_STANDARD=17 \
|
|
-DCMAKE_BUILD_TYPE=Release
|
|
|
|
read -r -a GROUP1_ARRAY <<< "${GROUP1_TARGETS}"
|
|
read -r -a GROUP2_ARRAY <<< "${GROUP2_TARGETS}"
|
|
read -r -a GROUP3_ARRAY <<< "${GROUP3_TARGETS}"
|
|
|
|
if [[ "${TESTS_ONLY}" != "ON" ]]; then
|
|
run_build_group "Group 1" "${BUILD_GROUP1}" "group1_build.log" "${GROUP1_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[@]}"
|
|
else
|
|
log_info "TESTS_ONLY enabled - skipping all build groups"
|
|
fi
|
|
|
|
if [[ "${RUN_CTEST}" == "ON" ]]; then
|
|
if [[ "${INTEGRATION_TEST}" == "ON" ]]; then
|
|
log_info "Running Z-module integration tests only"
|
|
ctest --test-dir . --output-on-failure -R "test_z_"
|
|
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_GROUP1 \
|
|
-e BUILD_GROUP2 \
|
|
-e BUILD_GROUP3 \
|
|
-e RUN_CTEST \
|
|
-e TESTS_ONLY \
|
|
-e INTEGRATION_TEST \
|
|
-e USE_PREBUILT_IMAGE \
|
|
-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}" \
|
|
-v "${WORKSPACE_ROOT_HOST}:/workspace" \
|
|
-v "${RTI_LICENSE_FILE_HOST}:/workspace/rti_license.dat" \
|
|
-v "${CONTAINER_SCRIPT_HOST}:/tmp/run-build-inside-container.sh:ro" \
|
|
"${DOCKER_IMAGE}" \
|
|
bash /tmp/run-build-inside-container.sh |