244 lines
7.2 KiB
Python
244 lines
7.2 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
MetaCore 打包配置脚本
|
||
使用 PyInstaller 将 MetaCore 打包为可执行文件
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import shutil
|
||
import subprocess
|
||
from pathlib import Path
|
||
|
||
class MetaCoreBuildConfig:
|
||
"""MetaCore 打包配置类"""
|
||
|
||
def __init__(self):
|
||
self.project_root = Path(__file__).parent
|
||
self.metacore_dir = self.project_root / "MetaCore"
|
||
self.build_dir = self.project_root / "build"
|
||
self.dist_dir = self.project_root / "dist"
|
||
self.spec_file = self.project_root / "metacore.spec"
|
||
|
||
def check_dependencies(self):
|
||
"""检查打包依赖"""
|
||
print("🔍 检查打包依赖...")
|
||
|
||
# 检查 PyInstaller
|
||
try:
|
||
import PyInstaller
|
||
print(f"✅ PyInstaller 已安装: {PyInstaller.__version__}")
|
||
except ImportError:
|
||
print("❌ PyInstaller 未安装,正在安装...")
|
||
subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"], check=True)
|
||
print("✅ PyInstaller 安装完成")
|
||
|
||
# 检查项目依赖
|
||
requirements_file = self.metacore_dir / "requirements.txt"
|
||
if requirements_file.exists():
|
||
print("📦 安装项目依赖...")
|
||
subprocess.run([sys.executable, "-m", "pip", "install", "-r", str(requirements_file)], check=True)
|
||
print("✅ 项目依赖安装完成")
|
||
|
||
def clean_build(self):
|
||
"""清理构建目录"""
|
||
print("🧹 清理构建目录...")
|
||
|
||
for dir_path in [self.build_dir, self.dist_dir]:
|
||
if dir_path.exists():
|
||
shutil.rmtree(dir_path)
|
||
print(f"✅ 已清理: {dir_path}")
|
||
|
||
if self.spec_file.exists():
|
||
self.spec_file.unlink()
|
||
print(f"✅ 已清理: {self.spec_file}")
|
||
|
||
def create_spec_file(self):
|
||
"""创建 PyInstaller 规格文件"""
|
||
print("📝 创建 PyInstaller 规格文件...")
|
||
|
||
spec_content = f'''# -*- mode: python ; coding: utf-8 -*-
|
||
|
||
import os
|
||
from pathlib import Path
|
||
|
||
# 项目路径
|
||
project_root = Path(r"{self.project_root}")
|
||
metacore_dir = project_root / "MetaCore"
|
||
|
||
a = Analysis(
|
||
[str(metacore_dir / "main.py")],
|
||
pathex=[str(metacore_dir)],
|
||
binaries=[],
|
||
datas=[
|
||
# 包含数据文件
|
||
(str(metacore_dir / "data" / "*.json"), "data"),
|
||
# 包含资源文件
|
||
(str(metacore_dir / "Resources"), "Resources"),
|
||
# 包含UI文件
|
||
(str(metacore_dir / "ui"), "ui"),
|
||
],
|
||
hiddenimports=[
|
||
'PyQt5.QtCore',
|
||
'PyQt5.QtGui',
|
||
'PyQt5.QtWidgets',
|
||
'PyQt5.sip',
|
||
],
|
||
hookspath=[],
|
||
hooksconfig={{}},
|
||
runtime_hooks=[],
|
||
excludes=[],
|
||
win_no_prefer_redirects=False,
|
||
win_private_assemblies=False,
|
||
cipher=None,
|
||
noarchive=False,
|
||
)
|
||
|
||
pyz = PYZ(a.pure, a.zipped_data, cipher=None)
|
||
|
||
exe = EXE(
|
||
pyz,
|
||
a.scripts,
|
||
a.binaries,
|
||
a.zipfiles,
|
||
a.datas,
|
||
[],
|
||
name='MetaCore',
|
||
debug=False,
|
||
bootloader_ignore_signals=False,
|
||
strip=False,
|
||
upx=True,
|
||
upx_exclude=[],
|
||
runtime_tmpdir=None,
|
||
console=False, # 不显示控制台窗口
|
||
disable_windowed_traceback=False,
|
||
argv_emulation=False,
|
||
target_arch=None,
|
||
codesign_identity=None,
|
||
entitlements_file=None,
|
||
icon=None, # 可以添加图标文件路径
|
||
version_file=None,
|
||
)
|
||
'''
|
||
|
||
with open(self.spec_file, 'w', encoding='utf-8') as f:
|
||
f.write(spec_content)
|
||
|
||
print(f"✅ 规格文件已创建: {self.spec_file}")
|
||
|
||
def build_executable(self):
|
||
"""构建可执行文件"""
|
||
print("🔨 开始构建可执行文件...")
|
||
|
||
# 切换到项目根目录
|
||
original_cwd = os.getcwd()
|
||
os.chdir(self.project_root)
|
||
|
||
try:
|
||
# 运行 PyInstaller
|
||
cmd = [
|
||
sys.executable, "-m", "PyInstaller",
|
||
"--clean",
|
||
"--noconfirm",
|
||
str(self.spec_file)
|
||
]
|
||
|
||
print(f"执行命令: {' '.join(cmd)}")
|
||
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
|
||
|
||
print("✅ 构建完成!")
|
||
print(f"📁 可执行文件位置: {self.dist_dir / 'MetaCore.exe'}")
|
||
|
||
except subprocess.CalledProcessError as e:
|
||
print(f"❌ 构建失败: {e}")
|
||
print(f"错误输出: {e.stderr}")
|
||
raise
|
||
finally:
|
||
os.chdir(original_cwd)
|
||
|
||
def create_installer_script(self):
|
||
"""创建安装脚本"""
|
||
print("📦 创建安装脚本...")
|
||
|
||
installer_script = self.project_root / "create_installer.bat"
|
||
|
||
script_content = f'''@echo off
|
||
echo 正在创建 MetaCore 安装包...
|
||
|
||
REM 检查是否存在可执行文件
|
||
if not exist "dist\\MetaCore.exe" (
|
||
echo 错误: 找不到 MetaCore.exe,请先运行构建脚本
|
||
pause
|
||
exit /b 1
|
||
)
|
||
|
||
REM 创建安装包目录
|
||
if exist "MetaCore_Installer" rmdir /s /q "MetaCore_Installer"
|
||
mkdir "MetaCore_Installer"
|
||
|
||
REM 复制文件
|
||
copy "dist\\MetaCore.exe" "MetaCore_Installer\\"
|
||
copy "MetaCore\\README.md" "MetaCore_Installer\\"
|
||
|
||
REM 创建启动脚本
|
||
echo @echo off > "MetaCore_Installer\\启动MetaCore.bat"
|
||
echo cd /d "%%~dp0" >> "MetaCore_Installer\\启动MetaCore.bat"
|
||
echo start MetaCore.exe >> "MetaCore_Installer\\启动MetaCore.bat"
|
||
|
||
REM 创建卸载脚本
|
||
echo @echo off > "MetaCore_Installer\\卸载.bat"
|
||
echo echo 确定要卸载 MetaCore 吗? >> "MetaCore_Installer\\卸载.bat"
|
||
echo pause >> "MetaCore_Installer\\卸载.bat"
|
||
echo del MetaCore.exe >> "MetaCore_Installer\\卸载.bat"
|
||
echo del 启动MetaCore.bat >> "MetaCore_Installer\\卸载.bat"
|
||
echo del README.md >> "MetaCore_Installer\\卸载.bat"
|
||
echo del 卸载.bat >> "MetaCore_Installer\\卸载.bat"
|
||
|
||
echo ✅ 安装包创建完成!
|
||
echo 📁 安装包位置: MetaCore_Installer
|
||
pause
|
||
'''
|
||
|
||
with open(installer_script, 'w', encoding='gbk') as f:
|
||
f.write(script_content)
|
||
|
||
print(f"✅ 安装脚本已创建: {installer_script}")
|
||
|
||
def build_all(self):
|
||
"""执行完整的构建流程"""
|
||
print("🚀 开始 MetaCore 打包流程...")
|
||
print("=" * 50)
|
||
|
||
try:
|
||
self.check_dependencies()
|
||
self.clean_build()
|
||
self.create_spec_file()
|
||
self.build_executable()
|
||
self.create_installer_script()
|
||
|
||
print("=" * 50)
|
||
print("🎉 MetaCore 打包完成!")
|
||
print(f"📁 可执行文件: {self.dist_dir / 'MetaCore.exe'}")
|
||
print(f"📦 安装脚本: {self.project_root / 'create_installer.bat'}")
|
||
print("\n使用说明:")
|
||
print("1. 运行 dist/MetaCore.exe 直接启动应用")
|
||
print("2. 运行 create_installer.bat 创建安装包")
|
||
|
||
except Exception as e:
|
||
print(f"❌ 打包失败: {e}")
|
||
return False
|
||
|
||
return True
|
||
|
||
def main():
|
||
"""主函数"""
|
||
builder = MetaCoreBuildConfig()
|
||
success = builder.build_all()
|
||
|
||
if not success:
|
||
sys.exit(1)
|
||
|
||
if __name__ == "__main__":
|
||
main()
|