#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (c) 2025 Any2MIF Project # All rights reserved. """ Any2MIF - 打包脚本 使用Nuitka将项目打包成单文件.exe可执行程序 """ import os import sys import subprocess import shutil import argparse from pathlib import Path def check_nuitka(): """检查Nuitka是否已安装,如果未安装则安装""" try: import nuitka return True except ImportError: print("Nuitka未安装,正在安装...") try: subprocess.check_call([sys.executable, "-m", "pip", "install", "nuitka"]) print("Nuitka安装成功") return True except subprocess.CalledProcessError: print("Nuitka安装失败") return False def ensure_icon_exists(): """确保图标文件存在""" icon_path = Path("resources/icon.ico") if not icon_path.exists(): print("图标文件不存在,正在创建...") try: # 尝试导入create_icon模块 try: import create_icon create_icon.create_icon() except ImportError: # 如果模块不存在,尝试运行脚本 if Path("create_icon.py").exists(): subprocess.check_call([sys.executable, "create_icon.py"]) else: print("警告:找不到create_icon.py脚本,将使用默认图标") except Exception as e: print(f"创建图标文件失败:{e}") print("将使用默认图标") else: print(f"图标文件已存在:{icon_path.absolute()}") def build_executable(output_name=None, debug=False, console=False): """使用Nuitka构建可执行文件""" # 确保当前目录是项目根目录 project_root = Path(__file__).parent.absolute() os.chdir(project_root) # 确保图标文件存在 ensure_icon_exists() # 设置输出名称 if output_name is None: output_name = "Any2MIF" # 构建Nuitka命令 cmd = [ sys.executable, "-m", "nuitka", "--standalone", # 创建独立的可执行文件 "--onefile", # 创建单文件可执行程序 #"--windows-disable-console" if not console else "", # 禁用控制台窗口(除非debug模式) "--windows-console-mode=disable", "--windows-icon-from-ico=resources/icon.ico" if os.path.exists("resources/icon.ico") else "", # 设置图标 #"--include-package=PyQt6", # 包含PyQt6包 "--enable-plugin=pyqt6", "--include-package=PIL", # 包含Pillow包 "--include-package=numpy", # 包含numpy包 "--include-data-dir=resources=resources", # 包含资源文件 f"--output-filename={output_name}.exe", # 设置输出文件名 "main.py" # 入口文件 ] # 移除空字符串 cmd = [item for item in cmd if item] # 打印命令 print("执行命令:") print(" ".join(cmd)) # 执行命令 try: subprocess.check_call(cmd) print(f"构建成功!可执行文件位于:{os.path.join(project_root, output_name + '.exe')}") return True except subprocess.CalledProcessError as e: print(f"构建失败:{e}") return False def main(): """主函数""" parser = argparse.ArgumentParser(description="Any2MIF打包脚本") parser.add_argument("--output", "-o", help="输出文件名(不包含扩展名)", default="Any2MIF") parser.add_argument("--debug", "-d", action="store_true", help="启用调试模式") parser.add_argument("--console", "-c", action="store_true", help="保留控制台窗口") args = parser.parse_args() # 检查Nuitka if not check_nuitka(): print("请手动安装Nuitka:pip install nuitka") return # 构建可执行文件 build_executable(args.output, args.debug, args.console) if __name__ == "__main__": main()