#!/bin/bash
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
VERSION=$(grep '^version' Cargo.toml | head -1 | cut -d'"' -f2)
if [ -z "$VERSION" ]; then
VERSION="0.3.0"
fi
ARCH=$(uname -m)
PACKAGE_NAME="xinyu-cap-app-store"
STATIC_BUILD=${STATIC_BUILD:-0}
if [ "$STATIC_BUILD" = "1" ]; then
STATIC_SUFFIX="-static"
else
STATIC_SUFFIX=""
fi
TARBALL_NAME="${PACKAGE_NAME}-v${VERSION}-${ARCH}${STATIC_SUFFIX}"
BUILD_DIR="target/tarball-build/${TARBALL_NAME}"
log_info "开始打包 ${TARBALL_NAME}.tar.gz"
log_info "版本: ${VERSION}"
log_info "架构: ${ARCH}"
if [ "$STATIC_BUILD" = "1" ]; then
log_info "类型: 静态链接版本(无 GLIBC 依赖)"
fi
rm -rf "target/tarball-build"
mkdir -p "${BUILD_DIR}"
if [ "$STATIC_BUILD" = "1" ]; then
log_info "启用静态链接构建(避免 GLIBC 依赖)..."
if ! command -v musl-gcc &> /dev/null; then
log_warn "未检测到 musl-gcc,尝试安装 musl-tools..."
apt-get update && apt-get install -y musl-tools 2>/dev/null || true
fi
rustup target add x86_64-unknown-linux-musl 2>/dev/null || true
rustup target add loongarch64-unknown-linux-musl 2>/dev/null || true
TARGET=$(uname -m)
case "$TARGET" in
x86_64) TARGET_TRIPLE="x86_64-unknown-linux-musl" ;;
loongarch64) TARGET_TRIPLE="loongarch64-unknown-linux-musl" ;;
*) TARGET_TRIPLE="" ;;
esac
if [ -n "$TARGET_TRIPLE" ] && rustup target list --installed | grep -q "$TARGET_TRIPLE"; then
log_info "使用 $TARGET_TRIPLE 目标构建静态链接版本..."
RUSTFLAGS='-C target-feature=+crt-static' cargo build --release --target "$TARGET_TRIPLE"
cp "target/$TARGET_TRIPLE/release/xinYu-cap-app-store" "target/release/xinYu-cap-app-store" 2>/dev/null || true
else
log_warn "静态链接目标不可用,使用默认构建..."
log_warn "如需静态链接,请安装 musl 工具链: rustup target add $TARGET_TRIPLE"
cargo build --release
fi
elif [ ! -f "target/release/xinYu-cap-app-store" ]; then
log_warn "构建 Release 版本..."
cargo build --release
fi
log_info "复制文件..."
cp "target/release/xinYu-cap-app-store" "${BUILD_DIR}/"
chmod 755 "${BUILD_DIR}/xinYu-cap-app-store"
log_info " - xinYu-cap-app-store (主程序)"
mkdir -p "${BUILD_DIR}/container/firejail-profiles"
cp container/firejail-profiles/*.profile "${BUILD_DIR}/container/firejail-profiles/"
log_info " - container/firejail-profiles/ (Firejail 配置)"
mkdir -p "${BUILD_DIR}/assets"
cp assets/terminal-beautify-install.sh "${BUILD_DIR}/assets/"
cp assets/terminal-beautify-uninstall.sh "${BUILD_DIR}/assets/"
if [ -f "openclaw-dashboard.sh" ]; then
cp openclaw-dashboard.sh "${BUILD_DIR}/"
chmod 755 "${BUILD_DIR}/openclaw-dashboard.sh"
log_info " - openclaw-dashboard.sh (OpenClaw Token 获取脚本)"
fi
cat > "${BUILD_DIR}/install.sh" << 'EOF'
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
if [ "$EUID" -ne 0 ]; then
log_error "请使用 sudo 运行安装脚本"
echo "示例: sudo ./install.sh"
exit 1
fi
INSTALL_DIR="/opt/xinyu-cap"
BIN_DIR="/usr/bin"
log_info "安装芯语 CAP 应用商店..."
log_info "目标目录: ${INSTALL_DIR}"
mkdir -p "${INSTALL_DIR}"
mkdir -p "${INSTALL_DIR}/container/firejail-profiles"
mkdir -p "${INSTALL_DIR}/assets"
log_info "复制文件..."
cp xinYu-cap-app-store "${INSTALL_DIR}/"
cp -r container/firejail-profiles/* "${INSTALL_DIR}/container/firejail-profiles/"
chmod 755 "${INSTALL_DIR}/xinYu-cap-app-store"
chmod 644 "${INSTALL_DIR}/container/firejail-profiles/"*.profile
if ls "${INSTALL_DIR}/assets/"*.json 1> /dev/null 2>&1; then
chmod 644 "${INSTALL_DIR}/assets/"*.json
fi
log_info "检查依赖..."
if ! command -v make &> /dev/null; then
log_warn "未检测到 make,尝试安装..."
if command -v apt-get &> /dev/null; then
apt-get update && apt-get install -y make
elif command -v yum &> /dev/null; then
yum install -y make
else
log_warn "请手动安装 make"
fi
else
log_info " make 已安装"
fi
log_info "配置 pnpm 镜像源..."
if command -v pnpm &> /dev/null; then
pnpm config set registry https://registry.npmmirror.com
log_info " pnpm 镜像已设置为 https://registry.npmmirror.com"
else
log_warn " 未检测到 pnpm,跳过镜像配置"
fi
log_info "创建启动脚本..."
cat > "${BIN_DIR}/xinyu-cap" << 'SCRIPT'
exec /opt/xinyu-cap/xinYu-cap-app-store "$@"
SCRIPT
chmod 755 "${BIN_DIR}/xinyu-cap"
log_info "创建桌面启动器..."
cat > "/usr/share/applications/xinyu-cap.desktop" << 'DESKTOP'
[Desktop Entry]
Name=芯语 CAP 应用商店
Name[en]=XinYu CAP App Store
Comment=芯语 CAP 应用管理和启动中心
Comment[en]=XinYu CAP Application Manager and Launcher
Exec=/opt/xinyu-cap/xinYu-cap-app-store
Icon=xinyu-cap
Type=Application
Categories=System;Settings;
Terminal=false
StartupNotify=true
Keywords=应用商店;启动器;管理;
DESKTOP
if [ -f "logo.png" ]; then
for size in 16 32 48 64 128 256; do
mkdir -p "/usr/share/icons/hicolor/${size}x${size}/apps"
cp logo.png "/usr/share/icons/hicolor/${size}x${size}/apps/xinyu-cap.png" 2>/dev/null || true
done
log_info "已安装图标"
fi
update-desktop-database /usr/share/applications 2>/dev/null || true
log_info "安装完成!"
echo ""
echo "使用方法:"
echo " - 命令行: xinyu-cap"
echo " - 或直接运行: /opt/xinyu-cap/xinYu-cap-app-store"
echo " - 桌面菜单: 从应用菜单启动"
echo ""
EOF
chmod 755 "${BUILD_DIR}/install.sh"
log_info " - install.sh (安装脚本)"
cat > "${BUILD_DIR}/uninstall.sh" << 'EOF'
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
if [ "$EUID" -ne 0 ]; then
log_error "请使用 sudo 运行卸载脚本"
exit 1
fi
log_info "卸载芯语 CAP 应用商店..."
pkill -f xinYu-cap-app-store 2>/dev/null || true
rm -rf /opt/xinyu-cap
rm -f /usr/bin/xinyu-cap
rm -f /usr/local/bin/xinyu-cap 2>/dev/null || true
rm -f /usr/share/applications/xinyu-cap.desktop
for size in 16 32 48 64 128 256; do
rm -f "/usr/share/icons/hicolor/${size}x${size}/apps/xinyu-cap.png"
done
update-desktop-database /usr/share/applications 2>/dev/null || true
log_info "卸载完成!"
EOF
chmod 755 "${BUILD_DIR}/uninstall.sh"
log_info " - uninstall.sh (卸载脚本)"
cat > "${BUILD_DIR}/README.txt" << EOF
芯语 CAP 应用商店 v${VERSION}
========================
快速安装
--------
1. 解压此压缩包
2. 进入解压后的目录
3. 运行安装脚本:
sudo ./install.sh
使用方法
--------
- 命令行启动: xinyu-cap
- 或直接运行: /opt/xinyu-cap/xinYu-cap-app-store
- 桌面启动: 从应用菜单选择"芯语 CAP 应用商店"
OpenClaw Token 获取
-------------------
安装后如需获取 OpenClaw Dashboard 的访问 Token:
./openclaw-dashboard.sh
卸载
----
sudo ./uninstall.sh
包含文件
--------
- xinYu-cap-app-store: 主程序
- container/firejail-profiles/: Firejail 沙箱配置文件
- install.sh: 安装脚本
- uninstall.sh: 卸载脚本
- openclaw-dashboard.sh: OpenClaw Dashboard Token 获取脚本
系统要求
--------
- Linux 操作系统 (x86_64 或 loong64)
- Firejail (用于应用沙箱隔离)
- PostgreSQL
- Node.js >= 20 (用于运行部分应用)
- pnpm (用于包管理)
- GLIBC >= 2.39 (如果提示 GLIBC 错误,见下方兼容性说明)
兼容性说明
----------
【GLIBC 版本问题】
如果运行时报错 GLIBC_2.39 not found,说明您的系统 GLIBC 版本过低。
解决方案:
1. 在目标系统上重新编译(推荐):
安装 Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
克隆代码并编译:
git clone https://gitcode.com/H076lik/Xinyu-CAP.git
cd Xinyu-CAP
cargo build --release
复制编译好的二进制文件:
cp target/release/xinYu-cap-app-store /opt/xinyu-cap/
2. 使用静态链接版本(如果提供):
静态链接版本文件名通常包含 -static,不依赖系统 GLIBC。
3. 升级系统 GLIBC(谨慎操作):
不建议,可能影响系统稳定性。
注意事项
--------
1. 首次启动可能需要配置依赖项
2. PostgreSQL 服务(如需要)
3. 应用默认安装到 ~/.local/share/xinyu-cap/apps/
项目主页
--------
https://gitcode.com/H076lik/Xinyu-CAP
EOF
log_info " - README.txt"
if [ -f "logo.png" ]; then
cp logo.png "${BUILD_DIR}/"
log_info " - logo.png"
fi
log_info "创建压缩包..."
mkdir -p "target/tarball"
cd "target/tarball-build"
tar czf "../tarball/${TARBALL_NAME}.tar.gz" "${TARBALL_NAME}"
cd ../..
log_info "生成 SHA256 校验和..."
cd "target/tarball"
sha256sum "${TARBALL_NAME}.tar.gz" > "${TARBALL_NAME}.tar.gz.sha256"
cd ../..
log_info "打包完成!"
echo ""
echo "输出文件:"
echo " target/tarball/${TARBALL_NAME}.tar.gz"
echo " target/tarball/${TARBALL_NAME}.tar.gz.sha256"
echo ""
echo "使用方法:"
echo " 1. 解压: tar xzf ${TARBALL_NAME}.tar.gz"
echo " 2. 进入目录: cd ${TARBALL_NAME}"
echo " 3. 安装: sudo ./install.sh"
echo ""
echo "分发时可以只提供 .tar.gz 文件"