203 lines
5.7 KiB
Python
203 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
MetaCore 应用程序打包脚本
|
||
|
||
这个脚本用于自动化打包 MetaCore 应用程序为可执行文件。
|
||
它会:
|
||
1. 清理之前的构建文件
|
||
2. 创建必要的资源目录
|
||
3. 使用优化的配置进行打包
|
||
4. 验证打包结果
|
||
|
||
使用方法:
|
||
python build_app.py
|
||
|
||
作者: MetaCore Team
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import shutil
|
||
import subprocess
|
||
from pathlib import Path
|
||
|
||
def clean_build_dirs():
|
||
"""清理构建目录"""
|
||
print("🧹 清理构建目录...")
|
||
|
||
dirs_to_clean = ['build', 'dist', '__pycache__']
|
||
for dir_name in dirs_to_clean:
|
||
dir_path = Path(dir_name)
|
||
if dir_path.exists():
|
||
print(f" 删除: {dir_path}")
|
||
shutil.rmtree(dir_path)
|
||
|
||
# 清理 .pyc 文件
|
||
for pyc_file in Path('.').rglob('*.pyc'):
|
||
pyc_file.unlink()
|
||
|
||
print("✅ 清理完成")
|
||
|
||
def ensure_resources():
|
||
"""确保必要的资源目录存在"""
|
||
print("📁 检查资源目录...")
|
||
|
||
resource_dirs = [
|
||
Path('MetaCore/Resources/Icons'),
|
||
Path('MetaCore/Resources/ProjectPreviews'),
|
||
Path('data')
|
||
]
|
||
|
||
for dir_path in resource_dirs:
|
||
if not dir_path.exists():
|
||
print(f" 创建目录: {dir_path}")
|
||
dir_path.mkdir(parents=True, exist_ok=True)
|
||
else:
|
||
print(f" ✓ 存在: {dir_path}")
|
||
|
||
print("✅ 资源目录检查完成")
|
||
|
||
def check_dependencies():
|
||
"""检查依赖"""
|
||
print("🔍 检查依赖...")
|
||
|
||
required_packages = ['PyQt5', 'pyinstaller']
|
||
missing = []
|
||
|
||
for package in required_packages:
|
||
try:
|
||
# 使用pip show来检查包是否安装
|
||
result = subprocess.run([sys.executable, '-m', 'pip', 'show', package],
|
||
capture_output=True, text=True)
|
||
if result.returncode == 0:
|
||
print(f" ✓ {package}")
|
||
else:
|
||
missing.append(package)
|
||
print(f" ✗ {package} - 缺失")
|
||
except Exception as e:
|
||
print(f" ⚠️ {package} - 检查失败: {e}")
|
||
# 如果pip检查失败,尝试直接导入
|
||
try:
|
||
if package == 'PyQt5':
|
||
import PyQt5.QtCore
|
||
elif package == 'pyinstaller':
|
||
import PyInstaller
|
||
print(f" ✓ {package} (通过导入验证)")
|
||
except ImportError:
|
||
missing.append(package)
|
||
print(f" ✗ {package} - 确实缺失")
|
||
|
||
if missing:
|
||
print(f"❌ 缺少依赖: {', '.join(missing)}")
|
||
print("请运行: pip install " + ' '.join(missing))
|
||
return False
|
||
|
||
print("✅ 依赖检查完成")
|
||
return True
|
||
|
||
def build_app():
|
||
"""构建应用程序"""
|
||
print("🔨 开始构建应用程序...")
|
||
|
||
# 使用自定义的spec文件
|
||
spec_file = 'MetaCore.spec'
|
||
if not Path(spec_file).exists():
|
||
print(f"❌ 找不到 {spec_file} 文件")
|
||
return False
|
||
|
||
try:
|
||
# 运行PyInstaller
|
||
cmd = [sys.executable, '-m', 'PyInstaller', spec_file, '--clean']
|
||
print(f"执行命令: {' '.join(cmd)}")
|
||
|
||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||
|
||
if result.returncode == 0:
|
||
print("✅ 构建成功!")
|
||
return True
|
||
else:
|
||
print("❌ 构建失败:")
|
||
print(result.stderr)
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"❌ 构建过程中发生错误: {e}")
|
||
return False
|
||
|
||
def verify_build():
|
||
"""验证构建结果"""
|
||
print("🔍 验证构建结果...")
|
||
|
||
exe_path = Path('dist/MetaCore.exe')
|
||
if exe_path.exists():
|
||
size_mb = exe_path.stat().st_size / (1024 * 1024)
|
||
print(f"✅ 找到可执行文件: {exe_path}")
|
||
print(f"📊 文件大小: {size_mb:.1f} MB")
|
||
|
||
# 检查资源文件是否被正确包含
|
||
# 这里可以添加更多的验证逻辑
|
||
|
||
return True
|
||
else:
|
||
print("❌ 未找到可执行文件")
|
||
return False
|
||
|
||
def show_results():
|
||
"""显示构建结果"""
|
||
print("\n" + "="*50)
|
||
print("🎉 构建完成!")
|
||
print("="*50)
|
||
|
||
dist_path = Path('dist')
|
||
if dist_path.exists():
|
||
print(f"📦 输出目录: {dist_path.absolute()}")
|
||
|
||
for file in dist_path.glob('*'):
|
||
if file.is_file():
|
||
size_mb = file.stat().st_size / (1024 * 1024)
|
||
print(f" 📄 {file.name} ({size_mb:.1f} MB)")
|
||
|
||
print("\n💡 使用提示:")
|
||
print("1. 双击 MetaCore.exe 运行应用程序")
|
||
print("2. 可以将 exe 文件分发给其他用户")
|
||
print("3. 首次运行可能会慢一些(解压时间)")
|
||
|
||
def main():
|
||
"""主函数"""
|
||
print("🚀 MetaCore 应用程序打包工具")
|
||
print("="*50)
|
||
|
||
# 检查是否在项目根目录
|
||
if not Path('MetaCore/main.py').exists():
|
||
print("❌ 请在项目根目录运行此脚本")
|
||
return 1
|
||
|
||
# 执行构建步骤
|
||
try:
|
||
clean_build_dirs()
|
||
ensure_resources()
|
||
|
||
# 跳过依赖检查,直接尝试构建
|
||
# if not check_dependencies():
|
||
# return 1
|
||
print("⚠️ 跳过依赖检查,直接尝试构建...")
|
||
|
||
if not build_app():
|
||
return 1
|
||
|
||
if not verify_build():
|
||
return 1
|
||
|
||
show_results()
|
||
return 0
|
||
|
||
except KeyboardInterrupt:
|
||
print("\n⚠️ 用户中断构建")
|
||
return 1
|
||
except Exception as e:
|
||
print(f"\n❌ 构建过程中发生未预期的错误: {e}")
|
||
return 1
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main()) |