# -*- mode: python ; coding: utf-8 -*- # LiveTalking.spec import os from PyInstaller.building.build_main import Analysis, PYZ, EXE, COLLECT block_cipher = None # 项目根目录:确保在此目录运行 pyinstaller PROJECT_ROOT = os.path.abspath('.') # Helper 函数:递归收集文件 def collect_dir(src_folder, dest_folder): """ 将 src_folder 下所有文件打包到 dist/.../dest_folder/... 中 返回 datas 条目列表 [(源文件绝对路径, 目标相对目录), ...] """ datas = [] for root, dirs, files in os.walk(src_folder): for f in files: src_file = os.path.join(root, f) # 相对于 src_folder 的子路径 rel_dir = os.path.relpath(root, src_folder) if rel_dir == '.': target_dir = dest_folder else: target_dir = os.path.join(dest_folder, rel_dir) datas.append((src_file, target_dir)) return datas # 1. 构建 datas 列表,收集资源目录 datas = [] for folder in ('models', 'data', 'web', 'ffmpeg-static'): src_path = os.path.join(PROJECT_ROOT, folder) if os.path.isdir(src_path): print(f"[DEBUG] 包含目录: {src_path}") collected = collect_dir(src_path, folder) print(f"[DEBUG] 采集到 {len(collected)} 个文件 从 {folder}") datas += collected # 2. 添加配置文件支持 config_path = os.path.join(PROJECT_ROOT, 'config', 'config.json') if os.path.isfile(config_path): print(f"[DEBUG] 包含配置文件: {config_path}") datas.append((config_path, '.')) # 打印最终 datas 长度 print(f"[DEBUG] datas 总计 {len(datas)} 条目") # hidden_imports:根据需要添加动态导入模块 hidden_imports = [] # print debug hidden_imports print(f"[DEBUG] hidden_imports: {hidden_imports}") # 分析入口脚本和依赖 analysis = Analysis( ['app.py'], pathex=[PROJECT_ROOT], binaries=[], datas=datas, hiddenimports=hidden_imports, hookspath=[], runtime_hooks=[], excludes=[], cipher=block_cipher, win_no_prefer_redirects=False, win_private_assemblies=False, ) # 打包纯 Python 模块 pyz = PYZ( analysis.pure, analysis.zipped_data, cipher=block_cipher, ) # 创建可执行文件 exe = EXE( pyz, analysis.scripts, exclude_binaries=True, name='livetalking', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=True, ) # 收集最终输出 coll = COLLECT( exe, analysis.binaries, analysis.zipfiles, analysis.datas, strip=False, upx=True, name='livetalking', )