UniversalChip Studio · Release Engineering

RHEL7 / RHEL8
Build Workflow

Rust、Python、Perl 客户程序的双平台构建、license 校验、ABI 门禁、测试、归档与 Usage 发布规则。

发布约定

同一份源码分别在目标 ABI 的容器中构建。宿主机只负责调度,不能代替目标系统。

目标构建系统最大 GLIBC服务器目录
RHEL7 / CentOS 7CentOS 7.92.17compiled_version/<tool>/RHEL7
RHEL8RHEL/Rocky/UBI 82.28compiled_version/<tool>/RHEL8
禁止:直接在服务器宿主机编译 RHEL8 客户程序。宿主机 GLIBC 是 2.32,会生成不兼容的二进制。
/root/ucs_code/source_code/<domain>/<tool>/<language>  # 源程序
/root/ucs_code/compiled_version/<tool>/RHEL7             # 客户程序
/root/ucs_code/compiled_version/<tool>/RHEL8
/root/ucs_build_jobs/<tool>/<timestamp>                  # 临时构建、日志

服务器构建镜像

Rust readyRHEL7 / RHEL8 · Rust 1.97
Python readyRHEL7 Python 3.6 · RHEL8 Python 3.9
Perl readyRHEL7 Perl 5.16 · RHEL8 Perl 5.26
语言RHEL7RHEL8
Rustucs/rhel7-rust-gui-build:20260714ucs/rhel8-rust-gui-build:20260714
Pythonucs/centos7-build:latestucs/rhel8-python-build:20260726
Perlucs/centos7-build:latestucs/rhel8-build:latest

新建的 RHEL8 Python 镜像已完成 PyInstaller one-file 实测:GLIBC 2.14,能够在 RHEL8 runtime 镜像运行。

建立隔离构建任务

export TOOL=ucs_example
export LANGUAGE=rust
export SOURCE=/root/ucs_code/source_code/<domain>/<tool>/<language>
export STAMP="$(date +%Y%m%d_%H%M%S)"
export JOB="/root/ucs_build_jobs/${TOOL}/${STAMP}"

mkdir -p "$JOB/src" "$JOB/out/RHEL7" "$JOB/out/RHEL8" "$JOB/logs"
rsync -a --delete --exclude target --exclude build --exclude dist \
  --exclude __pycache__ --exclude '*.log' --exclude '.ucs_license.conf' \
  "$SOURCE/" "$JOB/src/"
find "$JOB/src" -type f -print0 | sort -z | xargs -0 sha256sum \
  > "$JOB/SOURCE_SHA256SUMS"

所有生成日志必须位于 $JOB/logs;不能写到维护源码或客户程序目录。

Rust

cd "$JOB/src"
cargo fmt --all -- --check
cargo test --locked
cargo clippy --all-targets --all-features -- -D warnings

RHEL7

docker run --rm -v "$JOB:/work" -w /work/src \
  ucs/rhel7-rust-gui-build:20260714 bash -lc '
    export CARGO_TARGET_DIR=/work/target/RHEL7
    cargo build --release --locked --bin '"$TOOL"'
    install -m 0755 "$CARGO_TARGET_DIR"/release/'"$TOOL"' \
      /work/out/RHEL7/'"$TOOL"'
  '

RHEL8

docker run --rm -v "$JOB:/work" -w /work/src \
  ucs/rhel8-rust-gui-build:20260714 bash -lc '
    export CARGO_TARGET_DIR=/work/target/RHEL8
    cargo build --release --locked --bin '"$TOOL"'
    install -m 0755 "$CARGO_TARGET_DIR"/release/'"$TOOL"' \
      /work/out/RHEL8/'"$TOOL"'
  '

两个 target 目录必须分开。共享 Rust license crate 必须编译进程序,并在受保护功能前调用 ucs_check_license()。

Python / PyInstaller

export ENTRY=ucs_example.py
cd "$JOB/src"
python3 -m compileall -q .
python3 -m unittest discover -s tests -p 'test_*.py'

RHEL7

docker run --rm -v "$JOB:/work" -w /work/src \
  ucs/centos7-build:latest bash -lc '
    python3 -m PyInstaller --noconfirm --clean --onefile \
      --name '"$TOOL"' --distpath /work/out/RHEL7 \
      --workpath /work/pyinstaller/RHEL7/work \
      --specpath /work/pyinstaller/RHEL7/spec '"$ENTRY"'
  '

RHEL8

docker run --rm -v "$JOB:/work" -w /work/src \
  ucs/rhel8-python-build:20260726 bash -lc '
    python3.9 -m PyInstaller --noconfirm --clean --onefile \
      --name '"$TOOL"' --distpath /work/out/RHEL8 \
      --workpath /work/pyinstaller/RHEL8/work \
      --specpath /work/pyinstaller/RHEL8/spec '"$ENTRY"'
  '
只加入真实依赖。不得因为方便把 NumPy、pandas、Qt 或完整 site-packages 一起打包。PyInstaller 是部署格式,不等同于源码加密。

Perl / PAR Packager

export ENTRY=ucs_example.pl
cd "$JOB/src"
perl -c "$ENTRY"
prove -lr t

RHEL7

docker run --rm -v "$JOB:/work" -w /work/src \
  ucs/centos7-build:latest bash -lc '
    pp -o /work/out/RHEL7/'"$TOOL"' -I /work/src/lib \
      -M JSON::PP -M Excel::Writer::XLSX '"$ENTRY"'
    chmod 0755 /work/out/RHEL7/'"$TOOL"'
  '

RHEL8

docker run --rm -v "$JOB:/work" -w /work/src \
  ucs/rhel8-build:latest bash -lc '
    pp -o /work/out/RHEL8/'"$TOOL"' -I /work/src/lib \
      -M JSON::PP -M Excel::Writer::XLSX '"$ENTRY"'
    chmod 0755 /work/out/RHEL8/'"$TOOL"'
  '

动态 require 或计算出来的模块名必须显式通过 -M 加入;共享 Perl license checker 必须包含在 PAR 文件中。

强制验证门禁

  1. 执行单元测试、代表性输入和 golden-output 回归。
  2. 用 file、readelf、objdump 检查 x86_64 和最高 GLIBC。
  3. 分别在 ucs/rhel7-runtime 和 ucs/rhel8-runtime 中执行 --help 与功能 smoke test。
  4. 验证有效、缺失、损坏三种 license 情况;release 中不得存在 license。
  5. 确认 RHEL7/RHEL8 输出在去除时间戳后功能一致。
  6. 扫描源码、私钥、SSH key、绝对开发路径和构建缓存。
objdump -T "$JOB/out/RHEL7/$TOOL" |
  sed -n 's/.*GLIBC_\([0-9.]*\).*/\1/p' | sort -Vu | tail -1

docker run --rm -v "$JOB/out/RHEL7:/release:ro" \
  ucs/rhel7-runtime:20260713 /release/"$TOOL" --help
docker run --rm -v "$JOB/out/RHEL8:/release:ro" \
  ucs/rhel8-runtime:20260713 /release/"$TOOL" --help

归档与发布

cd "$JOB/out"
sha256sum RHEL7/"$TOOL" RHEL8/"$TOOL" > SHA256SUMS
cp "$JOB/BUILD_MANIFEST.txt" .
cp /path/to/latest/usage.html usage.html

先复制到 compiled_version/<tool>.new_<timestamp>,验证部署版本后再原子替换;旧版只在新版本验证成功后清除。

下载完整 Markdown Workflow