BodyBalanceEvaluation/backend/build_exe.py
2025-08-13 14:17:50 +08:00

233 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
身体平衡评估系统后端打包脚本
基于最小测试框架的成功经验,简化打包配置
"""
import os
import sys
import shutil
import subprocess
from pathlib import Path
def check_dependencies():
"""检查必需的依赖"""
print("检查依赖模块...")
required_modules = [
'flask',
'flask_socketio',
'flask_cors',
'socketio',
'engineio',
'numpy',
'cv2',
'psutil'
]
missing_modules = []
for module in required_modules:
try:
__import__(module)
print(f"{module}")
except ImportError:
print(f"{module} (缺失)")
missing_modules.append(module)
if missing_modules:
print(f"\n缺失模块: {', '.join(missing_modules)}")
print("请运行: pip install -r requirements_build.txt")
return False
print("✓ 所有依赖模块检查通过")
return True
def create_spec_file():
"""创建PyInstaller spec文件"""
spec_content = '''
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main_exe.py'],
pathex=[],
binaries=[
# 只包含确实存在的DLL文件
],
datas=[
('config.ini', '.'), # 配置文件
('data', 'data'), # 数据文件夹
('tests', 'tests'), # 测试文件夹
('app_minimal.py', '.'), # 应用入口文件
],
hiddenimports=[
'flask',
'flask_socketio',
'flask_cors',
'socketio',
'engineio',
'engineio.async_drivers.threading',
'socketio.namespace',
'cv2',
'numpy',
'psutil',
'sqlite3',
'configparser',
'logging',
'threading',
'queue',
'base64',
'requests',
'click',
'colorama',
'database',
'device_manager',
'utils',
'dns',
'dns.resolver',
'dns.asyncresolver'
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[
'eventlet',
'gevent',
'gevent_uwsgi'
],
noarchive=False,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='BodyBalanceBackend',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=None
)
'''
with open('backend.spec', 'w', encoding='utf-8') as f:
f.write(spec_content)
print("✓ 已创建 backend.spec 文件")
def build_exe():
"""构建exe文件"""
print("开始构建exe文件...")
# 检查依赖模块
print("\n检查依赖模块...")
if not check_dependencies():
print("\n❌ 依赖检查失败,请先安装缺失的模块")
return False
# 检查PyInstaller是否安装
try:
import PyInstaller
print(f"\n✓ PyInstaller版本: {PyInstaller.__version__}")
except ImportError:
print("❌ PyInstaller未安装正在安装...")
subprocess.run([sys.executable, '-m', 'pip', 'install', 'pyinstaller>=6.10.0'])
# 清理之前的构建
print("\n清理构建目录...")
if os.path.exists('build'):
shutil.rmtree('build')
print("✓ 清理build目录")
if os.path.exists('dist'):
shutil.rmtree('dist')
print("✓ 清理dist目录")
# 创建spec文件
create_spec_file()
# 使用spec文件构建
print("\n开始打包...")
cmd = [sys.executable, '-m', 'PyInstaller', 'backend.spec', '--clean', '--noconfirm']
print(f"执行命令: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8')
if result.returncode == 0:
print("\n✓ 构建成功!")
print("exe文件位置: dist/BodyBalanceBackend.exe")
# 复制额外的文件
dist_path = Path('dist')
if dist_path.exists():
# 复制配置文件(如果存在)
config_files = ['config.ini', 'config.json']
for config_file in config_files:
if os.path.exists(config_file):
shutil.copy2(config_file, dist_path)
print(f"✓ 复制配置文件: {config_file}")
# 创建启动脚本
start_script = dist_path / 'start_backend.bat'
with open(start_script, 'w', encoding='utf-8') as f:
f.write('@echo off\n')
f.write('chcp 65001 >nul\n')
f.write('echo Starting Body Balance Backend...\n')
f.write('BodyBalanceBackend.exe\n')
f.write('pause\n')
print("✓ 创建启动脚本: start_backend.bat")
print("\n🎉 打包完成!")
print("\n测试方法:")
print("1. 直接运行: dist/BodyBalanceBackend.exe")
print("2. 使用脚本: dist/start_backend.bat")
print("3. 在浏览器中访问: http://localhost:5000")
return True
else:
print("\n❌ 构建失败")
print(f"错误信息: {result.stderr}")
return False
def main():
"""主函数"""
print("================================================")
print("身体平衡评估系统 - 后端打包工具 (简化版)")
print("基于最小测试框架的成功经验")
print("================================================")
print()
try:
# 检查是否在正确的目录
if not os.path.exists('main_exe.py'):
print("❌ 错误请在backend目录下运行此脚本")
print("当前目录应包含 main_exe.py 文件")
return
# 构建exe
if build_exe():
print("\n✅ 所有操作完成!")
else:
print("\n❌ 构建过程中出现错误")
except Exception as e:
print(f"❌ 错误: {e}")
import traceback
traceback.print_exc()
input("\n按回车键退出...")
if __name__ == '__main__':
main()