# -*- mode: python ; coding: utf-8 -*- import os import dataui import confluent_kafka from PyInstaller.utils.hooks import collect_dynamic_libs, collect_submodules # ---- 定位 confluent_kafka.libs ---- kafka_libs_dir = os.path.join( os.path.dirname(confluent_kafka.__file__), '..', 'confluent_kafka.libs' ) kafka_libs_dir = os.path.normpath(kafka_libs_dir) if not os.path.exists(kafka_libs_dir): alt_dir = os.path.join( os.path.dirname(os.path.dirname(confluent_kafka.__file__)), 'confluent_kafka.libs' ) if os.path.exists(alt_dir): kafka_libs_dir = alt_dir print(f"[SPEC] Kafka libs dir: {kafka_libs_dir}, exists: {os.path.exists(kafka_libs_dir)}") # ---- 收集 numpy/pandas 动态库(若使用) ---- numpy_binaries = collect_dynamic_libs('numpy') if False else [] # 如果使用,改为 True pandas_binaries = collect_dynamic_libs('pandas') if False else [] # 我们也可以直接通过 datas 包含它们的 .libs 目录(但更推荐用 collect_dynamic_libs) # 这里我们先用 collect_dynamic_libs 并合并到 binaries all_binaries = numpy_binaries + pandas_binaries # 加入 kafka 吗?不,我们用 datas duipath = os.path.dirname(dataui.__file__) block_cipher = None a = Analysis( ['../src/kgadget.py'], pathex=['../src'], binaries=all_binaries, # 包含 numpy/pandas 的 .so datas=[ (f'{duipath}/tmpl/bricks/*.*', 'dataui/tmpl/bricks'), (kafka_libs_dir, 'confluent_kafka.libs'), # 复制整个 kafka 目录 ], hiddenimports=[ 'sqlite3', 'aiopg', 'aiomysql', 'confluent_kafka.admin', ], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], 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='kgadget', debug=False, bootloader_ignore_signals=False, strip=False, upx=False, # 务必关闭 UPX upx_exclude=[], runtime_tmpdir=None, console=True, disable_windowed_traceback=False, target_arch=None, codesign_identity=None, entitlements_file=None, onefile=False # 显式指定 onefile=False )