From 796a2f592121f1dad66edfcb7bf7424857ac997c Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 24 Oct 2026 23:16:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(ffilib):=20=E4=BB=85=E5=9C=A8=20runtime=3DT?= =?UTF-8?q?rue=20=E6=97=B6=E5=BC=95=E5=85=A5=20=5Fffilib=20=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=97=B6=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runtime CDLL 的 thunk 需要 _ffilib.Load/Sym,但 includes 是按需可达性扫描:没有 import _ffilib 就不会收录、拿不到 SHA1。改为在 _RegisterFfiHandle 里按 runtime 判定——runtime=True 才 _AddPending("_ffilib"),纯链接期(runtime=False)的工程不会多编译这个运行时库。_check_import_sha1 也放行 _ffilib(它由生成代码引用,不是用户手写 import)。 --- App/lib/core/builtin/ViperBuild.vp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/App/lib/core/builtin/ViperBuild.vp b/App/lib/core/builtin/ViperBuild.vp index fd9186c..5b09fb9 100644 --- a/App/lib/core/builtin/ViperBuild.vp +++ b/App/lib/core/builtin/ViperBuild.vp @@ -463,12 +463,11 @@ def _HandleImport(stmt: ast.Import*) -> int: if al.asname is not None: _alias = _DupScratch(al.asname) else: _alias = _DupScratch("viperbuild") elif string.strcmp(al.name, "ffilib") == 0: - # 宏库:不参与 BFS,只记别名(CDLL 语句由 _HandleCDLL 抽取) + # 宏库:不参与 BFS,只记别名(CDLL 语句由 _HandleCDLL 抽取)。 + # _ffilib 的依赖只在真正出现 runtime=True 的 CDLL 时才加(见 _RegisterFfiHandle), + # 纯链接期(runtime=False)的工程不需要编译这个运行时库。 if al.asname is not None: _ffi_alias = _DupScratch(al.asname) else: _ffi_alias = _DupScratch("ffilib") - # runtime CDLL 的 thunk 要调 _ffilib(真实运行时库):显式加入闭包, - # 否则按需可达性扫描不会收录它,_resolve_module_sha1("_ffilib") 会返回 None。 - _AddPending("_ffilib") else: _AddPending(al.name) return 0 @@ -975,6 +974,9 @@ def _RegisterFfiHandle(handle: str, runtime: int, path: str) -> None: _ffi_handles_names.append(nm) _ffi_handles_rt.append(runtime) _ffi_handles_path.append(pth) + # runtime=True:thunk 运行期要调 _ffilib.Load/Sym,把该运行时库加入依赖闭包 + # (按需可达性扫描只收录被 import 的模块,否则 _resolve_module_sha1("_ffilib") 为 None)。 + if runtime != 0: _AddPending("_ffilib") # _AssignTargetName - 取 `x = ...` 的赋值目标名;非简单 Name 时返回 None