Compare commits
10
Commits
a32481de09
...
1dd1e86355
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dd1e86355 | ||
|
|
52df1c8ae9 | ||
|
|
23e694afc2 | ||
|
|
217bb54bc0 | ||
|
|
ba99b74608 | ||
|
|
862d0dbe2b | ||
|
|
5554704174 | ||
|
|
14dde18e8a | ||
|
|
65ca0d8b5e | ||
|
|
23cf641d36 |
No files matched your search
@@ -0,0 +1,47 @@
|
||||
# Prebuilt build image for the release validation-scope branch
|
||||
# (Ubuntu 26.04 + Qt6 + all dependencies for the legatus release build).
|
||||
#
|
||||
# Built by new_docker_build.sh --build-prebuilt-image, which passes the
|
||||
# package list and Qt settings as build args (see build_prebuilt_image()).
|
||||
|
||||
FROM ubuntu:26.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG APT_PACKAGES
|
||||
ARG QT_VERSION=6.10.2
|
||||
ARG QT_ARCH=linux_gcc_64
|
||||
ARG QT_BASE_DIR=/opt/Qt
|
||||
|
||||
RUN apt-get update -qq && \
|
||||
apt-get install -y -qq \
|
||||
${APT_PACKAGES} \
|
||||
libqt6svg6-dev \
|
||||
libgtest-dev \
|
||||
libgmock-dev \
|
||||
python3-pip && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Qt6 packages via aqtinstall
|
||||
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
|
||||
|
||||
# Install KDReports from source (apt package not available in Ubuntu 22.04/26.04)
|
||||
# Try apt install first (will fail), then build from KDAB GitHub mirror
|
||||
RUN apt-get install -y -qq libkdreports-dev 2>/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 <KDReports/...>
|
||||
RUN ln -sfn KDReports-qt6 /usr/local/include/KDReports
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
@@ -298,7 +298,10 @@ void TelegramProxyModel::setFilterByEquipmentIds(bool bFilterByEquipmentIds)
|
||||
if (m_bFilterByEquipmentIds == bFilterByEquipmentIds)
|
||||
return;
|
||||
m_bFilterByEquipmentIds = bFilterByEquipmentIds;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -307,7 +310,10 @@ void TelegramProxyModel::setAllowedEquipmentIds(const std::set<int> &allowedEqui
|
||||
if (m_allowedEquipmentIds == allowedEquipmentIds)
|
||||
return;
|
||||
m_allowedEquipmentIds = allowedEquipmentIds;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -316,7 +322,10 @@ void TelegramProxyModel::setFilteredCentralTelegramIds(const std::set<int> &filt
|
||||
if (m_filteredCentralTelegramIds == filteredCentralTelegramIds)
|
||||
return;
|
||||
m_filteredCentralTelegramIds = filteredCentralTelegramIds;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -325,7 +334,10 @@ void TelegramProxyModel::setFilteredTetraTelegramIds(const std::set<int> &filter
|
||||
if (m_filteredTetraTelegramIds == filteredTetraTelegramIds)
|
||||
return;
|
||||
m_filteredTetraTelegramIds = filteredTetraTelegramIds;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -334,7 +346,10 @@ void TelegramProxyModel::setFilteredWlsTelegramIds(const std::set<int> &filtered
|
||||
if (m_filteredWlsTelegramIds == filteredWlsTelegramIds)
|
||||
return;
|
||||
m_filteredWlsTelegramIds = filteredWlsTelegramIds;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -350,7 +365,10 @@ void TelegramProxyModel::setFilterCentralTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader
|
||||
if (curFilter == m_filterCentralTelegrams)
|
||||
return;
|
||||
m_filterCentralTelegrams = curFilter;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -365,7 +383,10 @@ void TelegramProxyModel::setFilterTetraTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::
|
||||
if (curFilter == m_filterTetraTelegrams)
|
||||
return;
|
||||
m_filterTetraTelegrams = curFilter;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -380,7 +401,10 @@ void TelegramProxyModel::setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::E_
|
||||
if (curFilter == m_filterTetraPDU)
|
||||
return;
|
||||
m_filterTetraPDU = curFilter;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
void TelegramProxyModel::setFilterWlsTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction,
|
||||
@@ -394,7 +418,10 @@ void TelegramProxyModel::setFilterWlsTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_
|
||||
if (curFilter == m_filterWlsTelegrams)
|
||||
return;
|
||||
m_filterWlsTelegrams = curFilter;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -403,7 +430,10 @@ void TelegramProxyModel::setFilterTetraLogin(bool bFilter)
|
||||
if (m_bFilterLoginTelegrams == bFilter)
|
||||
return;
|
||||
m_bFilterLoginTelegrams = bFilter;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -412,7 +442,10 @@ void TelegramProxyModel::setFilterTetraFragmented(bool bFilter)
|
||||
if (m_bFilterFragmentedTelegrams == bFilter)
|
||||
return;
|
||||
m_bFilterFragmentedTelegrams = bFilter;
|
||||
invalidateFilter();
|
||||
// invalidateFilter() is deprecated in Qt6 - begin/endFilterChange() is the
|
||||
// documented replacement (re-filters the model)
|
||||
beginFilterChange();
|
||||
endFilterChange();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ QString TelegramEdit::s_TELEGRAMLIST_FILES()
|
||||
|
||||
TelegramEdit::TelegramEdit(QWidget *parent)
|
||||
: QObject(parent)
|
||||
, m_logger(getLogger("LogViewTelegramEdit"))
|
||||
, m_addTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/list-add.png")), tr("Add Telegram"), this))
|
||||
, m_editTeleAction(new QAction(QIcon(QLatin1String(":/image/Edit.png")), tr("Edit Telegram"), this))
|
||||
, m_copyTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/edit-copy.png")), tr("Copy Telegram"), this))
|
||||
@@ -58,6 +57,7 @@ TelegramEdit::TelegramEdit(QWidget *parent)
|
||||
, m_DoLoop(false)
|
||||
, m_InjectionThread(nullptr)
|
||||
, m_EditModel(new TelegramEditModel(this))
|
||||
, m_logger(getLogger("LogViewTelegramEdit"))
|
||||
{
|
||||
m_addTeleAction->setShortcut(tr("Ctrl+A"));
|
||||
m_editTeleAction->setShortcut(tr("Ctrl+E"));
|
||||
@@ -451,7 +451,7 @@ void TelegramEdit::saveTelegramList()
|
||||
|
||||
|
||||
QFile telegramFile(newFilename);
|
||||
telegramFile.open(QIODevice::WriteOnly);
|
||||
(void)telegramFile.open(QIODevice::WriteOnly);
|
||||
QDataStream stream(&telegramFile);
|
||||
|
||||
|
||||
@@ -515,7 +515,7 @@ void TelegramEdit::loadTelegramList(bool checkAppend)
|
||||
|
||||
|
||||
QFile telegramFile(newFilename);
|
||||
telegramFile.open(QIODevice::ReadOnly);
|
||||
(void)telegramFile.open(QIODevice::ReadOnly);
|
||||
QDataStream stream(&telegramFile);
|
||||
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ PrtCnvBroadcastMgr::PrtCnvBroadcastMgr() : m_ClaimWindow(0)
|
||||
, m_IsFullLoad(false)
|
||||
, m_FinishedBroadcastIndex(0)
|
||||
, m_FirstBroadcastIndexOfBc1(0)
|
||||
, m_loggerBcRequest(getLogger("PrtCnvBroadcastMgr.BcRequest"))
|
||||
, m_logger(getLogger("PrtCnvBroadcastMgr"))
|
||||
, m_loggerBcRequest(getLogger("PrtCnvBroadcastMgr.BcRequest"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -386,6 +386,8 @@ void PrtCnvCentralThread::handleTelegram(N_CoPrtCnv::CoPrtCnvCentralTelegram *a_
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
case AreaEffectSimulationType::BeStillWarning:
|
||||
case AreaEffectSimulationType::DangerZoneExplosion:
|
||||
case AreaEffectSimulationType::AirSupport:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,9 +65,12 @@ static void daemonize()
|
||||
}
|
||||
|
||||
|
||||
freopen( "/dev/null", "r", stdin);
|
||||
freopen( "/dev/null", "w", stdout);
|
||||
freopen( "/dev/null", "w", stderr);
|
||||
if (freopen( "/dev/null", "r", stdin ) == nullptr
|
||||
|| freopen( "/dev/null", "w", stdout ) == nullptr
|
||||
|| freopen( "/dev/null", "w", stderr ) == nullptr)
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ else()
|
||||
set(Qt6_Widgets "")
|
||||
endif()
|
||||
|
||||
|
||||
SET(nglapplication_SRCS
|
||||
nglapplication.cpp
|
||||
nglapplication.h
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
|
||||
|
||||
|
||||
#include "nglapplication.h"
|
||||
#include "ngl_signal_handler.inc"
|
||||
|
||||
|
||||
NGLApplication::NGLApplication(int &argc, char **argv)
|
||||
: QApplication(argc, argv)
|
||||
{
|
||||
|
||||
{
|
||||
signal(SIGTERM, &signalHandler);
|
||||
#ifdef Q_OS_WIN
|
||||
installNativeEventFilter(new MyEventFilter);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool NGLApplication::notify(QObject *o, QEvent *e)
|
||||
{
|
||||
bool bRet = false;
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
|
||||
|
||||
|
||||
#include "nglcoreapplication.h"
|
||||
|
||||
#include "ngl_signal_handler.inc"
|
||||
|
||||
|
||||
NGLCoreApplication::NGLCoreApplication(int &argc, char **argv)
|
||||
: QCoreApplication(argc, argv)
|
||||
{
|
||||
|
||||
{
|
||||
signal(SIGTERM, &signalHandler);
|
||||
#ifdef Q_OS_WIN
|
||||
installNativeEventFilter(new MyEventFilter);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
|
||||
|
||||
|
||||
#include "nglguiapplication.h"
|
||||
|
||||
#include "ngl_signal_handler.inc"
|
||||
|
||||
|
||||
NGLGuiApplication::NGLGuiApplication(int &argc, char **argv)
|
||||
: QGuiApplication(argc, argv)
|
||||
{
|
||||
|
||||
{
|
||||
signal(SIGTERM, &signalHandler);
|
||||
#ifdef Q_OS_WIN
|
||||
installNativeEventFilter(new MyEventFilter);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
|
||||
|
||||
|
||||
#include "nglloggerhandler.h"
|
||||
#include "ngl_qt_msg_handler.inc"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <nglcoreapplication.h>
|
||||
@@ -22,13 +18,11 @@ static QByteArray username()
|
||||
|
||||
static void setEnvVars()
|
||||
{
|
||||
|
||||
const QString logPath = NGL::Settings::logPath();
|
||||
qputenv("LOG4QT_LOGDIR", logPath.toLocal8Bit());
|
||||
qputenv("LOG4QT_USER", username());
|
||||
}
|
||||
|
||||
|
||||
void LoggerHandler::createLogger(const QByteArray &baseName, const char *configFileName, bool quiet)
|
||||
{
|
||||
setEnvVars();
|
||||
@@ -41,12 +35,10 @@ void LoggerHandler::createLogger(const QByteArray &baseName, const char *configF
|
||||
|
||||
const QString logOutputName = m_loggerFilenamePostfix + m_loggerFilenamePrefix;
|
||||
NGL::NGLLoggerBootstrap::createNGLRootLogger(QString::fromLatin1(configFileName), false, logOutputName, quiet);
|
||||
|
||||
|
||||
|
||||
qInstallMessageHandler(&qtMsgHandler);
|
||||
}
|
||||
|
||||
|
||||
void LoggerHandler::createLogger(const QByteArray &baseName, int exerciseId, int additionalId, bool quiet)
|
||||
{
|
||||
setEnvVars();
|
||||
@@ -64,25 +56,20 @@ void LoggerHandler::createLogger(const QByteArray &baseName, int exerciseId, int
|
||||
m_baseLoggerName = baseName + QByteArray(".main");
|
||||
|
||||
const QString logOutputName = m_loggerFilenamePostfix + m_loggerFilenamePrefix;
|
||||
NGL::NGLLoggerBootstrap::createNGLRootLogger(configFileName, false, logOutputName, quiet);
|
||||
|
||||
|
||||
NGL::NGLLoggerBootstrap::createNGLRootLogger(configFileName, false, logOutputName, quiet);
|
||||
qInstallMessageHandler(&qtMsgHandler);
|
||||
}
|
||||
|
||||
|
||||
NGL::INGLLogger &LoggerHandler::baseLogger() const
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(m_baseLoggerName.data());
|
||||
}
|
||||
|
||||
|
||||
NGL::INGLLogger &LoggerHandler::logger(const char *loggerName) const
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName);
|
||||
}
|
||||
|
||||
|
||||
LoggerHandler *LoggerHandler::getLoggerHandler()
|
||||
{
|
||||
return dynamic_cast<LoggerHandler*>(QCoreApplication::instance());
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtSingleApplication/QtSingleApplication>
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
|
||||
|
||||
|
||||
#include "nglsinglecoreapplication.h"
|
||||
|
||||
#include "ngl_signal_handler.inc"
|
||||
|
||||
|
||||
NGLSingleCoreApplication::NGLSingleCoreApplication(int &argc, char **argv)
|
||||
: QtSingleCoreApplication(argc, argv)
|
||||
{
|
||||
|
||||
{
|
||||
signal(SIGTERM, &signalHandler);
|
||||
#ifdef Q_OS_WIN
|
||||
installNativeEventFilter(new MyEventFilter);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtSingleApplication/QtSingleCoreApplication>
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
FIND_PROGRAM(DOXYGEN_EXECUTABLE doxygen)
|
||||
|
||||
MACRO(ADD_DOXYGEN_TARGET target input output infile outdir)
|
||||
|
||||
@@ -1,24 +1,3 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
IF(ARCGIS_INCLUDE_DIR AND ARCGIS_LIBRARY)
|
||||
SET(ARCGIS_FOUND TRUE)
|
||||
ELSE()
|
||||
|
||||
@@ -1,26 +1,3 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
INCLUDE(FindLibraryWithDebug)
|
||||
|
||||
|
||||
@@ -5,15 +5,16 @@ set -euo pipefail
|
||||
# Build helper for the release validation-scope branch of qt-migrated-legatus
|
||||
#
|
||||
# Builds only the release scope (TetraIF, Z/src, Lts/Common +
|
||||
# Lts/Proxies/TrainingAreaBase) inside Docker and optionally runs the Jenkins
|
||||
# builder to produce the release DEB packages.
|
||||
# Lts/Proxies/TrainingAreaBase) inside the prebuilt Docker image and
|
||||
# optionally runs the Jenkins builder to produce the release DEB packages.
|
||||
#
|
||||
# - Loads environment from .envrc
|
||||
# - Validates MIGRATE_PIPELINE_ROOT and rti_license.dat
|
||||
# - 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 Jenkins builder run for RPM/DEB package production
|
||||
# - Resolves MIGRATE_PIPELINE_ROOT (exported variable, .envrc, or derived
|
||||
# from the script location) and validates rti_license.dat
|
||||
# - Uses a prebuilt Docker image with all build dependencies installed
|
||||
# (build it from ./Dockerfile via --build-prebuilt-image)
|
||||
# - Optional deletion of the prebuilt Docker image via --delete-prebuilt-image
|
||||
# - Optional DEB package production via the in-tree rpmbuild/
|
||||
# make_rpm_ubuntu26.py (self-contained - no outer-repo dependencies)
|
||||
# - Uses a temporary container-side script for robust execution
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@@ -21,24 +22,21 @@ usage() {
|
||||
cat <<'EOF'
|
||||
Usage: ./new_docker_build.sh [options]
|
||||
|
||||
Builds the release validation scope inside Docker:
|
||||
Builds the release validation scope inside the prebuilt Docker image:
|
||||
RELEASE_BUILD=ON (fixed) - TetraIF, Z, Lts/Common (+ TrainingAreaBase)
|
||||
BUILD_RTI=OFF (fixed) - uses the ProjectDataManagement stubs
|
||||
ctest runs for the release scope test executables (Lts/Common + Z)
|
||||
|
||||
Options:
|
||||
--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
|
||||
(default: legatus-qt6-prebuilt:latest)
|
||||
--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
|
||||
--build-prebuilt-image Build the prebuilt Docker image (from ./Dockerfile)
|
||||
and exit. To run the build with it, run the script
|
||||
again with --docker-image
|
||||
--delete-prebuilt-image Delete the configured Docker image and exit
|
||||
--cmake_build_flags FLAGS Extra CMake flags passed to the in-container configure
|
||||
(space-separated -D flags, e.g. "-DBUILD_WLS=ON")
|
||||
|
||||
Jenkins builder options (for RPM/DEB package production):
|
||||
--run-jenkins-builder Run jenkins_builder_ubuntu26.sh inside container to produce packages
|
||||
Package production options (RPM/DEB):
|
||||
--run-jenkins-builder Build the release DEB packages inside the container
|
||||
using the in-tree rpmbuild/make_rpm_ubuntu26.py
|
||||
--package-output-dir DIR Directory to mount for package output (default: ./packages-out)
|
||||
--lts-version VERSION LTS version for package (default: 1.0)
|
||||
--project NAME Project name for package (default: guez)
|
||||
@@ -46,11 +44,9 @@ Jenkins builder options (for RPM/DEB package production):
|
||||
--build-tag TAG Build tag for package (default: manual-build)
|
||||
|
||||
Environment variable overrides:
|
||||
USE_PREBUILT_IMAGE=ON|OFF
|
||||
BUILD_PREBUILT_IMAGE=ON|OFF
|
||||
DELETE_PREBUILT_IMAGE=ON|OFF
|
||||
DOCKER_IMAGE=<image-name>
|
||||
CMAKE_BUILD_FLAGS=<flags>
|
||||
RUN_JENKINS_BUILDER=ON|OFF
|
||||
PACKAGE_OUTPUT_DIR=<dir>
|
||||
LTS_VERSION=<version>
|
||||
@@ -59,18 +55,19 @@ Environment variable overrides:
|
||||
BUILD_NUMBER=<num>
|
||||
BUILD_TAG=<tag>
|
||||
|
||||
Required .envrc variable:
|
||||
MIGRATE_PIPELINE_ROOT=<absolute-path>
|
||||
MIGRATE_PIPELINE_ROOT resolution (highest precedence first):
|
||||
1. exported MIGRATE_PIPELINE_ROOT (e.g. from a Jenkinsfile)
|
||||
2. MIGRATE_PIPELINE_ROOT set by .envrc in this directory
|
||||
3. derived from the script location (three levels up)
|
||||
|
||||
Expected file:
|
||||
${MIGRATE_PIPELINE_ROOT}/rti_license.dat
|
||||
|
||||
Examples:
|
||||
./new_docker_build.sh --build-prebuilt-image --docker-image legatus-qt6:1.0
|
||||
./new_docker_build.sh --use-prebuilt-image --docker-image legatus-qt6:1.0
|
||||
./new_docker_build.sh --build-prebuilt-image --use-prebuilt-image --docker-image legatus-qt6:1.0
|
||||
./new_docker_build.sh --docker-image legatus-qt6:1.0
|
||||
./new_docker_build.sh --delete-prebuilt-image --docker-image legatus-qt6:1.0
|
||||
./new_docker_build.sh --use-prebuilt-image --docker-image legatus-qt6:1.0 \
|
||||
./new_docker_build.sh --docker-image legatus-qt6:1.0 \
|
||||
--run-jenkins-builder --package-output-dir /path/to/rpms/guez/26.04
|
||||
EOF
|
||||
}
|
||||
@@ -187,8 +184,6 @@ APT_PACKAGES=(
|
||||
libgtest-dev
|
||||
libpq-dev
|
||||
postgresql-server-dev-all
|
||||
libvlc-dev
|
||||
vlc-plugin-base
|
||||
git
|
||||
python3-pip
|
||||
# Packaging tools for RPM/DEB build
|
||||
@@ -199,9 +194,15 @@ APT_PACKAGES=(
|
||||
devscripts
|
||||
)
|
||||
|
||||
# Release scope targets: Z components + Lts/Common libraries and the
|
||||
# release-scope test executables (Lts/Common + Z)
|
||||
# Release scope targets: TetraIF + Z components + Lts/Common libraries
|
||||
# and the release-scope test executables (Lts/Common + Z)
|
||||
RELEASE_BUILD_TARGETS=(
|
||||
# TetraIF module targets (CoPrtCnv / LogView / PrtCnv)
|
||||
CoPrtCnv
|
||||
LogViewLogger
|
||||
LogView
|
||||
PrtCnvLib
|
||||
PrtCnv
|
||||
# Z module targets
|
||||
NGLLogger
|
||||
nglapplication
|
||||
@@ -236,84 +237,58 @@ APT_PACKAGES_STRING="$(join_by ' ' "${APT_PACKAGES[@]}")"
|
||||
|
||||
build_prebuilt_image() {
|
||||
local image_name="$1"
|
||||
local dockerfile="Dockerfile"
|
||||
|
||||
require_file "${dockerfile}" "Prebuilt-image Dockerfile"
|
||||
|
||||
# The Dockerfile has no COPY/ADD, so an empty build context is fine -
|
||||
# this avoids tarring the source tree into the build context.
|
||||
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
|
||||
|
||||
# Install KDReports from source (apt package not available in Ubuntu 22.04/26.04)
|
||||
# Try apt install first (will fail), then build from KDAB GitHub mirror
|
||||
RUN apt-get install -y -qq libkdreports-dev 2>/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 <KDReports/...> 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
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
EOF
|
||||
|
||||
log_info "Building prebuilt Docker image: ${image_name}"
|
||||
docker build -t "${image_name}" "${tmp_dir}"
|
||||
log_info "Building prebuilt Docker image: ${image_name} (Dockerfile: ${dockerfile})"
|
||||
docker build -t "${image_name}" \
|
||||
-f "${dockerfile}" \
|
||||
--build-arg APT_PACKAGES="${APT_PACKAGES_STRING}" \
|
||||
--build-arg QT_VERSION="${QT_VERSION}" \
|
||||
--build-arg QT_ARCH="${QT_ARCH}" \
|
||||
--build-arg QT_BASE_DIR="${QT_BASE_DIR}" \
|
||||
"${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)"
|
||||
# MIGRATE_PIPELINE_ROOT resolution (highest precedence first):
|
||||
# 1. exported environment variable (e.g. from a Jenkinsfile)
|
||||
# 2. .envrc in this directory (if present)
|
||||
# 3. derived from this script's location - the script always lives at
|
||||
# <root>/qt-migration-legatus/qt6-after/qt6-migrated-legatus, so the
|
||||
# pipeline root is three levels up. This makes the script work in a
|
||||
# fresh Jenkins checkout with no environment setup at all.
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
MIGRATE_PIPELINE_ROOT_DEFAULT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||
PIPELINE_ROOT_EXPORTED="${MIGRATE_PIPELINE_ROOT:-}"
|
||||
|
||||
if [[ -f ".envrc" ]]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source ".envrc"
|
||||
set +a
|
||||
fi
|
||||
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source ".envrc"
|
||||
set +a
|
||||
# An explicitly exported MIGRATE_PIPELINE_ROOT (Jenkinsfile) wins over .envrc
|
||||
if [[ -n "${PIPELINE_ROOT_EXPORTED}" ]]; then
|
||||
MIGRATE_PIPELINE_ROOT="${PIPELINE_ROOT_EXPORTED}"
|
||||
else
|
||||
MIGRATE_PIPELINE_ROOT="${MIGRATE_PIPELINE_ROOT:-${MIGRATE_PIPELINE_ROOT_DEFAULT}}"
|
||||
fi
|
||||
|
||||
# Fixed configuration for the release validation-scope branch
|
||||
RELEASE_BUILD=ON
|
||||
BUILD_RTI=OFF
|
||||
BUILD_GRANTLEE=ON
|
||||
BUILD_ARCGIS=OFF
|
||||
BUILD_VIEWER_ONLY=OFF
|
||||
BUILD_CODIFICATION=OFF
|
||||
BUILD_ALL=ON
|
||||
BUILD_SV=ON
|
||||
BUILD_WS=ON
|
||||
BUILD_AAR=ON
|
||||
RUN_CTEST=ON
|
||||
USE_PREBUILT_IMAGE="${USE_PREBUILT_IMAGE:-OFF}"
|
||||
BUILD_PREBUILT_IMAGE="${BUILD_PREBUILT_IMAGE:-OFF}"
|
||||
DELETE_PREBUILT_IMAGE="${DELETE_PREBUILT_IMAGE:-OFF}"
|
||||
# Jenkins builder options for RPM/DEB package production
|
||||
@@ -332,12 +307,6 @@ export QT_BASE_DIR="${QT_BASE_DIR:-/opt/Qt}"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--use-prebuilt-image)
|
||||
USE_PREBUILT_IMAGE=ON
|
||||
;;
|
||||
--no-prebuilt-image)
|
||||
USE_PREBUILT_IMAGE=OFF
|
||||
;;
|
||||
--build-prebuilt-image)
|
||||
BUILD_PREBUILT_IMAGE=ON
|
||||
;;
|
||||
@@ -349,11 +318,6 @@ while [[ $# -gt 0 ]]; do
|
||||
[[ $# -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"
|
||||
;;
|
||||
--run-jenkins-builder)
|
||||
RUN_JENKINS_BUILDER=ON
|
||||
;;
|
||||
@@ -394,7 +358,6 @@ while [[ $# -gt 0 ]]; do
|
||||
shift
|
||||
done
|
||||
|
||||
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")"
|
||||
RUN_JENKINS_BUILDER="$(normalize_on_off "$RUN_JENKINS_BUILDER" "RUN_JENKINS_BUILDER")"
|
||||
@@ -402,11 +365,8 @@ RUN_JENKINS_BUILDER="$(normalize_on_off "$RUN_JENKINS_BUILDER" "RUN_JENKINS_BUIL
|
||||
# Default for the Docker image name
|
||||
DOCKER_IMAGE="${DOCKER_IMAGE:-legatus-qt6-prebuilt:latest}"
|
||||
|
||||
# Default for extra CMake flags (set via --cmake_build_flags or environment)
|
||||
CMAKE_BUILD_FLAGS="${CMAKE_BUILD_FLAGS:-}"
|
||||
|
||||
# Export variables for Docker container
|
||||
export RELEASE_BUILD BUILD_RTI BUILD_GRANTLEE BUILD_CODIFICATION BUILD_ALL BUILD_SV BUILD_WS BUILD_AAR RUN_CTEST USE_PREBUILT_IMAGE BUILD_PREBUILT_IMAGE DELETE_PREBUILT_IMAGE DOCKER_IMAGE CMAKE_BUILD_FLAGS RUN_JENKINS_BUILDER PACKAGE_OUTPUT_DIR LTS_VERSION PROJECT GUEZ_MODE BUILD_NUMBER BUILD_TAG
|
||||
export RELEASE_BUILD RUN_CTEST BUILD_PREBUILT_IMAGE DELETE_PREBUILT_IMAGE DOCKER_IMAGE RUN_JENKINS_BUILDER PACKAGE_OUTPUT_DIR LTS_VERSION PROJECT GUEZ_MODE BUILD_NUMBER BUILD_TAG
|
||||
|
||||
require_non_empty "${DOCKER_IMAGE}" "DOCKER_IMAGE"
|
||||
|
||||
@@ -426,9 +386,7 @@ require_file "${RTI_LICENSE_FILE_HOST}" "RTI license file"
|
||||
require_directory "${PROJECT_DIR_HOST}" "Project directory"
|
||||
|
||||
log_info "RELEASE_BUILD=${RELEASE_BUILD}"
|
||||
log_info "BUILD_RTI=${BUILD_RTI}"
|
||||
log_info "RUN_CTEST=${RUN_CTEST}"
|
||||
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}"
|
||||
@@ -446,15 +404,10 @@ 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}"
|
||||
log_info "Prebuilt image was built successfully."
|
||||
log_info "To run the build with it, run:"
|
||||
printf ' ./new_docker_build.sh --docker-image %q\n' "${DOCKER_IMAGE}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
RELEASE_BUILD_TARGETS_STRING="$(join_by ' ' "${RELEASE_BUILD_TARGETS[@]}")"
|
||||
@@ -472,28 +425,15 @@ set -euo pipefail
|
||||
|
||||
# Fixed configuration for the release validation-scope branch
|
||||
RELEASE_BUILD="${RELEASE_BUILD:-ON}"
|
||||
BUILD_RTI="${BUILD_RTI:-OFF}"
|
||||
BUILD_GRANTLEE="${BUILD_GRANTLEE:-ON}"
|
||||
BUILD_ARCGIS="${BUILD_ARCGIS:-OFF}"
|
||||
BUILD_VIEWER_ONLY="${BUILD_VIEWER_ONLY:-OFF}"
|
||||
BUILD_CODIFICATION="${BUILD_CODIFICATION:-OFF}"
|
||||
BUILD_ALL="${BUILD_ALL:-ON}"
|
||||
BUILD_SV="${BUILD_SV:-ON}"
|
||||
BUILD_WS="${BUILD_WS:-ON}"
|
||||
BUILD_AAR="${BUILD_AAR:-ON}"
|
||||
RUN_CTEST="${RUN_CTEST:-ON}"
|
||||
USE_PREBUILT_IMAGE="${USE_PREBUILT_IMAGE:-OFF}"
|
||||
APT_PACKAGES_STRING="${APT_PACKAGES_STRING:-}"
|
||||
# Jenkins builder and packaging variables
|
||||
# Packaging variables
|
||||
RUN_JENKINS_BUILDER="${RUN_JENKINS_BUILDER:-OFF}"
|
||||
MIGRATE_PIPELINE_ROOT="/workspace"
|
||||
PACKAGE_OUTPUT_DIR="${PACKAGE_OUTPUT_DIR:-/workspace/packages-out}"
|
||||
LTS_VERSION="${LTS_VERSION:-1.0}"
|
||||
PROJECT="${PROJECT:-guez}"
|
||||
GUEZ_MODE="${GUEZ_MODE:-ON}"
|
||||
BUILD_NUMBER="${BUILD_NUMBER:-1}"
|
||||
BUILD_TAG="${BUILD_TAG:-manual-build}"
|
||||
CMAKE_BUILD_FLAGS="${CMAKE_BUILD_FLAGS:-}"
|
||||
RELEASE_BUILD_TARGETS="${RELEASE_BUILD_TARGETS:-}"
|
||||
QT_VERSION="${QT_VERSION:-6.10.2}"
|
||||
QT_ARCH="${QT_ARCH:-linux_gcc_64}"
|
||||
@@ -508,75 +448,7 @@ log_error() {
|
||||
printf 'ERROR: %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 the prebuilt-image Dockerfile)
|
||||
# Note: qtsvg is NOT available via aqtinstall - it's provided by libqt6svg6-dev apt package
|
||||
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}"
|
||||
|
||||
log_info "Qt6 packages installed successfully"
|
||||
}
|
||||
|
||||
# Ensure a local PostgreSQL DB is available.
|
||||
# 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 "PostgreSQL not ready on 127.0.0.1:5432 (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 is available before the build.
|
||||
ensure_database
|
||||
log_info "Using prebuilt Docker image: all build dependencies are baked in"
|
||||
|
||||
export RTI_LICENSE_FILE=/workspace/rti_license.dat
|
||||
export QT_QPA_PLATFORM=offscreen
|
||||
@@ -587,19 +459,16 @@ rm -rf build4
|
||||
mkdir -p build4
|
||||
cd build4
|
||||
|
||||
# CMake option defaults that this branch must override:
|
||||
# BUILD_ARCGIS defaults to ON -> force OFF (ArcGIS SDK is not in the scope)
|
||||
# RELEASE_BUILD defaults to OFF -> force ON (release scope modules only)
|
||||
# All other BUILD_* flags are left at their CMake defaults, which match
|
||||
# the release scope configuration (BUILD_RTI/CODIFICATION/VIEWER_ONLY=OFF,
|
||||
# BUILD_GRANTLEE/ALL/SV/WS/AAR=ON).
|
||||
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_ARCGIS=OFF \
|
||||
-DRELEASE_BUILD="${RELEASE_BUILD}" \
|
||||
${CMAKE_BUILD_FLAGS:-} \
|
||||
-DCMAKE_CXX_STANDARD=17 \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_PREFIX_PATH="${QT_BASE_DIR}/${QT_VERSION}/${QT_ARCH_DIR}:/usr/local"
|
||||
@@ -619,39 +488,64 @@ else
|
||||
log_info "Skipping CTest"
|
||||
fi
|
||||
|
||||
# Jenkins builder execution (produces the release DEB packages)
|
||||
# DEB package production with the in-tree rpmbuild script
|
||||
if [[ "${RUN_JENKINS_BUILDER}" == "ON" ]]; then
|
||||
log_info "=== Jenkins Builder Execution (RPM/DEB Package Production) ==="
|
||||
log_info "=== DEB Package Production (in-tree rpmbuild) ==="
|
||||
|
||||
# Set up environment variables for jenkins_builder_ubuntu26.sh
|
||||
export OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | cut -d'"' -f2)
|
||||
export WORKSPACE=/workspace
|
||||
export PROJECT_BASE_DIR=/workspace
|
||||
OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | cut -d'"' -f2)
|
||||
STAGE_DIR=/workspace/deb_stage
|
||||
STAGED_SOURCE_DIR="${STAGE_DIR}/qt-migration-legatus/qt6-after/qt6-migrated-legatus"
|
||||
|
||||
log_info "Running jenkins_builder_ubuntu26.sh with:"
|
||||
# Stage the workspace as a clean copy. The workspace itself is NEVER
|
||||
# deleted (it contains git-managed sources); only the staging
|
||||
# subdirectory is removed.
|
||||
log_info "Staging workspace to ${STAGE_DIR}"
|
||||
rm -rf "${STAGE_DIR}"
|
||||
mkdir -p "${STAGE_DIR}"
|
||||
tar --exclude='./rpms' --exclude='./.git' --exclude='./build' \
|
||||
--exclude='./deb_build_tmp' --exclude='./deb_stage' --exclude='./packages-out' \
|
||||
-cf - -C /workspace . | tar -xf - -C "${STAGE_DIR}"
|
||||
|
||||
if [[ ! -f "${STAGED_SOURCE_DIR}/CMakeLists.txt" || ! -f "${STAGED_SOURCE_DIR}/rpmbuild/make_rpm_ubuntu26.py" ]]; then
|
||||
log_error "Staged source incomplete under ${STAGED_SOURCE_DIR} (CMakeLists.txt or rpmbuild/make_rpm_ubuntu26.py missing)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Running ${STAGED_SOURCE_DIR}/rpmbuild/make_rpm_ubuntu26.py with:"
|
||||
log_info " PROJECT=${PROJECT}"
|
||||
log_info " OS_VERSION=${OS_VERSION}"
|
||||
log_info " LTS_VERSION=${LTS_VERSION}"
|
||||
log_info " GUEZ_MODE=${GUEZ_MODE}"
|
||||
log_info " WORKSPACE=${WORKSPACE}"
|
||||
log_info " PROJECT_BASE_DIR=${PROJECT_BASE_DIR}"
|
||||
log_info " BUILD_NUMBER=${BUILD_NUMBER}"
|
||||
log_info " BUILD_TAG=${BUILD_TAG}"
|
||||
|
||||
# Execute jenkins_builder_ubuntu26.sh
|
||||
if [[ -f "${MIGRATE_PIPELINE_ROOT}/jenkins-ci-rme/jenkins_builder_ubuntu26.sh" ]]; then
|
||||
bash "${MIGRATE_PIPELINE_ROOT}/jenkins-ci-rme/jenkins_builder_ubuntu26.sh" || JENKINS_BUILDER_RESULT=$?
|
||||
if [[ "${JENKINS_BUILDER_RESULT:-0}" -ne 0 ]]; then
|
||||
log_info "Jenkins builder completed with errors (exit code: ${JENKINS_BUILDER_RESULT})"
|
||||
else
|
||||
log_info "Jenkins builder completed successfully"
|
||||
fi
|
||||
cd "${STAGED_SOURCE_DIR}/rpmbuild"
|
||||
if python3 make_rpm_ubuntu26.py -c LTS \
|
||||
--project_name "${PROJECT}" \
|
||||
--version "${LTS_VERSION}" \
|
||||
--output_dir "/workspace/rpms/${PROJECT}/${OS_VERSION}/" \
|
||||
--source_dir "${STAGED_SOURCE_DIR}" \
|
||||
--cmake_build_flags "-DUSE_IPO=ON -DUSE_UNITY_BUILD=ON -DGUEZ_MODE=${GUEZ_MODE} -DBUILD_WLS=ON -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/ -DRELEASE_BUILD=ON" \
|
||||
--build_number "${BUILD_NUMBER}" \
|
||||
--release_scope; then
|
||||
log_info "Package build completed successfully"
|
||||
else
|
||||
log_error "jenkins_builder_ubuntu26.sh not found at ${MIGRATE_PIPELINE_ROOT}/jenkins-ci-rme/jenkins_builder_ubuntu26.sh"
|
||||
JENKINS_BUILDER_RESULT=1
|
||||
log_error "Package build failed (exit code: $?)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy produced DEB packages to the packages-out mount so they are
|
||||
# available on the host after the container exits.
|
||||
mkdir -p "${PACKAGE_OUTPUT_DIR}"
|
||||
shopt -s nullglob
|
||||
for deb in "/workspace/rpms/${PROJECT}/${OS_VERSION}/"*.deb; do
|
||||
cp -f "${deb}" "${PACKAGE_OUTPUT_DIR}/"
|
||||
done
|
||||
shopt -u nullglob
|
||||
log_info "DEB packages copied to ${PACKAGE_OUTPUT_DIR}:"
|
||||
ls -lh "${PACKAGE_OUTPUT_DIR}/"
|
||||
else
|
||||
log_info "Skipping Jenkins builder execution"
|
||||
log_info "Skipping DEB package production"
|
||||
fi
|
||||
EOF
|
||||
|
||||
@@ -662,15 +556,7 @@ docker run --rm \
|
||||
-e LANG \
|
||||
-e LC_ALL \
|
||||
-e RELEASE_BUILD \
|
||||
-e BUILD_RTI \
|
||||
-e BUILD_GRANTLEE \
|
||||
-e BUILD_CODIFICATION \
|
||||
-e BUILD_ALL \
|
||||
-e BUILD_SV \
|
||||
-e BUILD_WS \
|
||||
-e BUILD_AAR \
|
||||
-e RUN_CTEST \
|
||||
-e USE_PREBUILT_IMAGE \
|
||||
-e RUN_JENKINS_BUILDER \
|
||||
-e PACKAGE_OUTPUT_DIR \
|
||||
-e LTS_VERSION \
|
||||
@@ -678,12 +564,10 @@ docker run --rm \
|
||||
-e GUEZ_MODE \
|
||||
-e BUILD_NUMBER \
|
||||
-e BUILD_TAG \
|
||||
-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 RELEASE_BUILD_TARGETS="${RELEASE_BUILD_TARGETS_STRING}" \
|
||||
-v "${WORKSPACE_ROOT_HOST}:/workspace" \
|
||||
-v "${RTI_LICENSE_FILE_HOST}:/workspace/rti_license.dat" \
|
||||
|
||||
@@ -0,0 +1,921 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
DEB package builder for Ubuntu 26.04 - Qt6 Release
|
||||
Creates 5 separate DEB packages as per customer requirements:
|
||||
1. qt6-release-runtime - binaries and libraries from S
|
||||
2. qt6-release-sources - Qt6 C++ sources from S
|
||||
3. qt6-release-ctest-runtime - CTest executables
|
||||
4. qt6-release-ctest-sources - CTest source files
|
||||
5. qt6-release-build-pipeline - Dockerfiles, build scripts, CI/CD files
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import getpass
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def verbose():
|
||||
verb = os.getenv("EMERGE_VERBOSE")
|
||||
if verb is not None and verb.isdigit() and int(verb) > 0:
|
||||
return int(verb)
|
||||
return 0
|
||||
|
||||
|
||||
def debug(message):
|
||||
if verbose() >= 1:
|
||||
print(f"debug: {message}")
|
||||
return True
|
||||
|
||||
|
||||
def info(message):
|
||||
if verbose() >= 0:
|
||||
print(f"info: {message}")
|
||||
return True
|
||||
|
||||
|
||||
def warning(message):
|
||||
print(f"warning: {message}")
|
||||
return True
|
||||
|
||||
|
||||
def error(message):
|
||||
die(message)
|
||||
|
||||
|
||||
def die(message):
|
||||
print(f"emerge fatal error: {message}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def remove_directory(path):
|
||||
"""Remove directory tree"""
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
|
||||
def copy_file_to_dest_dir(src_file, dest_dir):
|
||||
"""Copy a single file to destination directory"""
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
shutil.copy2(src_file, dest_dir)
|
||||
|
||||
|
||||
def is_dds_file(filepath):
|
||||
"""Check if a file or directory path contains DDS-related content that should be excluded
|
||||
|
||||
Args:
|
||||
filepath: Path to check
|
||||
|
||||
Returns:
|
||||
True if file should be excluded (is DDS-related), False otherwise
|
||||
"""
|
||||
# Convert to lowercase for case-insensitive matching
|
||||
path_lower = filepath.lower()
|
||||
|
||||
# Exclude files/directories with 'dds' in the name
|
||||
if 'dds' in path_lower:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def copy_src_dir_to_dest_dir(src_dir, dest_dir, release_scope=False, file_filter=None):
|
||||
"""Copy source directory to destination with optional filtering
|
||||
|
||||
Args:
|
||||
src_dir: Source directory
|
||||
dest_dir: Destination directory
|
||||
release_scope: If True, only copy release scope directories
|
||||
file_filter: Optional function to filter files (filepath) -> bool
|
||||
"""
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
|
||||
# Release scope directories
|
||||
release_dirs = [
|
||||
"TetraIF",
|
||||
"Z/src",
|
||||
"Lts/Common"
|
||||
]
|
||||
|
||||
if release_scope:
|
||||
info(f"Copying only release scope directories: {release_dirs}")
|
||||
# Also copy root-level build files needed for CMake
|
||||
root_build_files = ['CMakeLists.txt', 'CTestCustom.ctest']
|
||||
root_build_dirs = ['cmake']
|
||||
|
||||
for bf in root_build_files:
|
||||
src_file = os.path.join(src_dir, bf)
|
||||
if os.path.exists(src_file):
|
||||
debug(f" Copying root file {bf}...")
|
||||
shutil.copy2(src_file, os.path.join(dest_dir, bf))
|
||||
|
||||
for bd in root_build_dirs:
|
||||
src_bdir = os.path.join(src_dir, bd)
|
||||
dest_bdir = os.path.join(dest_dir, bd)
|
||||
if os.path.exists(src_bdir):
|
||||
debug(f" Copying root directory {bd}...")
|
||||
shutil.copytree(src_bdir, dest_bdir, dirs_exist_ok=True)
|
||||
|
||||
for rel_dir in release_dirs:
|
||||
src_subdir = os.path.join(src_dir, rel_dir)
|
||||
dest_subdir = os.path.join(dest_dir, rel_dir)
|
||||
if os.path.exists(src_subdir):
|
||||
debug(f" Copying {rel_dir}...")
|
||||
for root, dirs, files in os.walk(src_subdir):
|
||||
# Skip build directories, hidden directories, deb_build_tmp (prevent recursion), and DDS-related directories
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.')
|
||||
and d not in ['build', 'cmake-build-debug', 'cmake-build-release', 'deb_build_tmp']
|
||||
and (file_filter is None or not file_filter(os.path.join(root, d)))]
|
||||
|
||||
for file in files:
|
||||
src_file = os.path.join(root, file)
|
||||
rel_path = os.path.relpath(src_file, src_subdir)
|
||||
dest_file = os.path.join(dest_subdir, rel_path)
|
||||
|
||||
# Apply file filter if provided (skip file if filter returns True)
|
||||
if file_filter and file_filter(src_file):
|
||||
continue
|
||||
|
||||
os.makedirs(os.path.dirname(dest_file), exist_ok=True)
|
||||
shutil.copy2(src_file, dest_file)
|
||||
else:
|
||||
# Copy entire source tree
|
||||
for root, dirs, files in os.walk(src_dir):
|
||||
# Skip build directories, hidden directories, deb_build_tmp (prevent recursion), and DDS-related directories
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.')
|
||||
and d not in ['build', 'cmake-build-debug', 'cmake-build-release', 'deb_build_tmp']
|
||||
and (file_filter is None or not file_filter(os.path.join(root, d)))]
|
||||
|
||||
for file in files:
|
||||
src_file = os.path.join(root, file)
|
||||
rel_path = os.path.relpath(src_file, src_dir)
|
||||
dest_file = os.path.join(dest_dir, rel_path)
|
||||
|
||||
# Apply file filter if provided (skip file if filter returns True)
|
||||
if file_filter and file_filter(src_file):
|
||||
continue
|
||||
|
||||
os.makedirs(os.path.dirname(dest_file), exist_ok=True)
|
||||
shutil.copy2(src_file, dest_file)
|
||||
|
||||
|
||||
def find_test_executables(pkg_dir, release_dirs):
|
||||
"""Find test executables from release scope modules in build4/bin/
|
||||
|
||||
Args:
|
||||
pkg_dir: Package staging directory
|
||||
release_dirs: List of release scope directory paths
|
||||
|
||||
Returns:
|
||||
List of (executable_path, module_path) tuples for tests in release scope
|
||||
"""
|
||||
test_executables = []
|
||||
build_bin_dir = os.path.join(pkg_dir, "build4", "bin")
|
||||
|
||||
if not os.path.exists(build_bin_dir):
|
||||
warning(f"Build bin directory not found: {build_bin_dir}")
|
||||
return test_executables
|
||||
|
||||
# Get all executable files in build4/bin/
|
||||
for filename in os.listdir(build_bin_dir):
|
||||
file_path = os.path.join(build_bin_dir, filename)
|
||||
if not os.path.isfile(file_path) or not os.access(file_path, os.X_OK):
|
||||
continue
|
||||
|
||||
# Skip non-test executables (common patterns)
|
||||
if not ('test' in filename.lower() or 'Test' in filename):
|
||||
continue
|
||||
|
||||
# Find which module this test belongs to by searching CMakeLists.txt
|
||||
module_path = find_test_module_source(pkg_dir, filename, release_dirs)
|
||||
if module_path:
|
||||
test_executables.append((file_path, module_path))
|
||||
debug(f" Found test executable: {filename} from {module_path}")
|
||||
else:
|
||||
debug(f" Skipping test executable (no module found): {filename}")
|
||||
|
||||
return test_executables
|
||||
|
||||
|
||||
def find_test_module_source(pkg_dir, test_name, release_dirs):
|
||||
"""Find the source module directory for a test executable
|
||||
|
||||
Args:
|
||||
pkg_dir: Package staging directory
|
||||
test_name: Name of the test executable
|
||||
release_dirs: List of release scope directory paths
|
||||
|
||||
Returns:
|
||||
Relative path to module directory, or None if not found
|
||||
"""
|
||||
# Search for CMakeLists.txt files that define this test
|
||||
for rel_dir in release_dirs:
|
||||
module_dir = os.path.join(pkg_dir, rel_dir)
|
||||
if not os.path.exists(module_dir):
|
||||
continue
|
||||
|
||||
for root, dirs, files in os.walk(module_dir):
|
||||
# Skip build directories
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ['build', 'cmake-build-debug', 'cmake-build-release']]
|
||||
|
||||
if 'CMakeLists.txt' in files:
|
||||
cmake_file = os.path.join(root, 'CMakeLists.txt')
|
||||
try:
|
||||
with open(cmake_file, 'r') as f:
|
||||
content = f.read()
|
||||
# Look for ADD_EXECUTABLE or ADD_TEST with this test name
|
||||
if f'ADD_EXECUTABLE({test_name}' in content or f'ADD_TEST(NAME {test_name}' in content:
|
||||
# Return the module directory relative to pkg_dir
|
||||
return os.path.relpath(root, pkg_dir)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def find_test_sources(pkg_dir, release_dirs):
|
||||
"""Find test source files in release scope modules
|
||||
|
||||
Args:
|
||||
pkg_dir: Package staging directory
|
||||
release_dirs: List of release scope directory paths
|
||||
|
||||
Returns:
|
||||
List of relative paths to test source files
|
||||
"""
|
||||
test_sources = []
|
||||
test_patterns = ['*test*.cpp', '*test*.h', '*Test*.cpp', '*Test*.h', 'test_*.cpp', 'test_*.h']
|
||||
|
||||
for rel_dir in release_dirs:
|
||||
module_dir = os.path.join(pkg_dir, rel_dir)
|
||||
if not os.path.exists(module_dir):
|
||||
continue
|
||||
|
||||
for root, dirs, files in os.walk(module_dir):
|
||||
# Skip build directories and hidden directories
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ['build', 'cmake-build-debug', 'cmake-build-release']]
|
||||
|
||||
for filename in files:
|
||||
# Check if this is a test file
|
||||
if 'test' in filename.lower() and (filename.endswith('.cpp') or filename.endswith('.h')):
|
||||
file_path = os.path.join(root, filename)
|
||||
rel_path = os.path.relpath(file_path, pkg_dir)
|
||||
test_sources.append(rel_path)
|
||||
debug(f" Found test source: {rel_path}")
|
||||
|
||||
return test_sources
|
||||
|
||||
|
||||
def create_debian_control(deb_dir, package_name, version, build_number, description, depends="", section="devel"):
|
||||
"""Create debian/control file for a package"""
|
||||
control_content = f"""Source: {package_name}
|
||||
Section: {section}
|
||||
Priority: optional
|
||||
Maintainer: Legatus Team <team@legatus.example.com>
|
||||
Build-Depends: debhelper (>= 13), cmake, qt6-base-dev, qt6-tools-dev
|
||||
Standards-Version: 4.6.0
|
||||
|
||||
Package: {package_name}
|
||||
Architecture: any
|
||||
Depends: ${{shlibs:Depends}}, ${{misc:Depends}}{", " + depends if depends else ""}
|
||||
Description: {description}
|
||||
Legatus Qt6 Release Package
|
||||
This package is part of the Legatus Qt6 migration release.
|
||||
"""
|
||||
|
||||
control_file = os.path.join(deb_dir, "control")
|
||||
with open(control_file, "w") as f:
|
||||
f.write(control_content)
|
||||
info(f"Created {control_file}")
|
||||
|
||||
|
||||
def create_debian_changelog(deb_dir, package_name, version, build_number):
|
||||
"""Create debian/changelog file"""
|
||||
# Use +0000 as timezone offset (UTC) for reproducibility
|
||||
from email.utils import formatdate
|
||||
timestamp = formatdate(localtime=True)
|
||||
changelog_content = f"""{package_name} ({version}-{build_number}) unstable; urgency=medium
|
||||
|
||||
* Qt6 Release Build
|
||||
|
||||
-- Legatus Team <team@legatus.example.com> {timestamp}
|
||||
"""
|
||||
|
||||
changelog_file = os.path.join(deb_dir, "changelog")
|
||||
with open(changelog_file, "w") as f:
|
||||
f.write(changelog_content)
|
||||
info(f"Created {changelog_file}")
|
||||
|
||||
|
||||
def create_debian_rules(deb_dir, cmake_flags="", skip_tests=False):
|
||||
"""Create debian/rules file"""
|
||||
test_override = ""
|
||||
if skip_tests:
|
||||
test_override = """
|
||||
override_dh_auto_test:
|
||||
# Tests skipped for this package type
|
||||
"""
|
||||
|
||||
rules_content = f"""#!/usr/bin/make -f
|
||||
%:
|
||||
dh $@ --buildsystem=cmake
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- -DCMAKE_BUILD_TYPE=Release {cmake_flags}
|
||||
|
||||
override_dh_auto_build:
|
||||
dh_auto_build --parallel
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install --destdir=debian/tmp
|
||||
{test_override}"""
|
||||
|
||||
rules_file = os.path.join(deb_dir, "rules")
|
||||
with open(rules_file, "w") as f:
|
||||
f.write(rules_content)
|
||||
os.chmod(rules_file, stat.S_IREAD | stat.S_IWRITE | stat.S_IXUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXGRP | stat.S_IXOTH)
|
||||
info(f"Created {rules_file}")
|
||||
|
||||
|
||||
def create_debian_rules_nobuild(deb_dir, skip_shlibdeps=False):
|
||||
"""Create debian/rules file for packages that don't need building (pre-built files only)
|
||||
|
||||
Args:
|
||||
deb_dir: Path to debian directory
|
||||
skip_shlibdeps: If True, skip dh_shlibdeps (useful for test executables with external deps)
|
||||
"""
|
||||
rules_content = """#!/usr/bin/make -f
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_build:
|
||||
# No build step needed - pre-built files only
|
||||
|
||||
override_dh_auto_configure:
|
||||
# No configure step needed - pre-built files only
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install
|
||||
"""
|
||||
if skip_shlibdeps:
|
||||
rules_content += """
|
||||
override_dh_shlibdeps:
|
||||
# Skip shlibdeps for test executables - Qt6 deps are external system packages
|
||||
"""
|
||||
|
||||
rules_file = os.path.join(deb_dir, "rules")
|
||||
with open(rules_file, "w") as f:
|
||||
f.write(rules_content)
|
||||
os.chmod(rules_file, stat.S_IREAD | stat.S_IWRITE | stat.S_IXUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXGRP | stat.S_IXOTH)
|
||||
info(f"Created {rules_file}")
|
||||
|
||||
rules_file = os.path.join(deb_dir, "rules")
|
||||
with open(rules_file, "w") as f:
|
||||
f.write(rules_content)
|
||||
os.chmod(rules_file, stat.S_IREAD | stat.S_IWRITE | stat.S_IXUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXGRP | stat.S_IXOTH)
|
||||
info(f"Created {rules_file}")
|
||||
|
||||
|
||||
def create_debian_install(deb_dir, install_lines):
|
||||
"""Create debian/install file from list of file entries"""
|
||||
install_file = os.path.join(deb_dir, "install")
|
||||
with open(install_file, "w") as f:
|
||||
for line in install_lines:
|
||||
f.write(line + "\n")
|
||||
info(f"Created {install_file} with {len(install_lines)} entries")
|
||||
|
||||
|
||||
def create_manifest(output_dir, package_name, pkg_dir):
|
||||
"""Create manifest file listing all package contents from actual DEB file"""
|
||||
manifest_file = os.path.join(output_dir, "manifests", f"{package_name}.manifest")
|
||||
os.makedirs(os.path.dirname(manifest_file), exist_ok=True)
|
||||
|
||||
# Find the DEB file for this package
|
||||
deb_file = None
|
||||
for f in os.listdir(output_dir):
|
||||
if f.startswith(package_name) and f.endswith(".deb"):
|
||||
deb_file = os.path.join(output_dir, f)
|
||||
break
|
||||
|
||||
manifest_lines = []
|
||||
if deb_file and os.path.exists(deb_file):
|
||||
# Extract DEB contents using dpkg-deb
|
||||
result = subprocess.run(
|
||||
["dpkg-deb", "--contents", deb_file],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
if result.returncode == 0:
|
||||
for line in result.stdout.strip().split("\n"):
|
||||
if line.strip():
|
||||
# dpkg-deb --contents output format: -rw-r--r-- root/root 1234 2024-01-01 00:00 ./path/to/file
|
||||
# Extract the path (last field)
|
||||
parts = line.split()
|
||||
if len(parts) >= 6:
|
||||
file_path = parts[-1]
|
||||
# Remove leading ./ or /
|
||||
if file_path.startswith("./"):
|
||||
file_path = file_path[2:]
|
||||
elif file_path.startswith("/"):
|
||||
file_path = file_path[1:]
|
||||
if file_path:
|
||||
manifest_lines.append(file_path)
|
||||
elif os.path.exists(pkg_dir):
|
||||
# Fallback: scan directory if DEB not found
|
||||
info(f"Warning: DEB file not found for {package_name}, scanning directory instead")
|
||||
for root, dirs, files in os.walk(pkg_dir):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
rel_path = os.path.relpath(file_path, pkg_dir)
|
||||
manifest_lines.append(rel_path)
|
||||
|
||||
manifest_lines.sort()
|
||||
with open(manifest_file, "w") as f:
|
||||
for line in manifest_lines:
|
||||
f.write(line + "\n")
|
||||
|
||||
info(f"Created manifest: {manifest_file} ({len(manifest_lines)} entries)")
|
||||
return manifest_lines
|
||||
|
||||
|
||||
def validate_package_contents(package_name, manifest_lines, allowed_patterns, forbidden_patterns=None):
|
||||
"""Validate package contents against allowlist/forbidden list"""
|
||||
import fnmatch
|
||||
|
||||
errors = []
|
||||
warnings = []
|
||||
|
||||
for file_path in manifest_lines:
|
||||
# Skip directory entries (trailing '/') - only files are allowlisted
|
||||
if file_path.endswith('/'):
|
||||
continue
|
||||
|
||||
# Check forbidden patterns
|
||||
if forbidden_patterns:
|
||||
for pattern in forbidden_patterns:
|
||||
if fnmatch.fnmatch(file_path, pattern):
|
||||
errors.append(f"FORBIDDEN file in {package_name}: {file_path} (matches {pattern})")
|
||||
|
||||
# Check if file matches any allowed pattern
|
||||
allowed = False
|
||||
if allowed_patterns:
|
||||
for pattern in allowed_patterns:
|
||||
if fnmatch.fnmatch(file_path, pattern):
|
||||
allowed = True
|
||||
break
|
||||
|
||||
if not allowed and allowed_patterns:
|
||||
warnings.append(f"Unexpected file in {package_name}: {file_path}")
|
||||
|
||||
if errors:
|
||||
for err in errors:
|
||||
error(f"Validation error: {err}")
|
||||
return False
|
||||
|
||||
if warnings:
|
||||
for warn in warnings:
|
||||
warning(f"Validation warning: {warn}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def build_single_deb(pkg_name, pkg_dir, output_dir, version, build_number, cmake_flags, skip_tests, install_lines, description, section="devel", depends=""):
|
||||
"""Build a single DEB package"""
|
||||
info(f"Building DEB package: {pkg_name}")
|
||||
|
||||
deb_dir = os.path.join(pkg_dir, "debian")
|
||||
os.makedirs(deb_dir)
|
||||
|
||||
create_debian_control(deb_dir, pkg_name, version, build_number, description, depends, section)
|
||||
create_debian_changelog(deb_dir, pkg_name, version, build_number)
|
||||
create_debian_rules(deb_dir, cmake_flags, skip_tests)
|
||||
|
||||
# Create debian/source/format
|
||||
source_dir_path = os.path.join(deb_dir, "source")
|
||||
os.makedirs(source_dir_path)
|
||||
with open(os.path.join(source_dir_path, "format"), "w") as f:
|
||||
f.write("3.0 (quilt)\n")
|
||||
|
||||
# Create debian/compat
|
||||
with open(os.path.join(deb_dir, "compat"), "w") as f:
|
||||
f.write("13\n")
|
||||
|
||||
# Create debian/install
|
||||
if install_lines:
|
||||
create_debian_install(deb_dir, install_lines)
|
||||
|
||||
# Build the package
|
||||
info(f"Running debuild for {pkg_name}...")
|
||||
os.chdir(pkg_dir)
|
||||
|
||||
env = os.environ.copy()
|
||||
env["DEB_BUILD_OPTIONS"] = "parallel=$(nproc)"
|
||||
|
||||
cmd = f"debuild -us -uc -b"
|
||||
debug(f"Executing: {cmd}")
|
||||
ret = subprocess.run(cmd, shell=True, env=env, capture_output=True, text=True)
|
||||
|
||||
if ret.returncode != 0:
|
||||
print(ret.stdout)
|
||||
print(ret.stderr)
|
||||
die(f"debuild failed for {pkg_name} with code {ret.returncode}")
|
||||
|
||||
# Move generated packages to output directory
|
||||
parent_dir = os.path.dirname(pkg_dir)
|
||||
for f in os.listdir(parent_dir):
|
||||
if f.endswith(".deb") or f.endswith(".dsc") or f.endswith(".changes") or f.endswith(".buildinfo"):
|
||||
src = os.path.join(parent_dir, f)
|
||||
dst = os.path.join(output_dir, f)
|
||||
if os.path.exists(dst):
|
||||
os.remove(dst)
|
||||
shutil.move(src, output_dir)
|
||||
info(f"Moved {f} to {output_dir}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def build_single_deb_nobuild(pkg_name, pkg_dir, output_dir, version, build_number, install_lines, description, section="devel", depends="", skip_shlibdeps=False):
|
||||
"""Build a single DEB package without running cmake/make (pre-built files only)
|
||||
|
||||
Args:
|
||||
skip_shlibdeps: If True, skip dh_shlibdeps (useful for test executables with external deps)
|
||||
"""
|
||||
info(f"Building DEB package (no-build): {pkg_name}")
|
||||
|
||||
deb_dir = os.path.join(pkg_dir, "debian")
|
||||
os.makedirs(deb_dir)
|
||||
|
||||
create_debian_control(deb_dir, pkg_name, version, build_number, description, depends, section)
|
||||
create_debian_changelog(deb_dir, pkg_name, version, build_number)
|
||||
create_debian_rules_nobuild(deb_dir, skip_shlibdeps=skip_shlibdeps)
|
||||
|
||||
# Create debian/source/format
|
||||
source_dir_path = os.path.join(deb_dir, "source")
|
||||
os.makedirs(source_dir_path)
|
||||
with open(os.path.join(source_dir_path, "format"), "w") as f:
|
||||
f.write("3.0 (quilt)\n")
|
||||
|
||||
# Create debian/compat
|
||||
with open(os.path.join(deb_dir, "compat"), "w") as f:
|
||||
f.write("13\n")
|
||||
|
||||
# Create debian/install
|
||||
if install_lines:
|
||||
create_debian_install(deb_dir, install_lines)
|
||||
|
||||
# Build the package
|
||||
info(f"Running debuild for {pkg_name}...")
|
||||
os.chdir(pkg_dir)
|
||||
|
||||
env = os.environ.copy()
|
||||
env["DEB_BUILD_OPTIONS"] = "parallel=$(nproc)"
|
||||
|
||||
cmd = f"debuild -us -uc -b"
|
||||
debug(f"Executing: {cmd}")
|
||||
ret = subprocess.run(cmd, shell=True, env=env, capture_output=True, text=True)
|
||||
|
||||
if ret.returncode != 0:
|
||||
print(ret.stdout)
|
||||
print(ret.stderr)
|
||||
die(f"debuild failed for {pkg_name} with code {ret.returncode}")
|
||||
|
||||
# Move generated packages to output directory
|
||||
parent_dir = os.path.dirname(pkg_dir)
|
||||
for f in os.listdir(parent_dir):
|
||||
if f.endswith(".deb") or f.endswith(".dsc") or f.endswith(".changes") or f.endswith(".buildinfo"):
|
||||
src = os.path.join(parent_dir, f)
|
||||
dst = os.path.join(output_dir, f)
|
||||
if os.path.exists(dst):
|
||||
os.remove(dst)
|
||||
shutil.move(src, output_dir)
|
||||
info(f"Moved {f} to {output_dir}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def build_all_debs(source_dir, output_dir, project_name, version, build_number, cmake_flags, release_scope=True):
|
||||
"""Build all 5 required DEB packages - build once, then package"""
|
||||
info("========================================")
|
||||
info("Building 5 DEB packages for Qt6 Release")
|
||||
info("========================================")
|
||||
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
os.makedirs(os.path.join(output_dir, "manifests"), exist_ok=True)
|
||||
|
||||
build_base = os.path.join(source_dir, "deb_build_tmp")
|
||||
remove_directory(build_base)
|
||||
os.makedirs(build_base)
|
||||
|
||||
# Release scope directories
|
||||
release_dirs = ["TetraIF", "Z/src", "Lts/Common"]
|
||||
|
||||
# Source file extensions
|
||||
source_extensions = ['.cpp', '.h', '.hpp', '.cc', '.cxx', '.hxx']
|
||||
script_extensions = ['.py', '.sh', '.cmake', '.txt']
|
||||
|
||||
# ============================================
|
||||
# STEP 1: Build once from full source tree
|
||||
# ============================================
|
||||
info("\n=== Step 1: Building from full source tree ===")
|
||||
build_dir = os.path.join(source_dir, "build")
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
os.chdir(build_dir)
|
||||
|
||||
# Configure
|
||||
info("Running CMake configuration...")
|
||||
cmake_cmd = f"cmake -DCMAKE_BUILD_TYPE=Release {cmake_flags} .."
|
||||
ret = subprocess.run(cmake_cmd, shell=True, capture_output=True, text=True)
|
||||
if ret.returncode != 0:
|
||||
print(ret.stdout)
|
||||
print(ret.stderr)
|
||||
die("CMake configuration failed")
|
||||
|
||||
# Build
|
||||
info("Running build...")
|
||||
build_cmd = f"make -j$(nproc)"
|
||||
ret = subprocess.run(build_cmd, shell=True, capture_output=True, text=True)
|
||||
if ret.returncode != 0:
|
||||
print(ret.stdout)
|
||||
print(ret.stderr)
|
||||
die("Build failed")
|
||||
|
||||
info("Build completed successfully")
|
||||
|
||||
# ============================================
|
||||
# Package 1: qt6-release-runtime
|
||||
# ============================================
|
||||
info("\n=== Building qt6-release-runtime ===")
|
||||
pkg1_name = f"qt6-release-runtime"
|
||||
pkg1_dir = os.path.join(build_base, f"{pkg1_name}-{version}")
|
||||
os.makedirs(pkg1_dir)
|
||||
|
||||
# Copy FULL source tree (needed for debian/rules cmake reference)
|
||||
copy_src_dir_to_dest_dir(source_dir, pkg1_dir, release_scope=False)
|
||||
|
||||
# Install lines for runtime: binaries and libraries from release scope only
|
||||
# CMake install uses component prefixes: ALL->(none), AAR/SV/HLA->SV/, WS->WS/
|
||||
install_lines_1 = []
|
||||
|
||||
# Install from all possible component install paths
|
||||
# ALL component: bin/, lib/
|
||||
# AAR/SV/HLA components: SV/bin/, SV/lib/
|
||||
# WS component: WS/bin/, WS/lib/
|
||||
install_lines_1.append("usr/bin/* usr/bin/")
|
||||
install_lines_1.append("usr/lib/*.so* usr/lib/")
|
||||
install_lines_1.append("usr/SV/bin/* usr/bin/")
|
||||
install_lines_1.append("usr/SV/lib/*.so* usr/lib/")
|
||||
install_lines_1.append("usr/WS/bin/* usr/bin/")
|
||||
install_lines_1.append("usr/WS/lib/*.so* usr/lib/")
|
||||
|
||||
build_single_deb(
|
||||
pkg_name=pkg1_name,
|
||||
pkg_dir=pkg1_dir,
|
||||
output_dir=output_dir,
|
||||
version=version,
|
||||
build_number=build_number,
|
||||
cmake_flags=cmake_flags,
|
||||
skip_tests=True,
|
||||
install_lines=install_lines_1,
|
||||
description="Qt6 Release Runtime - binaries and libraries from release scope S",
|
||||
section="libs"
|
||||
)
|
||||
|
||||
# Create manifest
|
||||
manifest_1 = create_manifest(output_dir, pkg1_name, pkg1_dir)
|
||||
validate_package_contents(pkg1_name, manifest_1,
|
||||
allowed_patterns=["usr/bin/*", "usr/lib/*", "usr/SV/*", "usr/WS/*", "usr/share/doc/*", "debian/*"],
|
||||
forbidden_patterns=["*.cpp", "*.h", "*.hpp", "tests/*", "jenkins/*", "Dockerfile*"])
|
||||
|
||||
# ============================================
|
||||
# Package 2: qt6-release-sources
|
||||
# ============================================
|
||||
info("\n=== Building qt6-release-sources ===")
|
||||
pkg2_name = f"qt6-release-sources"
|
||||
pkg2_dir = os.path.join(build_base, f"{pkg2_name}-{version}")
|
||||
os.makedirs(pkg2_dir)
|
||||
|
||||
# Copy FULL source tree (excluding DDS-related files)
|
||||
copy_src_dir_to_dest_dir(source_dir, pkg2_dir, release_scope=False, file_filter=is_dds_file)
|
||||
|
||||
# Install lines for sources: only from release scope directories
|
||||
install_lines_2 = []
|
||||
for rel_dir in release_dirs:
|
||||
src_dir = os.path.join(pkg2_dir, rel_dir)
|
||||
if os.path.exists(src_dir):
|
||||
for root, dirs, files in os.walk(src_dir):
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.')]
|
||||
for file in files:
|
||||
ext = os.path.splitext(file)[1].lower()
|
||||
if ext in source_extensions or file == "CMakeLists.txt":
|
||||
rel_path = os.path.relpath(os.path.join(root, file), pkg2_dir)
|
||||
dest_dir = os.path.join("usr/src", os.path.dirname(rel_path))
|
||||
install_lines_2.append(f"{rel_path} {dest_dir}/")
|
||||
|
||||
# Use no-build rules for source package
|
||||
build_single_deb_nobuild(
|
||||
pkg_name=pkg2_name,
|
||||
pkg_dir=pkg2_dir,
|
||||
output_dir=output_dir,
|
||||
version=version,
|
||||
build_number=build_number,
|
||||
install_lines=install_lines_2,
|
||||
description="Qt6 Release Sources - C++ source files from release scope S",
|
||||
section="devel"
|
||||
)
|
||||
|
||||
manifest_2 = create_manifest(output_dir, pkg2_name, pkg2_dir)
|
||||
validate_package_contents(pkg2_name, manifest_2,
|
||||
# scope filtering happens at staging time (release_dirs); the
|
||||
# validator only guards against out-of-scope contamination
|
||||
allowed_patterns=["usr/src/*", "usr/share/doc/*", "debian/*"],
|
||||
forbidden_patterns=["build/*", "tests/*", "jenkins/*"])
|
||||
|
||||
# ============================================
|
||||
# Package 3: qt6-release-ctest-runtime
|
||||
# ============================================
|
||||
info("\n=== Building qt6-release-ctest-runtime ===")
|
||||
pkg3_name = f"qt6-release-ctest-runtime"
|
||||
pkg3_dir = os.path.join(build_base, f"{pkg3_name}-{version}")
|
||||
os.makedirs(pkg3_dir)
|
||||
|
||||
# Copy FULL source tree
|
||||
copy_src_dir_to_dest_dir(source_dir, pkg3_dir, release_scope=False)
|
||||
|
||||
# Install lines for CTest runtime: test executables from release scope only
|
||||
install_lines_3 = []
|
||||
|
||||
# Find test executables in build4/bin/ and map to release scope modules
|
||||
test_executables = find_test_executables(pkg3_dir, release_dirs)
|
||||
for exe_path, module_path in test_executables:
|
||||
rel_path = os.path.relpath(exe_path, pkg3_dir)
|
||||
dest_dir = "usr/lib/ctest"
|
||||
install_lines_3.append(f"{rel_path} {dest_dir}/")
|
||||
info(f" Including test executable: {os.path.basename(exe_path)} from {module_path}")
|
||||
|
||||
# Also include CTest configuration files
|
||||
ctest_files = [
|
||||
"build4/CTestTestfile.cmake",
|
||||
"build4/DartConfiguration.tcl",
|
||||
"build4/Testing/TAG",
|
||||
]
|
||||
for ctest_file in ctest_files:
|
||||
if os.path.exists(os.path.join(pkg3_dir, ctest_file)):
|
||||
install_lines_3.append(f"{ctest_file} usr/lib/ctest/")
|
||||
|
||||
build_single_deb_nobuild(
|
||||
pkg_name=pkg3_name,
|
||||
pkg_dir=pkg3_dir,
|
||||
output_dir=output_dir,
|
||||
version=version,
|
||||
build_number=build_number,
|
||||
install_lines=install_lines_3,
|
||||
description="Qt6 Release CTest Runtime - executable test programs from release scope",
|
||||
section="devel",
|
||||
skip_shlibdeps=True
|
||||
)
|
||||
|
||||
manifest_3 = create_manifest(output_dir, pkg3_name, pkg3_dir)
|
||||
validate_package_contents(pkg3_name, manifest_3,
|
||||
allowed_patterns=["usr/lib/ctest/*", "usr/share/doc/*", "debian/*"],
|
||||
forbidden_patterns=["*.cpp", "*.h", "jenkins/*"])
|
||||
|
||||
# ============================================
|
||||
# Package 4: qt6-release-ctest-sources
|
||||
# ============================================
|
||||
info("\n=== Building qt6-release-ctest-sources ===")
|
||||
pkg4_name = f"qt6-release-ctest-sources"
|
||||
pkg4_dir = os.path.join(build_base, f"{pkg4_name}-{version}")
|
||||
os.makedirs(pkg4_dir)
|
||||
|
||||
# Copy FULL source tree
|
||||
copy_src_dir_to_dest_dir(source_dir, pkg4_dir, release_scope=False)
|
||||
|
||||
# Install lines for test sources from release scope only
|
||||
install_lines_4 = []
|
||||
|
||||
# Find test source files in release scope modules
|
||||
test_sources = find_test_sources(pkg4_dir, release_dirs)
|
||||
for rel_path in test_sources:
|
||||
dest_dir = os.path.dirname(rel_path)
|
||||
install_lines_4.append(f"{rel_path} {dest_dir}/")
|
||||
|
||||
build_single_deb_nobuild(
|
||||
pkg_name=pkg4_name,
|
||||
pkg_dir=pkg4_dir,
|
||||
output_dir=output_dir,
|
||||
version=version,
|
||||
build_number=build_number,
|
||||
install_lines=install_lines_4,
|
||||
description="Qt6 Release CTest Sources - test source files from release scope",
|
||||
section="devel"
|
||||
)
|
||||
|
||||
manifest_4 = create_manifest(output_dir, pkg4_name, pkg4_dir)
|
||||
validate_package_contents(pkg4_name, manifest_4,
|
||||
allowed_patterns=["Lts/*", "TetraIF/*", "Z/*", "usr/share/doc/*", "debian/*"],
|
||||
forbidden_patterns=["build/*", "jenkins/*"])
|
||||
|
||||
# ============================================
|
||||
# Package 5: qt6-release-build-pipeline
|
||||
# ============================================
|
||||
info("\n=== Building qt6-release-build-pipeline ===")
|
||||
pkg5_name = f"qt6-release-build-pipeline"
|
||||
pkg5_dir = os.path.join(build_base, f"{pkg5_name}-{version}")
|
||||
os.makedirs(pkg5_dir)
|
||||
|
||||
# Copy FULL source tree
|
||||
copy_src_dir_to_dest_dir(source_dir, pkg5_dir, release_scope=False)
|
||||
|
||||
# Install lines for pipeline files only
|
||||
install_lines_5 = []
|
||||
pipeline_files = [
|
||||
"new_docker_build.sh",
|
||||
"Dockerfile",
|
||||
"Dockerfile.ubuntu26",
|
||||
"jenkins-ci-rme/release-16-10-2026.sh",
|
||||
"rpmbuild/make_rpm_ubuntu26.py",
|
||||
"CMakeLists.txt",
|
||||
"cmake/FindGeographicLib.cmake",
|
||||
"cmake/FindRTI.cmake",
|
||||
"cmake/FindZLIB.cmake",
|
||||
]
|
||||
|
||||
for pipeline_file in pipeline_files:
|
||||
src_file = os.path.join(pkg5_dir, pipeline_file)
|
||||
if os.path.exists(src_file):
|
||||
dest_dir = os.path.join("usr/src/pipeline", os.path.dirname(pipeline_file))
|
||||
install_lines_5.append(f"{pipeline_file} {dest_dir}/")
|
||||
info(f" Added pipeline file: {pipeline_file}")
|
||||
|
||||
build_single_deb_nobuild(
|
||||
pkg_name=pkg5_name,
|
||||
pkg_dir=pkg5_dir,
|
||||
output_dir=output_dir,
|
||||
version=version,
|
||||
build_number=build_number,
|
||||
install_lines=install_lines_5,
|
||||
description="Qt6 Release Build Pipeline - Docker, Jenkins, CMake, and packaging scripts",
|
||||
section="devel"
|
||||
)
|
||||
|
||||
manifest_5 = create_manifest(output_dir, pkg5_name, pkg5_dir)
|
||||
validate_package_contents(pkg5_name, manifest_5,
|
||||
allowed_patterns=["usr/src/pipeline/*", "usr/share/doc/*", "debian/*"],
|
||||
forbidden_patterns=["*.cpp", "*.h", "tests/*"])
|
||||
|
||||
# Cleanup
|
||||
os.chdir(source_dir)
|
||||
remove_directory(build_base)
|
||||
|
||||
info("\n========================================")
|
||||
info(f"DEB package build completed: {output_dir}")
|
||||
info("Generated packages:")
|
||||
for f in os.listdir(output_dir):
|
||||
if f.endswith(".deb"):
|
||||
info(f" - {f}")
|
||||
info("========================================")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Build DEB packages for Legatus Qt6 Release")
|
||||
parser.add_argument("-c", "--config", required=True, help="Config type (LTS)")
|
||||
parser.add_argument("--project_name", required=True, help="Project name (qatar|ahtc|guez)")
|
||||
parser.add_argument("--version", required=True, help="Version (Major.minor)")
|
||||
parser.add_argument("--output_dir", required=True, help="Output directory for packages")
|
||||
parser.add_argument("--source_dir", required=True, help="Source directory path")
|
||||
parser.add_argument("--cmake_build_flags", default="", help="CMake build flags")
|
||||
parser.add_argument("--build_number", default="1", help="Build number")
|
||||
parser.add_argument("--release_scope", action="store_true", help="Only include release scope files")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
info(f"Building {args.config} package for {args.project_name} v{args.version}")
|
||||
info(f"Output directory: {args.output_dir}")
|
||||
info(f"Source directory: {args.source_dir}")
|
||||
info(f"CMake flags: {args.cmake_build_flags}")
|
||||
info(f"Release scope: {args.release_scope}")
|
||||
|
||||
source_dir = args.source_dir
|
||||
|
||||
info(f"Source directory: {source_dir}")
|
||||
|
||||
build_all_debs(
|
||||
source_dir=source_dir,
|
||||
output_dir=args.output_dir,
|
||||
project_name=args.project_name,
|
||||
version=args.version,
|
||||
build_number=args.build_number,
|
||||
cmake_flags=args.cmake_build_flags,
|
||||
release_scope=args.release_scope
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user