build: 添加 Windows 打包方案

- 更新 PyInstaller spec 配置
- 简化 build.sh 构建脚本
- 更新 build.bat Windows 打包脚本
- 添加 docs/BUILD.md 打包说明文档

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
congsh
2026-02-12 15:59:23 +08:00
parent e853161975
commit 0ce1d71a90
4 changed files with 223 additions and 189 deletions

View File

@@ -1,20 +1,47 @@
# -*- mode: python ; coding: utf-8 -*- # -*- 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( a = Analysis(
['src/main.py'], ['src/main.py'],
pathex=[], pathex=[],
binaries=[], binaries=[],
datas=[('src', 'src')], datas=[
hiddenimports=['PyQt6.QtCore', 'PyQt6.QtGui', 'PyQt6.QtWidgets', 'sqlalchemy'], # 包含配置文件模板
('config.yaml.template', '.'),
],
hiddenimports=[
'PyQt6.QtCore',
'PyQt6.QtGui',
'PyQt6.QtWidgets',
'yaml',
],
hookspath=[], hookspath=[],
hooksconfig={}, hooksconfig={},
runtime_hooks=[], runtime_hooks=[],
excludes=[], excludes=[
# 排除测试相关
'test',
'tests',
'pytest',
],
noarchive=False, noarchive=False,
optimize=0, optimize=0,
) )
pyz = PYZ(a.pure)
# 打包配置
pyz = PYZ(a.pure, a.zipped_data, cipher=None)
exe = EXE( exe = EXE(
pyz, pyz,
@@ -22,17 +49,42 @@ exe = EXE(
a.binaries, a.binaries,
a.datas, a.datas,
[], [],
name='CutThenThink', exclude_binaries=True,
name=APP_NAME,
debug=False, debug=False,
bootloader_ignore_signals=False, bootloader_ignore_signals=False,
strip=False, strip=False,
upx=True, upx=True, # 使用 UPX 压缩
upx_exclude=[], upx_exclude=[],
runtime_tmpdir=None, runtime_tmpdir=None,
console=False, console=False, # 无控制台窗口
disable_windowed_traceback=False, disable_windowed_traceback=False,
argv_emulation=False, argv_emulation=False,
target_arch=None, target_arch=None,
codesign_identity=None, codesign_identity=None,
entitlements_file=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',
) )

104
build.bat
View File

@@ -1,99 +1,49 @@
@echo off @echo off
REM ================================ REM CutThenThink 极简版本 Windows 打包脚本
REM CutThenThink Windows Build Script - Cloud Only Version
REM ================================
REM 纯云端版本 - 无需本地 ML 库
REM 设置控制台编码为 UTF-8 echo ===================================
chcp 65001 >nul 2>&1 echo CutThenThink v2.0 极简版构建
echo ===================================
cd /d "%~dp0"
echo ========================================
echo CutThenThink 纯云端版本构建
echo ========================================
echo. echo.
echo 特点: echo 特点:
echo - OCR 使用云端 API echo - 核心依赖PyQt6, requests, Pillow
echo - AI 使用 API (OpenAI/Anthropic) echo - 可选 OCRRapidOCR 插件
echo - 无需任何本地 ML 库 echo - 无重型依赖torch, transformers, paddleocr
echo ======================================== echo ===================================
echo. echo.
REM Check Python REM [1/3] 清理旧的构建
echo [1/5] 检查 Python... echo [1/3] 清理旧的构建...
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] 清理旧的构建...
if exist build rmdir /s /q build if exist build rmdir /s /q build
if exist dist rmdir /s /q dist if exist dist rmdir /s /q dist
REM [2/3] 安装构建依赖
echo. echo.
echo [5/5] 开始构建... echo [2/3] 安装构建依赖...
python -m PyInstaller ^ pip install pyinstaller 2>NUL || echo PyInstaller 已安装
--noconfirm ^
--name "CutThenThink" ^ REM [3/3] 构建可执行文件
--windowed ^ echo.
--onefile ^ echo [3/3] 构建可执行文件...
--add-data "src:src" ^ python -m PyInstaller CutThenThink.spec --clean
--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
if errorlevel 1 ( if errorlevel 1 (
echo. echo.
echo ================================
echo 构建失败! echo 构建失败!
echo ================================
pause pause
exit /b 1 exit /b 1
) )
echo. echo.
echo ================================ echo ===================================
echo 构建成 echo 构建成!
echo ================================ echo ===================================
echo 可执行文件: dist\CutThenThink.exe
echo. echo.
echo 首次运行请配置: echo 输出位置:
echo - AI API Key (OpenAI/Anthropic) echo - dist\CutThenThink\ # 可执行文件目录
echo - 云端 OCR API echo.
echo 首次运行前请配置:
echo 1. 可选安装 OCRpip install -r requirements-ocr.txt
echo 2. 配置文件:%%USERPROFILE%%\.cutthenthink\config.yaml
echo. echo.
pause pause

View File

@@ -1,76 +1,46 @@
#!/bin/bash #!/bin/bash
# CutThenThink 纯云端版本打包脚本 # CutThenThink 极简版本打包脚本
# 无需任何本地 ML 库
set -e set -e
echo "===================================" echo "==================================="
echo "CutThenThink 纯云端版本构建" echo "CutThenThink v2.0 极简版构建"
echo "===================================" echo "==================================="
echo "" echo ""
echo "特点:" echo "特点:"
echo "- OCR 使用云端 API" echo "- 核心依赖PyQt6, requests, Pillow"
echo "- AI 使用 API (OpenAI/Anthropic)" echo "- 可选 OCRRapidOCR 插件"
echo "- 无需任何本地 ML 库" echo "- 无重型依赖torch, transformers, paddleocr"
echo "===================================" echo "==================================="
# 使用系统Python和pip # 检测 Python
PYTHON="python3" PYTHON="python3"
PIP="python3 -m pip" if ! command -v python3 &>/dev/null; then
PYTHON="python"
fi
PIP="$PYTHON -m pip"
echo "" echo ""
echo "[1/4] 安装打包工具..." echo "[1/5] 清理旧的构建..."
$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] 清理旧的构建..."
rm -rf build dist rm -rf build dist
echo "" echo ""
echo "[4/4] 开始构建..." echo "[2/5] 安装构建依赖..."
$PYTHON -m PyInstaller \ $PIP install --user pyinstaller 2>/dev/null || echo " PyInstaller 已安装"
--name "CutThenThink" \
--windowed \ echo ""
--onefile \ echo "[3/5] 构建可执行文件..."
--add-data "src:src" \ $PYTHON -m PyInstaller CutThenThink.spec --clean
--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 "" echo ""
echo "===================================" echo "==================================="
echo "构建完成!" echo "构建完成!"
echo "可执行文件: dist/CutThenThink" echo ""
echo "输出位置:"
echo " - dist/CutThenThink/ # 可执行文件"
echo ""
echo "首次运行前请配置:"
echo " 1. 可选安装 OCRpip install -r requirements-ocr.txt"
echo " 2. 配置文件:~/.cutthenthink/config.yaml"
echo "===================================" 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

View File

@@ -1,74 +1,136 @@
# CutThenThink 打包指南 # CutThenThink 打包指南
## 方式一:使用 build.sh 脚本(推荐) ## Windows 打包
在您的本地环境(有管理员权限)中运行: ### 方法一:使用批处理脚本(推荐)
```bash ```cmd
cd /path/to/CutThenThink # 双击运行
bash build.sh build.bat
``` ```
--- ### 方法二:手动命令
## 方式二:手动打包 ```cmd
# 1. 安装依赖
### 1. 安装 PyInstaller
```bash
# 使用 pipx推荐
pipx install pyinstaller
# 或使用系统包管理器
sudo apt install python3-pyinstaller
```
### 2. 安装项目依赖
```bash
pip install -r requirements.txt 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 ```bash
python3 -m PyInstaller \ # 添加执行权限
--name "CutThenThink" \ chmod +x build.sh
--windowed \
--onefile \ # 运行
--add-data "src:src" \ ./build.sh
--hidden-import=PyQt6.QtCore \
--hidden-import=PyQt6.QtGui \
--hidden-import=PyQt6.QtWidgets \
--hidden-import=sqlalchemy \
src/main.py
``` ```
### 4. 测试运行 ### 手动命令
```bash ```bash
./dist/CutThenThink # 1. 安装依赖
pip install -r requirements.txt
# 2. 安装 PyInstaller
pip install pyinstaller
# 3. 构建
python -m PyInstaller CutThenThink.spec --clean
``` ```
--- ## 打包说明
## 打包参数说明 ### PyInstaller 配置
| 参数 | 说明 | - `--onefile`: 打包成单个 EXE
|------|------| - `--windowed`: 无控制台窗口
| `--name` | 应用名称 | - `--upx`: 使用 UPX 压缩(减小体积)
| `--windowed` | 无控制台窗口 | - `--clean`: 清理旧的构建
| `--onefile` | 单文件打包 |
| `--add-data` | 添加数据文件(源代码) |
| `--hidden-import` | 隐式导入模块 |
--- ### 包含的隐式导入
## 打包后 - PyQt6.QtCore
- PyQt6.QtGui
- PyQt6.QtWidgets
- yaml
可执行文件位置:`dist/CutThenThink` ### 排除的模块
分发时建议: - test, tests, pytest
1.`dist/CutThenThink` 打包为 tar.gz
2. 创建安装脚本 ## 首次运行配置
3. 包含 README 说明
程序首次运行时会创建配置文件:
**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. 使用虚拟环境减少依赖