fix(desktop): TdxQuant Key 探测打包版失效 — 哨兵重执行 + tdxaidata 入包

- probe: worker 移入主模块, frozen 以「重执行自身 + TDX_PROBE_WORKER 哨兵」
  拉起子进程 (sys.executable -c 被 PyInstaller bootloader 无视, 子进程会
  重启整个桌面应用 → Key 永远验证失败); dev 保持 python -c, 共用 run_worker
- spec: tdxaidata 显式入包 — 后端全部懒导入 Analysis 不跟随; lib/ 跨平台
  原生库按 datas 整目录复制 (collect_all 会让 macholib 解析 Linux ELF 崩)
- desktop: 单实例 _pid_alive Windows 改 OpenProcess+GetExitCodeProcess
  (os.kill(pid,0) 在 Windows 是 TerminateProcess, 会误杀在跑实例);
  main() 哨兵分发探测 worker, 先于单实例/后端/窗口
- 测试: 新增 test_tdxquant_probe.py (8 例); 全量 2692 passed;
  打包产物端到端实测探测 API ok, tdxaidata 真实加载连服
This commit is contained in:
shy3130
2026-10-13 18:37:29 +08:00
parent 25fd5a0fad
commit 506d66f1ef
4 changed files with 272 additions and 67 deletions
+12
View File
@@ -49,6 +49,18 @@ for pkg in ("polars", "pyarrow", "duckdb", "fastexcel"):
binaries += b
hiddenimports += h
# tdxaidata (TdxQuant 插件依赖) — 后端对其全部懒导入, 必须显式声明:
# 纯 Python 接口 (包 __init__ + tdxaidata.py) 进 PYZ; lib/ 是跨平台原生库
# 合集 (win dll / mac dylib / linux so 同包), 运行时由 client.materialize_lib
# 复制物化后 ctypes 加载, 属数据文件 — 只能整目录按 datas 复制。
# 注意不能用 collect_all / collect_submodules: lib/ 下的 libTdxAiData.so
# 会被当成 Python 扩展子模块收进 binaries, mac 构建的 macholib 解析
# Linux ELF 直接崩。
if (spec_tdx := find_spec("tdxaidata")) is not None and spec_tdx.origin:
_tdx_pkg = Path(spec_tdx.origin).parent
datas += [(str(_tdx_pkg / "lib"), "tdxaidata/lib")]
hiddenimports += ["tdxaidata", "tdxaidata.tdxaidata"]
# Polars 的发行包名为 polars-runtime-32 / polars-runtime-compat, 但实际
# Python 导入包带前导下划线。release.yml 安装 legacy-cpu 后必须收集二者,
# 否则 onedir 产物无法在没有 AVX2/FMA 的旧 CPU 上加载兼容内核。