#!/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()