DEB: build the Release 2 scope instead of the impossible full tree

A full-tree build (ninja all) is not possible on the Release 2 tree:
out-of-scope modules reference modules excluded from the scope
(e.g. TopicEditorBase -> LtsScriptTimeline; 100+ CMakeLists references),
and cmake --install hard-fails on targets that were never built. Align
the DEB pipeline with its own description (binaries and libraries from
release scope S):

- make_rpm_ubuntu26_release2.py: new --build_targets option
  (space-separated CMake/Ninja targets; empty = legacy full tree).
  Step 1 builds only those targets; the runtime DEB is staged from the
  scoped build artifacts (bin/ + lib/) and packaged with build_deb
  nobuild, replacing the full-tree debuild/cmake-buildsystem path.
- new_docker_build_release2.sh: pass the Release 2 group targets via
  --build_targets; exclude the driver build4* dirs from the staging tar
  (the DEB step builds its own tree; nothing consumes the driver build
  output). Fix two comments inside the single-quoted docker bash -c
  string that contained apostrophes, which broke word construction and
  failed bash -n.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
berrux-devandClaude Code committed 2026-11-13 18:27:40 +01:00
1 parent 1646c5c71c
commit 646b1fc8ba
2 files changed
+58 -19

No files matched your search

@@ -586,9 +586,16 @@ if [[ "${RUN_JENKINS_BUILDER}" == "ON" ]]; then
log_info "Staging workspace to ${STAGE_DIR}"
rm -rf "${STAGE_DIR}"
mkdir -p "${STAGE_DIR}"
# Exclude build4* (the driver build dirs, e.g. build4_<timestamp>): the DEB
# pipeline builds its own tree in <staging>/build; nothing in the DEB step
# consumes the driver build output (the ctest DEB looks for a plain build4
# dir, which the driver never creates; it uses build4_<timestamp> instead).
# NOTE: no apostrophes allowed in comments here - this block lives inside
# the single-quoted docker bash -c string (see lines 477/653).
tar --exclude='./rpms' --exclude='./.git' --exclude='./build' \
--exclude='./deb_build_tmp' --exclude='./deb_stage' --exclude='./packages-out' \
--exclude='./legatus-qt6_1.0.tar.gz' \
--exclude=./build4\* \
-cf - -C "${WORKSPACE_DIR}" . | tar -xf - -C "${STAGE_DIR}"
if [[ ! -f "${STAGED_SOURCE_DIR}/CMakeLists.txt" || ! -f "${STAGED_SOURCE_DIR}/rpmbuild/make_rpm_ubuntu26_release2.py" ]]; then
@@ -607,8 +614,8 @@ if [[ "${RUN_JENKINS_BUILDER}" == "ON" ]]; then
# DEB cmake flags: -DBUILD_RTI=ON is required - the full-tree DEB build
# compiles RTI codegen consumers (e.g. svcPdmCommon -> pdm_enums.hpp)
# whose BUILD_RTI=OFF stubs were removed as "forbidden OFF variants".
# (A '#' line inside a backslash-continued command breaks the continuation
# and drops the remaining arguments - keep comments outside it.)
# (A lone hash line inside a backslash-continued command breaks the
# continuation and drops the remaining arguments - keep comments outside it.)
cd "${STAGED_SOURCE_DIR}/rpmbuild"
if python3 make_rpm_ubuntu26_release2.py -c LTS \
--project_name "${PROJECT}" \
@@ -616,6 +623,7 @@ if [[ "${RUN_JENKINS_BUILDER}" == "ON" ]]; then
--output_dir "${DOCKER_MOUNT_ROOT}/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/ -DBUILD_RTI=ON -DRELEASE_BUILD=ON" \
--build_targets "${GROUP1_TARGETS[*]} ${GROUP3_TARGETS[*]} ${GROUP5_TARGETS[*]} ${GROUP6_TARGETS[*]}" \
--build_number "${BUILD_NUMBER}" \
--release_scope; then
log_info "Package build completed successfully"
@@ -408,8 +408,14 @@ def build_nobuild_package(name, source_dir, build_base, output_dir, version, bui
validate_package_contents(name, manifest, allowed_patterns, forbidden_patterns)
def build_all_debs(source_dir, output_dir, version, build_number, cmake_flags):
"""Build the 5 DEB packages: build once from the source tree, then package."""
def build_all_debs(source_dir, output_dir, version, build_number, cmake_flags,
build_targets=""):
"""Build the 5 DEB packages: build once from the source tree, then package.
build_targets: space-separated CMake/Ninja target list (the Release 2
scope). When non-empty, only these targets are built; when empty, the
legacy full-tree build is used.
"""
info("========================================")
info("Building 5 DEB packages for Qt6 Release")
info("========================================")
@@ -420,8 +426,16 @@ def build_all_debs(source_dir, output_dir, version, build_number, cmake_flags):
os.makedirs(build_base)
release_dirs = ["TetraIF", "Z/src", "Lts/Common"]
# Step 1: build once from the full source tree
info("\n=== Step 1: Building from full source tree ===")
# Step 1: build the release scope from the source tree.
# A full-tree build (ninja all) is NOT possible on the Release 2 tree:
# out-of-scope modules reference modules excluded from the scope
# (e.g. TopicEditorBase -> LtsScriptTimeline, 100+ CMakeLists files), so
# their link rules fail. The release scope is built instead.
info("\n=== Step 1: Building release scope ===")
if build_targets:
info(f"Targets: {build_targets}")
else:
warning("No target list given - building the full tree (legacy behavior)")
build_dir = os.path.join(source_dir, "build")
os.makedirs(build_dir, exist_ok=True)
os.chdir(build_dir)
@@ -432,27 +446,40 @@ def build_all_debs(source_dir, output_dir, version, build_number, cmake_flags):
# breaks every Qt target. Ninja handles automoc correctly.
run(f"cmake -G Ninja -DCMAKE_BUILD_TYPE=Release {cmake_flags} ..", "CMake configuration failed")
info("Running build...")
run(f"ninja -j$(nproc)", "Build failed")
run(f"ninja -j$(nproc) {build_targets}".rstrip(), "Build failed")
info("Build completed successfully")
# Package 1: qt6-release-runtime (binaries and libraries, built via debuild)
# Package 1: qt6-release-runtime (binaries and libraries from release scope S)
#
# The artifacts are taken from the step-1 scoped build above. A debuild
# with the cmake buildsystem is not an option here: dh_auto_install runs
# 'cmake --install', which fails hard on every target that has an install
# rule but was not built (file INSTALL cannot find), and a full build is
# not possible on the Release 2 tree (see step 1).
info("\n=== Building qt6-release-runtime ===")
pkg1_dir = os.path.join(build_base, f"qt6-release-runtime-{version}")
os.makedirs(pkg1_dir)
# FULL source tree (needed for debian/rules cmake reference)
copy_src_dir_to_dest_dir(source_dir, pkg1_dir)
# Install from all component install paths: ALL -> bin/, lib/ ; SV/ ; WS/
staged = 0
for src_root, dst_root in ((os.path.join(build_dir, "bin"), "usr/bin"),
(os.path.join(build_dir, "lib"), "usr/lib")):
if not os.path.isdir(src_root):
continue
for entry in sorted(os.listdir(src_root)):
src_path = os.path.join(src_root, entry)
if not os.path.isfile(src_path):
continue
dst_dir = os.path.join(pkg1_dir, dst_root)
os.makedirs(dst_dir, exist_ok=True)
shutil.copy2(src_path, os.path.join(dst_dir, entry))
staged += 1
info(f"Staged {staged} artifacts from {build_dir}")
install_lines_1 = [
"usr/bin/* usr/bin/",
"usr/lib/*.so* usr/lib/",
"usr/SV/bin/* usr/bin/",
"usr/SV/lib/*.so* usr/lib/",
"usr/WS/bin/* usr/bin/",
"usr/WS/lib/*.so* usr/lib/",
"usr/lib/* usr/lib/",
]
build_deb(pkg_name="qt6-release-runtime", 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,
version=version, build_number=build_number, nobuild=True,
skip_shlibdeps=True, install_lines=install_lines_1,
description="Qt6 Release Runtime - binaries and libraries from release scope S",
section="libs")
manifest_1 = create_manifest(output_dir, "qt6-release-runtime", pkg1_dir)
@@ -517,6 +544,9 @@ def main():
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")
parser.add_argument("--build_targets", default="",
help="Space-separated CMake/Ninja targets to build "
"(release scope); empty = full tree (legacy)")
args = parser.parse_args()
info(f"Building {args.config} package for {args.project_name} v{args.version}")
@@ -526,7 +556,8 @@ def main():
info(f"Release scope: {args.release_scope}")
build_all_debs(source_dir=args.source_dir, output_dir=args.output_dir,
version=args.version, build_number=args.build_number,
cmake_flags=args.cmake_build_flags)
cmake_flags=args.cmake_build_flags,
build_targets=args.build_targets)
if __name__ == "__main__":