441 lines
10 KiB
Bash
441 lines
10 KiB
Bash
#!/bin/bash
|
||
|
||
# ============================================
|
||
# AGV Qt6 GUI 自动部署脚本
|
||
# ============================================
|
||
#
|
||
# 功能:
|
||
# 1. 自动编译项目(如果未编译)
|
||
# 2. 自动打包 Qt6 应用程序及其所有依赖
|
||
# 3. 创建可独立运行的 release_package 发布包
|
||
#
|
||
# 使用:./deploy_windows.sh
|
||
#
|
||
# 作者:AGV Team
|
||
# 日期:2025-11-27
|
||
# 版本:1.0
|
||
#
|
||
# ============================================
|
||
|
||
set -e # 遇到错误立即退出
|
||
|
||
# ==================== 配置区域 ====================
|
||
|
||
# Qt 安装路径(请根据实际情况修改)
|
||
QT_DIR="/c/Qt/6.10.1/mingw_64"
|
||
MINGW_DIR="/c/Qt/Tools/mingw1310_64"
|
||
|
||
# 项目路径
|
||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
BUILD_DIR="$PROJECT_ROOT/build"
|
||
DEPLOY_DIR="$PROJECT_ROOT/release_package"
|
||
|
||
# 可执行文件名
|
||
EXE_NAME="agv_qt_gui.exe"
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# ==================== 函数定义 ====================
|
||
|
||
print_header() {
|
||
echo ""
|
||
echo -e "${BLUE}========================================${NC}"
|
||
echo -e "${BLUE} AGV Qt6 GUI 自动部署脚本${NC}"
|
||
echo -e "${BLUE}========================================${NC}"
|
||
echo ""
|
||
}
|
||
|
||
print_step() {
|
||
echo -e "${GREEN}[$(date +%H:%M:%S)]${NC} $1"
|
||
}
|
||
|
||
print_warning() {
|
||
echo -e "${YELLOW}[警告]${NC} $1"
|
||
}
|
||
|
||
print_error() {
|
||
echo -e "${RED}[错误]${NC} $1"
|
||
}
|
||
|
||
check_requirements() {
|
||
print_step "检查环境要求..."
|
||
|
||
# 检查 Qt
|
||
if [ ! -d "$QT_DIR" ]; then
|
||
print_error "找不到 Qt 安装目录: $QT_DIR"
|
||
echo "请修改脚本中的 QT_DIR 变量"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 MinGW
|
||
if [ ! -d "$MINGW_DIR" ]; then
|
||
print_error "找不到 MinGW 目录: $MINGW_DIR"
|
||
echo "请修改脚本中的 MINGW_DIR 变量"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 windeployqt
|
||
if [ ! -f "$QT_DIR/bin/windeployqt.exe" ]; then
|
||
print_error "找不到 windeployqt.exe"
|
||
exit 1
|
||
fi
|
||
|
||
echo -e " ✓ Qt 目录: $QT_DIR"
|
||
echo -e " ✓ MinGW 目录: $MINGW_DIR"
|
||
}
|
||
|
||
build_project() {
|
||
# 检查可执行文件是否存在
|
||
if [ ! -f "$BUILD_DIR/$EXE_NAME" ]; then
|
||
print_warning "找不到可执行文件,将自动编译项目..."
|
||
echo ""
|
||
|
||
# 自动编译
|
||
if [ -f "$PROJECT_ROOT/build.sh" ]; then
|
||
print_step "运行 build.sh 编译项目..."
|
||
"$PROJECT_ROOT/build.sh"
|
||
echo ""
|
||
else
|
||
print_error "找不到 build.sh 脚本"
|
||
exit 1
|
||
fi
|
||
|
||
# 再次检查
|
||
if [ ! -f "$BUILD_DIR/$EXE_NAME" ]; then
|
||
print_error "编译失败,找不到 $EXE_NAME"
|
||
exit 1
|
||
fi
|
||
|
||
print_step "编译成功"
|
||
else
|
||
echo -e " ✓ 可执行文件: $EXE_NAME"
|
||
fi
|
||
}
|
||
|
||
create_deploy_dir() {
|
||
print_step "创建部署目录..."
|
||
|
||
if [ -d "$DEPLOY_DIR" ]; then
|
||
print_warning "部署目录已存在,将被删除"
|
||
rm -rf "$DEPLOY_DIR"
|
||
fi
|
||
|
||
mkdir -p "$DEPLOY_DIR"
|
||
echo -e " ✓ 创建目录: $DEPLOY_DIR"
|
||
}
|
||
|
||
copy_executable() {
|
||
print_step "复制可执行文件..."
|
||
|
||
cp "$BUILD_DIR/$EXE_NAME" "$DEPLOY_DIR/"
|
||
|
||
# 获取文件大小
|
||
SIZE=$(ls -lh "$DEPLOY_DIR/$EXE_NAME" | awk '{print $5}')
|
||
echo -e " ✓ $EXE_NAME ($SIZE)"
|
||
}
|
||
|
||
run_windeployqt() {
|
||
print_step "运行 windeployqt(自动收集 Qt 依赖)..."
|
||
|
||
cd "$DEPLOY_DIR"
|
||
|
||
# 运行 windeployqt
|
||
"$QT_DIR/bin/windeployqt.exe" \
|
||
--release \
|
||
--no-translations \
|
||
--no-system-d3d-compiler \
|
||
"$EXE_NAME" > /dev/null 2>&1
|
||
|
||
cd "$PROJECT_ROOT"
|
||
|
||
echo -e " ✓ Qt 依赖已复制"
|
||
}
|
||
|
||
copy_mingw_runtime() {
|
||
print_step "复制 MinGW 运行时库..."
|
||
|
||
RUNTIME_DLLS=(
|
||
"libgcc_s_seh-1.dll"
|
||
"libstdc++-6.dll"
|
||
"libwinpthread-1.dll"
|
||
)
|
||
|
||
for dll in "${RUNTIME_DLLS[@]}"; do
|
||
if [ -f "$MINGW_DIR/bin/$dll" ]; then
|
||
cp "$MINGW_DIR/bin/$dll" "$DEPLOY_DIR/"
|
||
echo -e " ✓ $dll"
|
||
else
|
||
print_warning "找不到 $dll"
|
||
fi
|
||
done
|
||
}
|
||
|
||
copy_project_libs() {
|
||
print_step "复制项目特定库..."
|
||
|
||
# 复制 ControlCAN 库(如果存在)
|
||
if [ -f "$PROJECT_ROOT/lib/ControlCAN.dll" ]; then
|
||
cp "$PROJECT_ROOT/lib/ControlCAN.dll" "$DEPLOY_DIR/"
|
||
echo -e " ✓ ControlCAN.dll"
|
||
else
|
||
print_warning "未找到 ControlCAN.dll(CAN 功能可能不可用)"
|
||
fi
|
||
|
||
# 复制其他必要的数据文件(如果有)
|
||
# if [ -d "$PROJECT_ROOT/data" ]; then
|
||
# cp -r "$PROJECT_ROOT/data" "$DEPLOY_DIR/"
|
||
# echo -e " ✓ data 目录"
|
||
# fi
|
||
}
|
||
|
||
create_launcher() {
|
||
print_step "创建启动脚本..."
|
||
|
||
# Windows 批处理文件
|
||
cat > "$DEPLOY_DIR/run.bat" << 'EOF'
|
||
@echo off
|
||
chcp 65001 >nul
|
||
title AGV Path Tracking Control System
|
||
|
||
echo ========================================
|
||
echo AGV 路径跟踪控制系统
|
||
echo Qt6 图形界面
|
||
echo ========================================
|
||
echo.
|
||
echo 正在启动程序...
|
||
echo.
|
||
|
||
agv_qt_gui.exe
|
||
|
||
if errorlevel 1 (
|
||
echo.
|
||
echo ========================================
|
||
echo 程序异常退出!
|
||
echo 错误代码: %errorlevel%
|
||
echo ========================================
|
||
echo.
|
||
pause
|
||
)
|
||
EOF
|
||
|
||
# Bash 启动脚本
|
||
cat > "$DEPLOY_DIR/run.sh" << 'EOF'
|
||
#!/bin/bash
|
||
echo "========================================"
|
||
echo " AGV 路径跟踪控制系统"
|
||
echo " Qt6 图形界面"
|
||
echo "========================================"
|
||
echo ""
|
||
echo "正在启动程序..."
|
||
echo ""
|
||
|
||
./agv_qt_gui.exe
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo ""
|
||
echo "========================================"
|
||
echo " 程序异常退出!"
|
||
echo " 错误代码: $?"
|
||
echo "========================================"
|
||
echo ""
|
||
read -p "按 Enter 键继续..."
|
||
fi
|
||
EOF
|
||
|
||
chmod +x "$DEPLOY_DIR/run.sh"
|
||
|
||
echo -e " ✓ run.bat (Windows 启动脚本)"
|
||
echo -e " ✓ run.sh (Bash 启动脚本)"
|
||
}
|
||
|
||
create_readme() {
|
||
print_step "创建 README 文件..."
|
||
|
||
cat > "$DEPLOY_DIR/README.txt" << EOF
|
||
========================================
|
||
AGV 路径跟踪控制系统 - 部署包
|
||
========================================
|
||
|
||
版本:1.0
|
||
构建日期:$(date +%Y-%m-%d)
|
||
Qt 版本:6.10.1
|
||
编译器:MinGW 13.1.0
|
||
|
||
========================================
|
||
运行方法
|
||
========================================
|
||
|
||
Windows:
|
||
双击运行 run.bat 或 agv_qt_gui.exe
|
||
|
||
Linux/Git Bash:
|
||
./run.sh
|
||
|
||
========================================
|
||
系统要求
|
||
========================================
|
||
|
||
- Windows 10 或更高版本
|
||
- 64 位操作系统
|
||
- 约 100MB 磁盘空间
|
||
|
||
========================================
|
||
功能说明
|
||
========================================
|
||
|
||
1. 路径规划
|
||
- 圆弧路径
|
||
- 直线路径
|
||
- S 曲线
|
||
- CSV 文件加载
|
||
- 样条插值
|
||
|
||
2. 路径跟踪
|
||
- Pure Pursuit 算法
|
||
- Stanley 算法
|
||
- 实时可视化
|
||
|
||
3. AGV 参数配置
|
||
- 轴距调整
|
||
- 最大速度设置
|
||
- 最大转向角设置
|
||
|
||
========================================
|
||
故障排除
|
||
========================================
|
||
|
||
问题:程序无法启动
|
||
解决:确保所有 DLL 文件都在同一目录下
|
||
|
||
问题:中文路径无法加载
|
||
解决:确保 CSV 文件使用 UTF-8 编码
|
||
|
||
问题:动画播放卡顿
|
||
解决:减小时间步长或增加 Horizon
|
||
|
||
========================================
|
||
技术支持
|
||
========================================
|
||
|
||
详细文档:docs/guides/
|
||
编译说明:docs/guides/BUILD_INSTRUCTIONS.md
|
||
部署说明:docs/guides/QT6_DEPLOYMENT_GUIDE.md
|
||
|
||
========================================
|
||
文件列表
|
||
========================================
|
||
|
||
agv_qt_gui.exe - 主程序
|
||
Qt6*.dll - Qt 库文件
|
||
libgcc*.dll - MinGW 运行时
|
||
platforms/ - Qt 平台插件
|
||
styles/ - Qt 样式插件
|
||
run.bat - Windows 启动脚本
|
||
run.sh - Linux 启动脚本
|
||
README.txt - 本文件
|
||
|
||
========================================
|
||
EOF
|
||
|
||
echo -e " ✓ README.txt"
|
||
}
|
||
|
||
optimize_size() {
|
||
print_step "优化部署包大小..."
|
||
|
||
cd "$DEPLOY_DIR"
|
||
|
||
# 删除不需要的插件
|
||
rm -rf tls 2>/dev/null || true
|
||
rm -rf networkinformation 2>/dev/null || true
|
||
|
||
# 删除不常用的图像格式插件
|
||
if [ -d "imageformats" ]; then
|
||
cd imageformats
|
||
rm -f qicns.dll qico.dll qtga.dll qtiff.dll qwbmp.dll qwebp.dll 2>/dev/null || true
|
||
cd ..
|
||
fi
|
||
|
||
# 删除调试文件
|
||
find . -name "*.pdb" -delete 2>/dev/null || true
|
||
|
||
cd "$PROJECT_ROOT"
|
||
|
||
echo -e " ✓ 已删除不必要的文件"
|
||
}
|
||
|
||
create_archive() {
|
||
print_step "创建压缩包..."
|
||
|
||
ARCHIVE_NAME="AGV_PathTracking_Qt6_$(date +%Y%m%d).zip"
|
||
|
||
cd "$PROJECT_ROOT"
|
||
|
||
if command -v zip &> /dev/null; then
|
||
zip -r -q "$ARCHIVE_NAME" "$(basename "$DEPLOY_DIR")"
|
||
echo -e " ✓ $ARCHIVE_NAME"
|
||
else
|
||
print_warning "未安装 zip 工具,跳过创建压缩包"
|
||
fi
|
||
}
|
||
|
||
show_summary() {
|
||
echo ""
|
||
echo -e "${GREEN}========================================${NC}"
|
||
echo -e "${GREEN} 部署完成!${NC}"
|
||
echo -e "${GREEN}========================================${NC}"
|
||
echo ""
|
||
|
||
# 计算大小
|
||
TOTAL_SIZE=$(du -sh "$DEPLOY_DIR" 2>/dev/null | cut -f1)
|
||
FILE_COUNT=$(find "$DEPLOY_DIR" -type f | wc -l)
|
||
|
||
echo "部署目录: $DEPLOY_DIR"
|
||
echo "总大小: $TOTAL_SIZE"
|
||
echo "文件数量: $FILE_COUNT"
|
||
echo ""
|
||
|
||
echo "目录结构:"
|
||
tree -L 2 "$DEPLOY_DIR" 2>/dev/null || ls -la "$DEPLOY_DIR" | head -20
|
||
|
||
echo ""
|
||
echo -e "${YELLOW}下一步操作:${NC}"
|
||
echo "1. 测试部署包:"
|
||
echo " cd $DEPLOY_DIR && ./agv_qt_gui.exe"
|
||
echo ""
|
||
echo "2. 分发到其他计算机:"
|
||
echo " 复制整个 $(basename "$DEPLOY_DIR") 文件夹"
|
||
echo ""
|
||
echo "3. 查看部署文档:"
|
||
echo " docs/guides/QT6_DEPLOYMENT_GUIDE.md"
|
||
echo ""
|
||
}
|
||
|
||
# ==================== 主流程 ====================
|
||
|
||
main() {
|
||
print_header
|
||
|
||
check_requirements
|
||
build_project
|
||
create_deploy_dir
|
||
copy_executable
|
||
run_windeployqt
|
||
copy_mingw_runtime
|
||
copy_project_libs
|
||
create_launcher
|
||
create_readme
|
||
optimize_size
|
||
# create_archive # 可选:取消注释以创建 ZIP
|
||
|
||
show_summary
|
||
}
|
||
|
||
# 运行主函数
|
||
main
|