From 0ce1d71a90d9d7214b2826b0bbc5fa380417ca03 Mon Sep 17 00:00:00 2001 From: congsh Date: Thu, 12 Feb 2026 15:59:23 +0800 Subject: [PATCH] =?UTF-8?q?build:=20=E6=B7=BB=E5=8A=A0=20Windows=20?= =?UTF-8?q?=E6=89=93=E5=8C=85=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 PyInstaller spec 配置 - 简化 build.sh 构建脚本 - 更新 build.bat Windows 打包脚本 - 添加 docs/BUILD.md 打包说明文档 Co-Authored-By: Claude Opus 4.6 --- CutThenThink.spec | 66 +++++++++++++++++-- build.bat | 104 ++++++++--------------------- build.sh | 80 +++++++---------------- docs/BUILD.md | 162 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 223 insertions(+), 189 deletions(-) diff --git a/CutThenThink.spec b/CutThenThink.spec index d74f49f..db080ac 100644 --- a/CutThenThink.spec +++ b/CutThenThink.spec @@ -1,20 +1,47 @@ # -*- mode: python ; coding: utf-8 -*- +""" +CutThenThink - Windows 打包配置 +极简截图上传工具的 PyInstaller 配置 +""" +import sys +from PyInstaller.building.build_main import Analysis, EXE, COLLECT, PYZ +from PyInstaller.building.api import PKG +# 项目信息 +APP_NAME = 'CutThenThink' +APP_VERSION = '2.0.0' + +# 分析配置 a = Analysis( ['src/main.py'], pathex=[], binaries=[], - datas=[('src', 'src')], - hiddenimports=['PyQt6.QtCore', 'PyQt6.QtGui', 'PyQt6.QtWidgets', 'sqlalchemy'], + datas=[ + # 包含配置文件模板 + ('config.yaml.template', '.'), + ], + hiddenimports=[ + 'PyQt6.QtCore', + 'PyQt6.QtGui', + 'PyQt6.QtWidgets', + 'yaml', + ], hookspath=[], hooksconfig={}, runtime_hooks=[], - excludes=[], + excludes=[ + # 排除测试相关 + 'test', + 'tests', + 'pytest', + ], noarchive=False, optimize=0, ) -pyz = PYZ(a.pure) + +# 打包配置 +pyz = PYZ(a.pure, a.zipped_data, cipher=None) exe = EXE( pyz, @@ -22,17 +49,42 @@ exe = EXE( a.binaries, a.datas, [], - name='CutThenThink', + exclude_binaries=True, + name=APP_NAME, debug=False, bootloader_ignore_signals=False, strip=False, - upx=True, + upx=True, # 使用 UPX 压缩 upx_exclude=[], runtime_tmpdir=None, - console=False, + console=False, # 无控制台窗口 disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, + icon=None, # TODO: 添加图标路径 +) + +# 收集所有文件 +coll = COLLECT( + exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + upx_exclude=[], + name=APP_NAME, +) + +# 构建 MSI 安装包(Windows) +pkg = PKG( + coll, + name=APP_NAME, + version=APP_VERSION, + description='极简截图上传工具', + author='CutThenThink', + keywords=['screenshot', 'upload', 'OCR'], + license='MIT', ) diff --git a/build.bat b/build.bat index 63c052c..fc439c8 100644 --- a/build.bat +++ b/build.bat @@ -1,99 +1,49 @@ @echo off -REM ================================ -REM CutThenThink Windows Build Script - Cloud Only Version -REM ================================ -REM 纯云端版本 - 无需本地 ML 库 +REM CutThenThink 极简版本 Windows 打包脚本 -REM 设置控制台编码为 UTF-8 -chcp 65001 >nul 2>&1 - -cd /d "%~dp0" - -echo ======================================== -echo CutThenThink 纯云端版本构建 -echo ======================================== +echo =================================== +echo CutThenThink v2.0 极简版构建 +echo =================================== echo. echo 特点: -echo - OCR 使用云端 API -echo - AI 使用 API (OpenAI/Anthropic) -echo - 无需任何本地 ML 库 -echo ======================================== +echo - 核心依赖:PyQt6, requests, Pillow +echo - 可选 OCR:RapidOCR 插件 +echo - 无重型依赖:torch, transformers, paddleocr +echo =================================== echo. -REM Check Python -echo [1/5] 检查 Python... -python --version 2>nul -if errorlevel 1 ( - echo 错误: 未找到 Python - pause - exit /b 1 -) - -echo. -echo [2/5] 检查源码大小... -set SIZE=0 -for /r %%A in (src\*) do ( - set /a SIZE+=%%~zA -) -if %SIZE% GTR 5242880 ( - echo 警告: src 目录大小超过 5MB,构建的 exe 可能会很大 - echo 当前大小: %SIZE% 字节 - echo. -) - -echo. -echo [3/5] 安装核心依赖... -python -m pip install --user pyinstaller 2>nul -python -m pip install --user "PyQt6>=6.7.0" 2>nul -python -m pip install --user "SQLAlchemy>=2.0.36" 2>nul -python -m pip install --user openai anthropic 2>nul -python -m pip install --user requests pyyaml pillow pyperclip 2>nul - -echo. -echo [4/5] 清理旧的构建... +REM [1/3] 清理旧的构建 +echo [1/3] 清理旧的构建... if exist build rmdir /s /q build if exist dist rmdir /s /q dist +REM [2/3] 安装构建依赖 echo. -echo [5/5] 开始构建... -python -m PyInstaller ^ - --noconfirm ^ - --name "CutThenThink" ^ - --windowed ^ - --onefile ^ - --add-data "src:src" ^ - --hidden-import=PyQt6.QtCore ^ - --hidden-import=PyQt6.QtGui ^ - --hidden-import=PyQt6.QtWidgets ^ - --hidden-import=sqlalchemy ^ - --hidden-import=sqlalchemy.orm ^ - --hidden-import=PIL ^ - --hidden-import=PIL.Image ^ - --hidden-import=pyperclip ^ - --hidden-import=yaml ^ - --hidden-import=requests ^ - --hidden-import=openai ^ - --hidden-import=anthropic ^ - --collect-all pyqt6 ^ - src/main.py +echo [2/3] 安装构建依赖... +pip install pyinstaller 2>NUL || echo PyInstaller 已安装 + +REM [3/3] 构建可执行文件 +echo. +echo [3/3] 构建可执行文件... +python -m PyInstaller CutThenThink.spec --clean if errorlevel 1 ( echo. - echo ================================ echo 构建失败! - echo ================================ pause exit /b 1 ) echo. -echo ================================ -echo 构建成功! -echo ================================ -echo 可执行文件: dist\CutThenThink.exe +echo =================================== +echo 构建完成! +echo =================================== echo. -echo 首次运行请配置: -echo - AI API Key (OpenAI/Anthropic) -echo - 云端 OCR API +echo 输出位置: +echo - dist\CutThenThink\ # 可执行文件目录 +echo. +echo 首次运行前请配置: +echo 1. 可选安装 OCR:pip install -r requirements-ocr.txt +echo 2. 配置文件:%%USERPROFILE%%\.cutthenthink\config.yaml echo. pause diff --git a/build.sh b/build.sh index 9315602..3fa17e4 100644 --- a/build.sh +++ b/build.sh @@ -1,76 +1,46 @@ #!/bin/bash -# CutThenThink 纯云端版本打包脚本 -# 无需任何本地 ML 库 +# CutThenThink 极简版本打包脚本 set -e echo "===================================" -echo "CutThenThink 纯云端版本构建" +echo "CutThenThink v2.0 极简版构建" echo "===================================" echo "" echo "特点:" -echo "- OCR 使用云端 API" -echo "- AI 使用 API (OpenAI/Anthropic)" -echo "- 无需任何本地 ML 库" +echo "- 核心依赖:PyQt6, requests, Pillow" +echo "- 可选 OCR:RapidOCR 插件" +echo "- 无重型依赖:torch, transformers, paddleocr" echo "===================================" -# 使用系统Python和pip +# 检测 Python PYTHON="python3" -PIP="python3 -m pip" +if ! command -v python3 &>/dev/null; then + PYTHON="python" +fi + +PIP="$PYTHON -m pip" echo "" -echo "[1/4] 安装打包工具..." -$PIP install --user pyinstaller 2>/dev/null || echo " PyInstaller可能已安装" - -echo "" -echo "[2/4] 安装核心依赖..." -$PIP install --user "PyQt6>=6.7.0" 2>/dev/null || echo " PyQt6可能已安装" -$PIP install --user "SQLAlchemy>=2.0.36" 2>/dev/null || echo " SQLAlchemy可能已安装" -$PIP install --user openai anthropic 2>/dev/null || echo " AI库可能已安装" -$PIP install --user requests pyyaml pillow pyperclip 2>/dev/null || echo " 工具库可能已安装" - -echo "" -echo "[3/4] 清理旧的构建..." +echo "[1/5] 清理旧的构建..." rm -rf build dist echo "" -echo "[4/4] 开始构建..." -$PYTHON -m PyInstaller \ - --name "CutThenThink" \ - --windowed \ - --onefile \ - --add-data "src:src" \ - --hidden-import=PyQt6.QtCore \ - --hidden-import=PyQt6.QtGui \ - --hidden-import=PyQt6.QtWidgets \ - --hidden-import=sqlalchemy \ - --hidden-import=sqlalchemy.orm \ - --hidden-import=PIL \ - --hidden-import=PIL.Image \ - --hidden-import=pyperclip \ - --hidden-import=yaml \ - --hidden-import=requests \ - --hidden-import=openai \ - --hidden-import=anthropic \ - --collect-all pyqt6 \ - src/main.py +echo "[2/5] 安装构建依赖..." +$PIP install --user pyinstaller 2>/dev/null || echo " PyInstaller 已安装" + +echo "" +echo "[3/5] 构建可执行文件..." +$PYTHON -m PyInstaller CutThenThink.spec --clean echo "" echo "===================================" echo "构建完成!" -echo "可执行文件: dist/CutThenThink" +echo "" +echo "输出位置:" +echo " - dist/CutThenThink/ # 可执行文件" +echo "" +echo "首次运行前请配置:" +echo " 1. 可选安装 OCR:pip install -r requirements-ocr.txt" +echo " 2. 配置文件:~/.cutthenthink/config.yaml" echo "===================================" -echo "" -echo "首次运行请配置:" -echo "- AI API Key (OpenAI/Anthropic)" -echo "- 云端 OCR API" -echo "" - -# 测试运行提示 -echo "" -read -p "是否测试运行?(y/n) " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "启动测试..." - ./dist/CutThenThink -fi diff --git a/docs/BUILD.md b/docs/BUILD.md index bd47f5e..0ca34a8 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -1,74 +1,136 @@ # CutThenThink 打包指南 -## 方式一:使用 build.sh 脚本(推荐) +## Windows 打包 -在您的本地环境(有管理员权限)中运行: +### 方法一:使用批处理脚本(推荐) -```bash -cd /path/to/CutThenThink -bash build.sh +```cmd +# 双击运行 +build.bat ``` ---- +### 方法二:手动命令 -## 方式二:手动打包 - -### 1. 安装 PyInstaller - -```bash -# 使用 pipx(推荐) -pipx install pyinstaller - -# 或使用系统包管理器 -sudo apt install python3-pyinstaller -``` - -### 2. 安装项目依赖 - -```bash +```cmd +# 1. 安装依赖 pip install -r requirements.txt + +# 2. 安装 PyInstaller +pip install pyinstaller + +# 3. 构建 +python -m PyInstaller CutThenThink.spec --clean ``` -### 3. 执行打包 +### 输出位置 + +``` +dist/ +└── CutThenThink/ + ├── CutThenThink.exe # 主程序 + └── _internal/ # 运行时依赖 +``` + +### 可选:安装 OCR 支持 + +```cmd +pip install -r requirements-ocr.txt +``` + +## Linux/macOS 打包 + +### 使用 Shell 脚本 ```bash -python3 -m PyInstaller \ - --name "CutThenThink" \ - --windowed \ - --onefile \ - --add-data "src:src" \ - --hidden-import=PyQt6.QtCore \ - --hidden-import=PyQt6.QtGui \ - --hidden-import=PyQt6.QtWidgets \ - --hidden-import=sqlalchemy \ - src/main.py +# 添加执行权限 +chmod +x build.sh + +# 运行 +./build.sh ``` -### 4. 测试运行 +### 手动命令 ```bash -./dist/CutThenThink +# 1. 安装依赖 +pip install -r requirements.txt + +# 2. 安装 PyInstaller +pip install pyinstaller + +# 3. 构建 +python -m PyInstaller CutThenThink.spec --clean ``` ---- +## 打包说明 -## 打包参数说明 +### PyInstaller 配置 -| 参数 | 说明 | -|------|------| -| `--name` | 应用名称 | -| `--windowed` | 无控制台窗口 | -| `--onefile` | 单文件打包 | -| `--add-data` | 添加数据文件(源代码) | -| `--hidden-import` | 隐式导入模块 | +- `--onefile`: 打包成单个 EXE +- `--windowed`: 无控制台窗口 +- `--upx`: 使用 UPX 压缩(减小体积) +- `--clean`: 清理旧的构建 ---- +### 包含的隐式导入 -## 打包后 +- PyQt6.QtCore +- PyQt6.QtGui +- PyQt6.QtWidgets +- yaml -可执行文件位置:`dist/CutThenThink` +### 排除的模块 -分发时建议: -1. 将 `dist/CutThenThink` 打包为 tar.gz -2. 创建安装脚本 -3. 包含 README 说明 +- test, tests, pytest + +## 首次运行配置 + +程序首次运行时会创建配置文件: + +**Windows**: `%USERPROFILE%\.cutthenthink\config.yaml` +**Linux/macOS**: `~/.cutthenthink/config.yaml` + +```yaml +upload: + provider: custom + endpoint: https://your-server.com/upload + api_key: your-api-key + auto_copy: true + +screenshot: + format: png + save_path: ~/Pictures/Screenshots + +hotkeys: + capture: Ctrl+Shift+A + region: Ctrl+Shift+R + upload: Ctrl+Shift+U + +ocr: + enabled: false + auto_copy: false +``` + +## 故障排除 + +### PyInstaller 构建失败 + +1. 确保 PyInstaller 已安装:`pip list | grep pyinstaller` +2. 检查 Python 版本:需要 Python 3.8+ +3. 清理缓存:删除 `build/` 和 `dist/` 目录后重试 + +### 运行时错误 + +1. 检查是否有防火墙阻止 +2. 检查 OCR 功能是否可选安装 +3. 查看日志文件(如果有) + +## 体积优化建议 + +当前打包体积预估: +- 核心依赖:~50MB +- 可选 OCR:+10MB + +如需进一步减小体积: +1. 使用 `--exclude-module` 排除不需要的模块 +2. 启用 UPX 压缩(已启用) +3. 使用虚拟环境减少依赖