#!/bin/bash # ============================================ # AGV Qt6 GUI 自动部署脚本 # ============================================ # # 功能:自动打包 Qt6 应用程序及其所有依赖 # 作者: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 "检查环境要求..." # 检查可执行文件 if [ ! -f "$BUILD_DIR/$EXE_NAME" ]; then print_error "找不到可执行文件: $BUILD_DIR/$EXE_NAME" echo "请先编译项目!" echo "" echo "编译命令:" echo " cd build" echo " cmake -G \"MinGW Makefiles\" -DCMAKE_PREFIX_PATH=$QT_DIR .." echo " cmake --build . -j4" exit 1 fi # 检查 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 " ✓ 可执行文件: $EXE_NAME" echo -e " ✓ Qt 目录: $QT_DIR" echo -e " ✓ MinGW 目录: $MINGW_DIR" } 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 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