#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ENV_DIR="$ROOT_DIR/tools/linux-build-env" BUILD_DIR="$ROOT_DIR/build-linux" DIST_DIR="$ROOT_DIR/dist-linux" PACKAGE_ROOT="$DIST_DIR/chengnan-linux-x86_64" APP_BIN="$PACKAGE_ROOT/bin/chengnan" LIB_DIR="$PACKAGE_ROOT/lib" PLUGIN_DIR="$PACKAGE_ROOT/plugins" QT_CONF="$PACKAGE_ROOT/bin/qt.conf" ARCHIVE="$DIST_DIR/chengnan-linux-x86_64.tar.gz" "$ROOT_DIR/scripts/build-linux-binary.sh" rm -rf "$PACKAGE_ROOT" "$ARCHIVE" mkdir -p "$PACKAGE_ROOT/bin" "$LIB_DIR" "$PLUGIN_DIR" "$ENV_DIR/bin/cmake" --install "$BUILD_DIR" --prefix "$PACKAGE_ROOT" if [[ ! -x "$APP_BIN" ]]; then echo "[package] 未找到可执行文件:$APP_BIN" >&2 exit 1 fi copy_lib() { local lib="$1" if [[ -f "$lib" ]]; then cp -L -n "$lib" "$LIB_DIR/" fi } # 只打包项目内二进制环境中的依赖,避免把系统 /lib、/usr/lib 复制进制品。 while IFS= read -r lib; do case "$lib" in "$ENV_DIR"/*) copy_lib "$lib" ;; esac done < <(LD_LIBRARY_PATH="$ENV_DIR/lib:${LD_LIBRARY_PATH:-}" ldd "$APP_BIN" | awk '/=>/ {print $3}' | sort -u) # Qt GUI 程序运行需要平台插件;同时带上常用图片格式插件,保证 jpg/png 等格式可打开。 for subdir in platforms imageformats xcbglintegrations platformthemes styles iconengines; do if [[ -d "$ENV_DIR/plugins/$subdir" ]]; then mkdir -p "$PLUGIN_DIR/$subdir" cp -L "$ENV_DIR/plugins/$subdir"/*.so "$PLUGIN_DIR/$subdir/" 2>/dev/null || true fi done # 平台插件自身还有二级依赖,继续收集项目内环境中的 .so。 if [[ -d "$PLUGIN_DIR" ]]; then while IFS= read -r plugin; do while IFS= read -r lib; do case "$lib" in "$ENV_DIR"/*) copy_lib "$lib" ;; esac done < <(LD_LIBRARY_PATH="$ENV_DIR/lib:$LIB_DIR:${LD_LIBRARY_PATH:-}" ldd "$plugin" | awk '/=>/ {print $3}' | sort -u || true) done < <(find "$PLUGIN_DIR" -type f -name '*.so' | sort) fi cat > "$QT_CONF" <<'QTCFG' [Paths] Plugins = ../plugins QTCFG cat > "$PACKAGE_ROOT/run-chengnan.sh" <<'RUNNER' #!/usr/bin/env bash set -euo pipefail APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" export LD_LIBRARY_PATH="$APP_DIR/lib:${LD_LIBRARY_PATH:-}" export QT_PLUGIN_PATH="$APP_DIR/plugins" exec "$APP_DIR/bin/chengnan" "$@" RUNNER chmod +x "$PACKAGE_ROOT/run-chengnan.sh" if command -v patchelf >/dev/null 2>&1; then patchelf --set-rpath '$ORIGIN/../lib' "$APP_BIN" || true elif [[ -x "$ENV_DIR/bin/patchelf" ]]; then "$ENV_DIR/bin/patchelf" --set-rpath '$ORIGIN/../lib' "$APP_BIN" || true else echo "[package] 未找到 patchelf,制品可通过 run-chengnan.sh 设置 LD_LIBRARY_PATH 运行。" fi find "$PACKAGE_ROOT" -type f -name '*.so*' -exec chmod 0644 {} + chmod +x "$APP_BIN" tar -C "$DIST_DIR" -czf "$ARCHIVE" "$(basename "$PACKAGE_ROOT")" if [[ ! -s "$ARCHIVE" ]]; then echo "[package] 打包失败:$ARCHIVE 为空或不存在" >&2 exit 1 fi sha256sum "$ARCHIVE" > "$ARCHIVE.sha256" echo "[package] 发布包:$ARCHIVE" echo "[package] 校验文件:$ARCHIVE.sha256"