diff --git a/App/lib/Phase/Phase2/__init__.vp b/App/lib/Phase/Phase2/__init__.vp index aa34079..bdb084b 100644 --- a/App/lib/Phase/Phase2/__init__.vp +++ b/App/lib/Phase/Phase2/__init__.vp @@ -708,10 +708,70 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr, stdlib.free(im_mod_buf) if tr_a._deps_pending != 0: # 依赖模块 text.ll 未生成(同项目文件顺序),不写盘,下遍重试 + # 诊断增强:遍历本文件直接依赖,列出 text.ll 仍缺失的模块 + # (含 SHA1)——精确定位是哪个依赖未完成(通常是其自身依赖链 + # 上某个文件先失败,text.ll 从未落盘)。全部直接依赖已就绪仍 + # pending 时,说明缺失在传递依赖/MRO/vpi 侧,据此缩小排查范围。 fb_dp: str = VLogger.fmt_buf() if fb_dp is not None: - viperlib.snprintf(fb_dp, 1024, - "Phase A 依赖未就绪,下遍重试: %s", ent.Path) + miss_dp: bytes = stdlib.malloc(768) + if miss_dp is not None: + miss_dp[0] = '\0' + md_cnt: int = 0 + if tr_a._imported_modules is not None: + im_dp_len: t.CSizeT = string.strlen(tr_a._imported_modules) + im_dp_pos: t.CSizeT = 0 + while im_dp_pos < im_dp_len: + im_dp_start: t.CSizeT = im_dp_pos + while im_dp_pos < im_dp_len and tr_a._imported_modules[im_dp_pos] != ' ': + im_dp_pos += 1 + im_dp_mod_len: t.CSizeT = im_dp_pos - im_dp_start + if im_dp_pos < im_dp_len: + im_dp_pos += 1 + if im_dp_mod_len == 0: + continue + im_dp_buf: bytes = stdlib.malloc(im_dp_mod_len + 1) + if im_dp_buf is None: + continue + string.strncpy(im_dp_buf, tr_a._imported_modules + im_dp_start, im_dp_mod_len) + im_dp_buf[im_dp_mod_len] = '\0' + im_dp_sha1: str = StubMergerStore.LookupSha1ByModName(im_dp_buf) + im_dp_missing: int = 1 + if im_dp_sha1 is not None: + im_dp_txt: str = StubMergerCollect._sliced_path( + temp_dir, td_len_pa, im_dp_sha1, "text.ll") + if im_dp_txt is not None: + im_dp_f: fileio.File | t.CPtr = fileio.File(im_dp_txt, fileio.MODE.R) + if not im_dp_f.closed: + im_dp_f.close() + im_dp_missing = 0 + stdlib.free(im_dp_txt) + if im_dp_missing != 0: + if md_cnt > 0 and string.strlen(miss_dp) < 700: + string.strcat(miss_dp, ", ") + if string.strlen(miss_dp) < 700: + if im_dp_sha1 is not None: + viperlib.snprintf(miss_dp + string.strlen(miss_dp), + 768 - string.strlen(miss_dp), + "%s(%s)", im_dp_buf, im_dp_sha1) + else: + viperlib.snprintf(miss_dp + string.strlen(miss_dp), + 768 - string.strlen(miss_dp), + "%s(sha1?)", im_dp_buf) + md_cnt += 1 + stdlib.free(im_dp_buf) + if md_cnt > 0: + viperlib.snprintf(fb_dp, 1024, + "Phase A 依赖未就绪,下遍重试: %s | 缺失 text.ll 的直接依赖: %s", + ent.Path, miss_dp) + else: + viperlib.snprintf(fb_dp, 1024, + "Phase A 依赖未就绪,下遍重试: %s | 直接依赖 text.ll 均已生成" + "(缺失可能在传递依赖/MRO/vpi 侧)", ent.Path) + stdlib.free(miss_dp) + else: + viperlib.snprintf(fb_dp, 1024, + "Phase A 依赖未就绪,下遍重试: %s", ent.Path) # --nowarn-register 亦抑制此类 Phase A 依赖重试 WARN(刷屏收敛) if VLogger.nowarn_register() == 0: VLogger.warning(fb_dp, "PhaseA-DBG") @@ -795,7 +855,9 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr, fb_err: str = VLogger.fmt_buf() if fb_err is not None: viperlib.snprintf(fb_err, 1024, - "Phase A 无法完成翻译: %s(请检查依赖模块是否已编译/注册)", ent_err.Path) + "Phase A 无法完成翻译: %s(请检查依赖模块是否已编译/注册;" + "缺失依赖明细见上方 PhaseA-DBG 警告,若被 --nowarn-register 抑制请去掉该参数重跑)", + ent_err.Path) VLogger.error(fb_err, "PhaseA") stdlib.free(done_flags) VLogger.error("Phase A 多遍收敛失败,终止编译", "PhaseA")