Files
micro_servers/aibox/skills/test-auto-appimage.sh
T
2026-07-27 21:39:53 +08:00

270 lines
8.2 KiB
Bash
Executable File

#!/bin/bash
# appimage-packager.sh - 简单的AppImage打包工具
set -e
# 彩色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 帮助信息
show_help() {
cat << EOF
${GREEN}AppImage 打包工具${NC}
${BLUE}════════════════════════════════${NC}
${YELLOW}用法:${NC}
$0 [选项] <可执行文件> [输出名称]
${YELLOW}选项:${NC}
-h, --help 显示帮助信息
-i, --icon <文件> 指定图标文件 (PNG格式)
-d, --data <目录> 包含数据文件目录
-n, --name <名称> 应用程序名称
-v, --version <版本> 设置版本号
-t, --terminal 在终端中运行
${YELLOW}示例:${NC}
$0 ./myapp # 基本打包
$0 -i icon.png ./myapp # 带图标
$0 -d data/ ./myapp MyApp # 包含数据文件
$0 -t ./cli-tool # 命令行工具
${BLUE}════════════════════════════════${NC}
EOF
}
# 创建默认图标
create_default_icon() {
local icon_path="$1"
mkdir -p "$(dirname "$icon_path")"
# 创建一个简单的1x1像素PNG图标
echo -ne '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\nIDATx\x9cc\xf8\x0f\x00\x00\x01\x00\x01\x05\x01\x00\x00\x00\x00IEND\xaeB`\x82' > "$icon_path"
}
# 创建AppRun脚本
create_apprun() {
local app_dir="$1"
local exec_name="$2"
local terminal="$3"
cat > "$app_dir/AppRun" << 'EOF'
#!/bin/bash
HERE="$(dirname "$(readlink -f "$0")")"
export PATH="$HERE/usr/bin:$PATH"
export LD_LIBRARY_PATH="$HERE/usr/lib:$LD_LIBRARY_PATH"
export XDG_DATA_DIRS="$HERE/usr/share:$XDG_DATA_DIRS"
exec "$HERE/usr/bin/EXEC_NAME" "$@"
EOF
# 替换可执行文件名
sed -i "s/EXEC_NAME/$exec_name/g" "$app_dir/AppRun"
chmod +x "$app_dir/AppRun"
}
# 收集动态库依赖
collect_dependencies() {
local executable="$1"
local lib_dir="$2"
echo -e "${YELLOW}收集动态库依赖...${NC}"
mkdir -p "$lib_dir"
local count=0
# 使用ldd获取依赖
ldd "$executable" 2>/dev/null | grep "=> /" | awk '{print $3}' | while read -r lib; do
if [ -f "$lib" ] && [ ! -f "$lib_dir/$(basename "$lib")" ]; then
cp -f "$lib" "$lib_dir/" 2>/dev/null && {
echo " ✓ $(basename "$lib")"
count=$((count + 1))
}
fi
done
echo -e "${GREEN}✓ 已收集 $count 个库${NC}"
}
# 主程序
main() {
# 默认参数
ICON_FILE=""
DATA_DIR=""
APP_NAME=""
APP_VERSION="1.0"
TERMINAL=false
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-i|--icon)
ICON_FILE="$2"
shift 2
;;
-d|--data)
DATA_DIR="$2"
shift 2
;;
-n|--name)
APP_NAME="$2"
shift 2
;;
-v|--version)
APP_VERSION="$2"
shift 2
;;
-t|--terminal)
TERMINAL=true
shift
;;
-*)
echo -e "${RED}错误: 未知选项 $1${NC}"
show_help
exit 1
;;
*)
break
;;
esac
done
# 检查参数
if [[ $# -lt 1 ]]; then
show_help
exit 1
fi
EXECUTABLE="$1"
OUTPUT_NAME="${2:-$(basename "$EXECUTABLE" .AppImage)}"
# 检查可执行文件
if [[ ! -f "$EXECUTABLE" ]]; then
echo -e "${RED}错误: 文件不存在: $EXECUTABLE${NC}"
exit 1
fi
if [[ ! -x "$EXECUTABLE" ]]; then
echo -e "${YELLOW}添加执行权限...${NC}"
chmod +x "$EXECUTABLE"
fi
# 设置应用程序名称
if [[ -z "$APP_NAME" ]]; then
APP_NAME="$OUTPUT_NAME"
fi
echo -e "${BLUE}════════════════════════════════${NC}"
echo -e "${GREEN}AppImage 打包工具${NC}"
echo -e "${BLUE}════════════════════════════════${NC}"
echo "程序: $(basename "$EXECUTABLE")"
echo "输出: $OUTPUT_NAME.AppImage"
echo "名称: $APP_NAME"
echo "版本: $APP_VERSION"
echo ""
# 清理旧文件
rm -rf AppDir "${OUTPUT_NAME}.AppImage"
# 步骤1: 创建目录结构
echo -e "${YELLOW}[1/6] 创建目录结构...${NC}"
mkdir -p AppDir/usr/bin
mkdir -p AppDir/usr/lib
mkdir -p AppDir/usr/share/applications
mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps
# 步骤2: 复制可执行文件
echo -e "${YELLOW}[2/6] 复制可执行文件...${NC}"
EXEC_NAME=$(basename "$EXECUTABLE")
cp "$EXECUTABLE" "AppDir/usr/bin/$EXEC_NAME"
echo -e "${GREEN}✓ 已复制: $EXEC_NAME${NC}"
# 步骤3: 收集动态库
collect_dependencies "$EXECUTABLE" "AppDir/usr/lib"
# 步骤4: 处理数据文件
if [[ -n "$DATA_DIR" ]] && [[ -d "$DATA_DIR" ]]; then
echo -e "${YELLOW}[3/6] 复制数据文件...${NC}"
cp -r "$DATA_DIR"/* "AppDir/usr/share/$APP_NAME/" 2>/dev/null || true
echo -e "${GREEN}✓ 已复制数据文件${NC}"
fi
# 步骤5: 处理图标
echo -e "${YELLOW}[4/6] 设置图标...${NC}"
if [[ -n "$ICON_FILE" ]] && [[ -f "$ICON_FILE" ]]; then
cp "$ICON_FILE" "AppDir/usr/share/icons/hicolor/256x256/apps/$APP_NAME.png"
cp "$ICON_FILE" "AppDir/$APP_NAME.png"
echo -e "${GREEN}✓ 使用自定义图标${NC}"
else
create_default_icon "AppDir/usr/share/icons/hicolor/256x256/apps/$APP_NAME.png"
create_default_icon "AppDir/$APP_NAME.png"
echo -e "${YELLOW}⚠ 使用默认图标${NC}"
fi
cp "AppDir/$APP_NAME.png" "AppDir/.DirIcon"
# 步骤6: 创建桌面文件
echo -e "${YELLOW}[5/6] 创建桌面文件...${NC}"
TERMINAL_FLAG="$([ "$TERMINAL" = true ] && echo "true" || echo "false")"
cat > "AppDir/usr/share/applications/$APP_NAME.desktop" << EOF
[Desktop Entry]
Version=$APP_VERSION
Type=Application
Name=$APP_NAME
Comment=$APP_NAME application
Exec=$EXEC_NAME
Icon=$APP_NAME
Terminal=$TERMINAL_FLAG
Categories=Utility;
StartupNotify=false
EOF
ln -sf usr/share/applications/$APP_NAME.desktop "AppDir/"
# 步骤7: 创建AppRun
echo -e "${YELLOW}[6/6] 创建AppRun...${NC}"
create_apprun "AppDir" "$EXEC_NAME" "$TERMINAL"
# 步骤8: 打包AppImage
echo -e "\n${YELLOW}打包AppImage...${NC}"
if command -v appimagetool >/dev/null 2>&1; then
OUTPUT_FILE="${OUTPUT_NAME}.AppImage"
appimagetool --no-appstream AppDir "$OUTPUT_FILE" 2>&1 | grep -v "WARNING" | grep -v "gpg" || true
if [[ -f "$OUTPUT_FILE" ]]; then
chmod +x "$OUTPUT_FILE"
echo -e "\n${GREEN}════════════════════════════════${NC}"
echo -e "${GREEN}✅ 打包成功!${NC}"
echo -e "${GREEN}════════════════════════════════${NC}"
echo "📦 输出: $(realpath "$OUTPUT_FILE")"
echo "📏 大小: $(du -h "$OUTPUT_FILE" | cut -f1)"
echo ""
echo "🚀 运行: ./$OUTPUT_FILE"
# 清理
rm -rf AppDir
else
echo -e "${RED}❌ 打包失败${NC}"
exit 1
fi
else
echo -e "${RED}错误: 未找到 appimagetool${NC}"
echo ""
echo "请下载 appimagetool:"
echo " wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
echo " chmod +x appimagetool-x86_64.AppImage"
echo " sudo mv appimagetool-x86_64.AppImage /usr/local/bin/appimagetool"
exit 1
fi
}
# 运行主程序
main "$@"