TableSynthesis/cross_platform_build.py
2025-06-30 10:36:41 +08:00

327 lines
8.9 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 -*-
"""
跨平台构建脚本
在macOS上构建Windows x86/x64版本的exe文件
使用Wine和PyInstaller实现跨平台编译
"""
import os
import sys
import subprocess
import platform
import shutil
from pathlib import Path
def check_dependencies():
"""检查必要的依赖"""
print("检查构建依赖...")
# 检查是否在macOS上
if platform.system() != 'Darwin':
print(f"当前系统: {platform.system()}")
print("此脚本专为macOS设计用于构建Windows版本")
return False
# 检查Python包
required_packages = ['pandas', 'openpyxl', 'pyinstaller']
missing_packages = []
for package in required_packages:
try:
__import__(package)
print(f"{package} 已安装")
except ImportError:
missing_packages.append(package)
print(f"{package} 未安装")
if missing_packages:
print(f"\n安装缺失的包...")
for package in missing_packages:
try:
subprocess.check_call([sys.executable, '-m', 'pip', 'install', package])
print(f"{package} 安装成功")
except subprocess.CalledProcessError:
print(f"{package} 安装失败")
return False
return True
def install_wine():
"""安装Wine如果需要"""
print("\n检查Wine环境...")
# 检查是否已安装Wine
try:
result = subprocess.run(['wine', '--version'], capture_output=True, text=True)
if result.returncode == 0:
print(f"✅ Wine已安装: {result.stdout.strip()}")
return True
except FileNotFoundError:
pass
print("Wine未安装开始安装...")
print("请按照以下步骤手动安装Wine:")
print("1. 安装Homebrew (如果未安装): /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"")
print("2. 安装Wine: brew install --cask wine-stable")
print("3. 配置Wine: winecfg")
response = input("是否已完成Wine安装? (y/N): ")
return response.lower() == 'y'
def setup_wine_python():
"""在Wine中设置Python环境"""
print("\n设置Wine Python环境...")
# 检查Wine中是否已安装Python
try:
result = subprocess.run(['wine', 'python', '--version'], capture_output=True, text=True)
if result.returncode == 0:
print(f"✅ Wine Python已安装: {result.stdout.strip()}")
return True
except:
pass
print("需要在Wine中安装Python...")
print("请按照以下步骤:")
print("1. 下载Windows版Python: https://www.python.org/downloads/windows/")
print("2. 使用Wine安装: wine python-3.10.x-amd64.exe")
print("3. 安装pip包: wine python -m pip install pandas openpyxl pyinstaller")
response = input("是否已完成Wine Python安装? (y/N): ")
return response.lower() == 'y'
def create_build_spec(target_arch='x64'):
"""创建构建规格文件"""
exe_name = f"座位分配系统_{target_arch}"
spec_content = f'''# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['seat_allocation_system.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[
'pandas',
'openpyxl',
'numpy',
'xlsxwriter',
'xlrd',
'datetime',
'pathlib'
],
hookspath=[],
hooksconfig={{}},
runtime_hooks=[],
excludes=[
'matplotlib',
'scipy',
'IPython',
'jupyter',
'notebook',
'tkinter'
],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='{exe_name}',
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,
)
'''
spec_file = f'{exe_name}.spec'
with open(spec_file, 'w', encoding='utf-8') as f:
f.write(spec_content)
return spec_file, exe_name
def build_with_docker():
"""使用Docker构建Windows版本"""
print("\n使用Docker构建Windows版本...")
# 创建Dockerfile
dockerfile_content = '''FROM python:3.10-windowsservercore
# 设置工作目录
WORKDIR /app
# 复制文件
COPY requirements.txt .
COPY seat_allocation_system.py .
# 安装依赖
RUN pip install -r requirements.txt
# 构建exe
RUN pyinstaller --onefile --console --name "座位分配系统_x64" seat_allocation_system.py
# 输出目录
VOLUME ["/app/dist"]
'''
with open('Dockerfile.windows', 'w') as f:
f.write(dockerfile_content)
print("Docker方法需要Docker Desktop和Windows容器支持")
print("这是一个高级选项,建议使用其他方法")
return False
def build_native_macos():
"""在macOS上直接构建生成macOS版本"""
print("\n在macOS上构建本地版本...")
# 清理之前的构建
if os.path.exists('dist'):
shutil.rmtree('dist')
if os.path.exists('build'):
shutil.rmtree('build')
# 构建命令
cmd = [
sys.executable, '-m', 'PyInstaller',
'--onefile',
'--console',
'--clean',
'--name', '座位分配系统_macos',
'seat_allocation_system.py'
]
try:
print(f"执行命令: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print("✅ macOS版本构建成功!")
# 检查生成的文件
app_path = Path('dist') / '座位分配系统_macos'
if app_path.exists():
file_size = app_path.stat().st_size / (1024 * 1024) # MB
print(f"生成文件: {app_path}")
print(f"文件大小: {file_size:.1f} MB")
return True, app_path
else:
print("❌ 构建失败!")
print("错误输出:")
print(result.stderr)
return False, None
except Exception as e:
print(f"❌ 构建过程中出现错误: {e}")
return False, None
def create_cross_compile_script():
"""创建跨编译脚本"""
script_content = '''#!/bin/bash
# Windows交叉编译脚本
echo "座位分配系统 - Windows交叉编译"
echo "================================"
# 检查是否安装了mingw-w64
if ! command -v x86_64-w64-mingw32-gcc &> /dev/null; then
echo "安装mingw-w64..."
brew install mingw-w64
fi
# 设置交叉编译环境
export CC=x86_64-w64-mingw32-gcc
export CXX=x86_64-w64-mingw32-g++
# 构建Windows版本
echo "开始构建Windows x64版本..."
python -m PyInstaller \\
--onefile \\
--console \\
--clean \\
--name "座位分配系统_x64" \\
--target-arch x86_64 \\
seat_allocation_system.py
echo "构建完成!"
'''
with open('cross_compile.sh', 'w') as f:
f.write(script_content)
# 设置执行权限
os.chmod('cross_compile.sh', 0o755)
print("✅ 已创建交叉编译脚本: cross_compile.sh")
def main():
"""主函数"""
print("座位分配系统 - 跨平台构建工具")
print("=" * 50)
print("在macOS上构建Windows版本")
# 检查依赖
if not check_dependencies():
return
print("\n选择构建方法:")
print("1. 构建macOS版本推荐")
print("2. 使用Wine构建Windows版本复杂")
print("3. 创建交叉编译脚本(实验性)")
print("4. 生成Docker构建文件高级")
choice = input("\n请选择 (1-4): ").strip()
if choice == '1':
print("\n构建macOS版本...")
success, app_path = build_native_macos()
if success:
print(f"\n🎉 构建完成!")
print(f"生成文件: {app_path}")
print("\n注意: 这是macOS版本不能在Windows上运行")
print("如需Windows版本请在Windows系统上运行构建脚本")
elif choice == '2':
print("\n使用Wine构建Windows版本...")
if install_wine() and setup_wine_python():
print("Wine环境已准备就绪")
print("请手动在Wine中运行: wine python windows_build.py")
else:
print("Wine环境设置失败")
elif choice == '3':
print("\n创建交叉编译脚本...")
create_cross_compile_script()
print("请运行: ./cross_compile.sh")
elif choice == '4':
print("\n生成Docker构建文件...")
build_with_docker()
else:
print("无效选择")
if __name__ == "__main__":
main()