Adds pycache
This commit is contained in:
2 files changed
+819
No files matched your search
@@ -1,2 +1,3 @@
|
||||
.svn/
|
||||
packages-out/
|
||||
__pycache__
|
||||
Executable
+818
@@ -0,0 +1,818 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Build DEB packages for Qt6 Release 2
|
||||
|
||||
This script creates 5 DEB packages from the Release 2 scope:
|
||||
- qt6-release-runtime: Binaries and libraries
|
||||
- qt6-release-sources: C++ source files
|
||||
- qt6-release-ctest-runtime: Test executables
|
||||
- qt6-release-ctest-sources: Test source files
|
||||
- qt6-release-build-pipeline: Build scripts and configuration
|
||||
|
||||
Release 2 scope (S set - 39 modules):
|
||||
- Lts/Common (15 modules)
|
||||
- Lts/DDS (10 modules)
|
||||
- Lts/Services (6 modules in 3 directories)
|
||||
- Lts/Proxies/TrainingAreaBase (1 module)
|
||||
- Lts/Tools (7 AP9 tools)
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import subprocess
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
# Import helpers from rpmbuild
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'rpmbuild'))
|
||||
from helpers import info, debug, warning as warn, die, removeDirectory
|
||||
|
||||
|
||||
def copy_src_dir_to_dest_dir(src_dir, dest_dir, release_scope=False, release_dirs=None, 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
|
||||
release_dirs: List of release scope directories (Release 2 specific)
|
||||
file_filter: Optional function to filter files (filepath) -> bool, returns True to EXCLUDE
|
||||
"""
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
|
||||
# Release 2 scope directories (S set)
|
||||
if release_dirs is None:
|
||||
release_dirs = [
|
||||
"Lts/Common",
|
||||
"Lts/DDS",
|
||||
"Lts/Services",
|
||||
"Lts/Proxies/TrainingAreaBase",
|
||||
"Lts/Tools"
|
||||
]
|
||||
|
||||
if release_scope:
|
||||
info(f"Copying 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
|
||||
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
|
||||
|
||||
# Skip broken symlinks
|
||||
if os.path.islink(src_file) and not os.path.exists(src_file):
|
||||
debug(f"Skipping broken symlink: {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
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.')
|
||||
and d not in ['build', 'cmake-build-debug', 'cmake-build-release', 'deb_build_tmp', 'deb_packages']]
|
||||
|
||||
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
|
||||
if file_filter and file_filter(src_file):
|
||||
continue
|
||||
|
||||
# Skip broken symlinks
|
||||
if os.path.islink(src_file) and not os.path.exists(src_file):
|
||||
debug(f"Skipping broken symlink: {src_file}")
|
||||
continue
|
||||
|
||||
os.makedirs(os.path.dirname(dest_file), exist_ok=True)
|
||||
shutil.copy2(src_file, dest_file)
|
||||
|
||||
|
||||
def is_dds_file(filepath):
|
||||
"""Check if a file or directory path contains DDS-related content that should be excluded
|
||||
|
||||
For Release 2, we INCLUDE DDS files in the sources package since DDS is part of our scope.
|
||||
This function is kept for compatibility but returns False for all files.
|
||||
|
||||
Args:
|
||||
filepath: Path to check
|
||||
|
||||
Returns:
|
||||
False (include all files for Release 2)
|
||||
"""
|
||||
return False
|
||||
|
||||
|
||||
def create_manifest(output_dir, pkg_name, pkg_dir):
|
||||
"""Create a manifest file listing all files in the package"""
|
||||
manifest_path = os.path.join(output_dir, "manifests", f"{pkg_name}.txt")
|
||||
os.makedirs(os.path.dirname(manifest_path), exist_ok=True)
|
||||
|
||||
files = []
|
||||
for root, dirs, filenames in os.walk(pkg_dir):
|
||||
rel_root = os.path.relpath(root, pkg_dir)
|
||||
for filename in filenames:
|
||||
full_path = os.path.join(rel_root, filename) if rel_root != '.' else filename
|
||||
files.append(full_path)
|
||||
|
||||
with open(manifest_path, 'w') as f:
|
||||
f.write('\n'.join(sorted(files)))
|
||||
|
||||
return manifest_path
|
||||
|
||||
|
||||
def validate_package_contents(pkg_name, manifest_path, allowed_patterns=None, forbidden_patterns=None):
|
||||
"""Validate package contents against allowlist and denylist"""
|
||||
info(f"Validating {pkg_name} contents...")
|
||||
|
||||
with open(manifest_path, 'r') as f:
|
||||
files = [line.strip() for line in f if line.strip()]
|
||||
|
||||
import fnmatch
|
||||
|
||||
if forbidden_patterns:
|
||||
for pattern in forbidden_patterns:
|
||||
for file in files:
|
||||
if fnmatch.fnmatch(file, pattern):
|
||||
warn(f" Forbidden file found: {file} (matches {pattern})")
|
||||
|
||||
info(f" Found {len(files)} files in {pkg_name}")
|
||||
return True
|
||||
|
||||
|
||||
def create_debian_control(deb_dir, package_name, version, build_number, description, depends="", section="devel"):
|
||||
"""Create debian/control file for a package (binary package format for dpkg-deb)"""
|
||||
control_path = os.path.join(deb_dir, "control")
|
||||
|
||||
# Runtime dependencies for Release 2
|
||||
runtime_deps = "" # dpkg-deb does not support debhelper variables
|
||||
if depends:
|
||||
runtime_deps += f", {depends}"
|
||||
|
||||
# Binary package control format (required by dpkg-deb)
|
||||
control_content = f"""Package: {package_name}
|
||||
Version: {version}-{build_number}
|
||||
Section: {section}
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
Maintainer: Qt6 Release Team <qt6-release@example.com>
|
||||
Depends: {runtime_deps}
|
||||
Description: Qt6 Release 2 - {description}
|
||||
This package contains {description.lower()} for the Qt6 Release 2 delivery.
|
||||
.
|
||||
Release 2 scope includes:
|
||||
- AP3: LtsUtils, LtsWidgets, LtsSession, LtsLicence, LtsPluginManager
|
||||
- AP4: Core, DDSConnector, Routing, QosProfile, RTI DDS
|
||||
- AP9: DdsView, LogViewer, SqlBrowser, 3 generators, lupdate
|
||||
"""
|
||||
|
||||
with open(control_path, 'w') as f:
|
||||
f.write(control_content)
|
||||
|
||||
|
||||
def create_debian_changelog(deb_dir, package_name, version, build_number):
|
||||
"""Create debian/changelog file"""
|
||||
changelog_path = os.path.join(deb_dir, "changelog")
|
||||
|
||||
changelog_content = f"""{package_name} ({version}-{build_number}) unstable; urgency=medium
|
||||
|
||||
* Qt6 Release 2 delivery
|
||||
* Scope: AP3, AP4, AP9 modules (39 modules total)
|
||||
* Includes: Common, DDS, Services, Proxies/TrainingAreaBase, Tools
|
||||
|
||||
-- Qt6 Release Team <qt6-release@example.com> {subprocess.check_output(['date', '-R']).decode().strip()}
|
||||
"""
|
||||
|
||||
with open(changelog_path, 'w') as f:
|
||||
f.write(changelog_content)
|
||||
|
||||
|
||||
def create_debian_rules(deb_dir, cmake_flags="", skip_tests=False, use_prebuilt=False):
|
||||
"""Create debian/rules file"""
|
||||
rules_path = os.path.join(deb_dir, "rules")
|
||||
|
||||
if use_prebuilt:
|
||||
# No-build rules - just package existing files
|
||||
rules_content = """#!/usr/bin/make -f
|
||||
# Debian rules file for Qt6 Release 2 (pre-built artifacts)
|
||||
|
||||
%:
|
||||
\tdh $@
|
||||
|
||||
override_dh_auto_configure:
|
||||
\t# No configuration needed - using pre-built artifacts
|
||||
|
||||
override_dh_auto_build:
|
||||
\t# No build needed - using pre-built artifacts
|
||||
|
||||
override_dh_auto_install:
|
||||
\t# Files already in place via debian/install
|
||||
"""
|
||||
else:
|
||||
test_flag = "-DENABLE_TESTS=OFF" if skip_tests else "-DENABLE_TESTS=ON"
|
||||
|
||||
rules_content = f"""#!/usr/bin/make -f
|
||||
# Debian rules file for Qt6 Release 2
|
||||
|
||||
%:
|
||||
\tdh $@
|
||||
|
||||
override_dh_auto_configure:
|
||||
\tdh_auto_configure -- -DCMAKE_BUILD_TYPE=Release {cmake_flags} {test_flag}
|
||||
|
||||
override_dh_auto_build:
|
||||
\tdh_auto_build
|
||||
|
||||
override_dh_auto_test:
|
||||
\t# Skip tests during package build (run separately with ctest)
|
||||
\ttrue
|
||||
|
||||
override_dh_auto_install:
|
||||
\tdh_auto_install --destdir=debian/tmp
|
||||
"""
|
||||
|
||||
with open(rules_path, 'w') as f:
|
||||
f.write(rules_content)
|
||||
os.chmod(rules_path, 0o755)
|
||||
|
||||
|
||||
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)"""
|
||||
rules_path = os.path.join(deb_dir, "rules")
|
||||
|
||||
shlibdeps_override = ""
|
||||
if skip_shlibdeps:
|
||||
shlibdeps_override = """
|
||||
override_dh_shlibdeps:
|
||||
\t# Skip shared library dependencies (test executables may have external deps)
|
||||
\ttrue
|
||||
"""
|
||||
|
||||
rules_content = f"""#!/usr/bin/make -f
|
||||
# Debian rules file for Qt6 Release 2 (no-build package){shlibdeps_override}
|
||||
|
||||
%:
|
||||
\tdh $@
|
||||
|
||||
override_dh_auto_configure:
|
||||
\t# No configuration needed (pre-built files)
|
||||
\ttrue
|
||||
|
||||
override_dh_auto_build:
|
||||
\t# No build needed (pre-built files)
|
||||
\ttrue
|
||||
|
||||
override_dh_auto_install:
|
||||
\t# Files installed via debian/install
|
||||
\ttrue
|
||||
|
||||
override_dh_auto_test:
|
||||
\t# No tests in this package
|
||||
\ttrue
|
||||
"""
|
||||
|
||||
with open(rules_path, 'w') as f:
|
||||
f.write(rules_content)
|
||||
os.chmod(rules_path, 0o755)
|
||||
|
||||
|
||||
def create_debian_install(deb_dir, install_lines):
|
||||
"""Create debian/install file from list of file entries"""
|
||||
install_path = os.path.join(deb_dir, "install")
|
||||
|
||||
with open(install_path, 'w') as f:
|
||||
f.write('\n'.join(install_lines))
|
||||
|
||||
|
||||
def find_test_executables(pkg_dir, release_dirs):
|
||||
"""Find test executables in build directory"""
|
||||
test_executables = []
|
||||
|
||||
# Look for test executables in build directories
|
||||
build_dirs = ['build/bin', 'build4/bin', 'build-release/bin']
|
||||
|
||||
for build_dir in build_dirs:
|
||||
bin_path = os.path.join(pkg_dir, build_dir)
|
||||
if os.path.exists(bin_path):
|
||||
for f in os.listdir(bin_path):
|
||||
if f.startswith('test') or f.endswith('_test'):
|
||||
exe_path = os.path.join(bin_path, f)
|
||||
if os.path.isfile(exe_path) and os.access(exe_path, os.X_OK):
|
||||
# Try to determine which module this test belongs to
|
||||
module_path = "unknown"
|
||||
for rel_dir in release_dirs:
|
||||
if rel_dir.lower() in f.lower():
|
||||
module_path = rel_dir
|
||||
break
|
||||
test_executables.append((exe_path, module_path))
|
||||
|
||||
return test_executables
|
||||
|
||||
|
||||
def find_test_sources(pkg_dir, release_dirs):
|
||||
"""Find test source files in release scope modules"""
|
||||
test_sources = []
|
||||
|
||||
for rel_dir in release_dirs:
|
||||
module_path = os.path.join(pkg_dir, rel_dir)
|
||||
if os.path.exists(module_path):
|
||||
for root, dirs, files in os.walk(module_path):
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.')]
|
||||
for file in files:
|
||||
if 'test' in file.lower() and (file.endswith('.cpp') or file.endswith('.h')):
|
||||
rel_path = os.path.relpath(os.path.join(root, file), pkg_dir)
|
||||
test_sources.append(rel_path)
|
||||
|
||||
return test_sources
|
||||
|
||||
|
||||
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)"""
|
||||
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 using dpkg-deb directly
|
||||
info(f"Building DEB package for {pkg_name} using dpkg-deb...")
|
||||
original_dir = os.getcwd()
|
||||
os.chdir(pkg_dir)
|
||||
|
||||
# dpkg-deb --build creates the .deb file directly
|
||||
deb_file = f"{pkg_name}_{version}-{build_number}_amd64.deb"
|
||||
cmd = f"dpkg-deb --build . ../{deb_file}"
|
||||
debug(f"Executing: {cmd}")
|
||||
ret = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
||||
|
||||
# Change back to original directory
|
||||
os.chdir(original_dir)
|
||||
|
||||
if ret.returncode != 0:
|
||||
print(ret.stdout)
|
||||
print(ret.stderr)
|
||||
die(f"dpkg-deb failed for {pkg_name} with code {ret.returncode}")
|
||||
|
||||
# Move the .deb file to output directory
|
||||
parent_dir = os.path.dirname(pkg_dir)
|
||||
deb_path = os.path.join(parent_dir, deb_file)
|
||||
if os.path.exists(deb_path):
|
||||
dst = os.path.join(output_dir, deb_file)
|
||||
if os.path.exists(dst):
|
||||
os.remove(dst)
|
||||
shutil.move(deb_path, output_dir)
|
||||
info(f"Moved {deb_file} to {output_dir}")
|
||||
|
||||
# Clean up build directory to save disk space
|
||||
info(f"Cleaning up build directory: {pkg_dir}")
|
||||
try:
|
||||
shutil.rmtree(pkg_dir, ignore_errors=True)
|
||||
except Exception as e:
|
||||
warning(f"Failed to clean up {pkg_dir}: {e}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def build_all_debs(source_dir, output_dir, project_name, version, build_number, cmake_flags, release_scope=True):
|
||||
"""Build all 5 DEB packages for Release 2 using pre-built artifacts"""
|
||||
info("========================================")
|
||||
info("Building 5 DEB packages for Qt6 Release 2")
|
||||
info("========================================")
|
||||
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
os.makedirs(os.path.join(output_dir, "manifests"), exist_ok=True)
|
||||
|
||||
build_base = os.path.join("/tmp", "qt6_deb_build_" + str(os.getpid()))
|
||||
# removeDirectory(build_base) # Skip removal when using /tmp
|
||||
os.makedirs(build_base)
|
||||
|
||||
# Release 2 scope directories (S set - 39 modules)
|
||||
release_dirs = [
|
||||
"Lts/Common",
|
||||
"Lts/DDS",
|
||||
"Lts/Services",
|
||||
"Lts/Proxies/TrainingAreaBase",
|
||||
"Lts/Tools"
|
||||
]
|
||||
|
||||
# Source file extensions
|
||||
source_extensions = ['.cpp', '.h', '.hpp', '.cc', '.cxx', '.hxx']
|
||||
script_extensions = ['.py', '.sh', '.cmake', '.txt']
|
||||
|
||||
# ============================================
|
||||
# STEP 1: Use pre-built artifacts from build4/
|
||||
# ============================================
|
||||
info("\n=== Step 1: Using pre-built artifacts from build4/ ===")
|
||||
build4_dir = os.path.join(source_dir, "build4")
|
||||
|
||||
if not os.path.exists(build4_dir):
|
||||
die(f"Pre-built artifacts not found in {build4_dir}. Run build first.")
|
||||
|
||||
# Verify libraries exist
|
||||
lib_dir = os.path.join(build4_dir, "lib")
|
||||
if not os.path.exists(lib_dir):
|
||||
die(f"Library directory not found: {lib_dir}")
|
||||
|
||||
lib_count = len([f for f in os.listdir(lib_dir) if f.endswith('.so')])
|
||||
info(f"Found {lib_count} shared libraries in build4/lib/")
|
||||
|
||||
# Verify tool executables exist
|
||||
tools_build_dir = os.path.join(build4_dir, "Lts", "Tools")
|
||||
if os.path.exists(tools_build_dir):
|
||||
info(f"AP9 tools build directory exists: {tools_build_dir}")
|
||||
|
||||
bin_dir = os.path.join(build4_dir, "bin")
|
||||
if os.path.exists(bin_dir):
|
||||
tool_exes = [f for f in os.listdir(bin_dir) if f.startswith('t') or 'generator' in f.lower()]
|
||||
if tool_exes:
|
||||
info(f"Found tool executables in build4/bin/: {', '.join(tool_exes)}")
|
||||
|
||||
info("Pre-built artifacts verified 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)
|
||||
|
||||
# Create package structure
|
||||
pkg1_lib_dir = os.path.join(pkg1_dir, "usr", "lib")
|
||||
pkg1_bin_dir = os.path.join(pkg1_dir, "usr", "bin")
|
||||
os.makedirs(pkg1_lib_dir, exist_ok=True)
|
||||
os.makedirs(pkg1_bin_dir, exist_ok=True)
|
||||
|
||||
# Copy pre-built libraries from build4/lib
|
||||
info("Copying libraries from build4/lib/...")
|
||||
for f in os.listdir(lib_dir):
|
||||
if f.endswith('.so') or f.endswith('.so.1') or f.startswith('lib'):
|
||||
src = os.path.join(lib_dir, f)
|
||||
dst = os.path.join(pkg1_lib_dir, f)
|
||||
if os.path.isfile(src):
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
# Copy tool executables from build4/bin
|
||||
info("Copying executables from build4/bin/...")
|
||||
if os.path.exists(bin_dir):
|
||||
for f in os.listdir(bin_dir):
|
||||
fpath = os.path.join(bin_dir, f)
|
||||
if os.path.isfile(fpath) and (f.startswith('t') or 'generator' in f.lower() or f in ['ddsview', 'sqlbrowser', 'LogViewer', 'topicdiscover']):
|
||||
shutil.copy2(fpath, os.path.join(pkg1_bin_dir, f))
|
||||
|
||||
# Copy tool executables from build4/Lts/Tools subdirectories
|
||||
if os.path.exists(tools_build_dir):
|
||||
for tool_subdir in os.listdir(tools_build_dir):
|
||||
tool_bin_path = os.path.join(tools_build_dir, tool_subdir, "bin")
|
||||
if os.path.exists(tool_bin_path):
|
||||
for exe in os.listdir(tool_bin_path):
|
||||
if exe and not exe.startswith('.'):
|
||||
src = os.path.join(tool_bin_path, exe)
|
||||
if os.path.isfile(src):
|
||||
shutil.copy2(src, os.path.join(pkg1_bin_dir, exe))
|
||||
|
||||
# Install lines for runtime
|
||||
install_lines_1 = []
|
||||
install_lines_1.append("usr/lib/* usr/lib/")
|
||||
install_lines_1.append("usr/bin/* usr/bin/")
|
||||
|
||||
build_single_deb_nobuild(
|
||||
pkg_name=pkg1_name,
|
||||
pkg_dir=pkg1_dir,
|
||||
output_dir=output_dir,
|
||||
version=version,
|
||||
build_number=build_number,
|
||||
install_lines=install_lines_1,
|
||||
description="Runtime binaries and libraries for Release 2 scope (AP3, AP4, AP9)",
|
||||
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/*", "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 (Release 2 includes DDS files)
|
||||
copy_src_dir_to_dest_dir(source_dir, pkg2_dir, release_scope=False, release_dirs=release_dirs)
|
||||
|
||||
# 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="C++ source files for Release 2 scope (AP3, AP4, AP9)",
|
||||
section="devel"
|
||||
)
|
||||
|
||||
manifest_2 = create_manifest(output_dir, pkg2_name, pkg2_dir)
|
||||
validate_package_contents(pkg2_name, manifest_2,
|
||||
allowed_patterns=["usr/src/**/*.cpp", "usr/src/**/*.h", "usr/src/**/CMakeLists.txt", "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, release_dirs=release_dirs)
|
||||
|
||||
# Install lines for CTest runtime: test executables from release scope only
|
||||
install_lines_3 = []
|
||||
|
||||
# Find test executables in build directory
|
||||
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 = [
|
||||
"build/CTestTestfile.cmake",
|
||||
"build/DartConfiguration.tcl",
|
||||
"build/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="Test executables for Release 2 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/*", "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, release_dirs=release_dirs)
|
||||
|
||||
# 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} usr/src/{dest_dir}/")
|
||||
info(f" Including test source: {rel_path}")
|
||||
|
||||
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="Test source files for Release 2 scope",
|
||||
section="devel"
|
||||
)
|
||||
|
||||
manifest_4 = create_manifest(output_dir, pkg4_name, pkg4_dir)
|
||||
validate_package_contents(pkg4_name, manifest_4,
|
||||
allowed_patterns=["usr/src/**/tests/*", "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 pipeline scripts and configuration
|
||||
# Note: pipeline dirs are at project root, not in qt-migration-legatus
|
||||
pipeline_dirs = [
|
||||
"jenkins-ci-rme",
|
||||
"docker",
|
||||
"scripts"
|
||||
]
|
||||
|
||||
# Use parent of source_dir as project root (source_dir points to qt-migration-legatus/qt6-after/qt6-migrated-legatus)
|
||||
project_root = os.path.dirname(os.path.dirname(os.path.dirname(source_dir)))
|
||||
|
||||
install_lines_5 = []
|
||||
for pipeline_dir in pipeline_dirs:
|
||||
src_pipeline = os.path.join(project_root, pipeline_dir)
|
||||
dest_pipeline = os.path.join(pkg5_dir, pipeline_dir)
|
||||
if os.path.exists(src_pipeline):
|
||||
shutil.copytree(src_pipeline, dest_pipeline, dirs_exist_ok=True)
|
||||
for root, dirs, files in os.walk(dest_pipeline):
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.')]
|
||||
for file in files:
|
||||
rel_path = os.path.relpath(os.path.join(root, file), pkg5_dir)
|
||||
install_lines_5.append(f"{rel_path} usr/src/pipeline/{os.path.dirname(rel_path)}/")
|
||||
|
||||
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="Build pipeline scripts and configuration for Release 2",
|
||||
section="devel"
|
||||
)
|
||||
|
||||
manifest_5 = create_manifest(output_dir, pkg5_name, pkg5_dir)
|
||||
validate_package_contents(pkg5_name, manifest_5,
|
||||
allowed_patterns=["usr/src/pipeline/*", "debian/*"],
|
||||
forbidden_patterns=["*.cpp", "*.h", "build/*"])
|
||||
|
||||
info("\n========================================")
|
||||
info("All 5 DEB packages built successfully!")
|
||||
info(f"Output directory: {output_dir}")
|
||||
info("========================================")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Build DEB packages for Qt6 Release 2")
|
||||
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