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:
@@ -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
104
build.bat
@@ -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 - 可选 OCR:RapidOCR 插件
|
||||||
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. 可选安装 OCR:pip install -r requirements-ocr.txt
|
||||||
|
echo 2. 配置文件:%%USERPROFILE%%\.cutthenthink\config.yaml
|
||||||
echo.
|
echo.
|
||||||
pause
|
pause
|
||||||
|
|||||||
80
build.sh
80
build.sh
@@ -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 "- 可选 OCR:RapidOCR 插件"
|
||||||
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. 可选安装 OCR:pip 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
|
|
||||||
|
|||||||
162
docs/BUILD.md
162
docs/BUILD.md
@@ -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. 使用虚拟环境减少依赖
|
||||||
|
|||||||
Reference in New Issue
Block a user