fix(tpv): phase2command 模式 Phase C 不再因 .obj 缺失中止——链接命令正确写入 bat - 根因:phase2command 模式下 llc 未执行(命令写入 bat),Phase C 的'可达模块 .obj 存在性检查'对所有实现模块触发 VLogger.error→sys.exit(1),进程在调用 link_objs_to_exe 之前终止,clang 链接命令永远写不进 bat - 修复:Phase C 可达收集在 _phase2_cmd_path 非空时跳过缺失报错,并把可达 includes .obj 路径照常加入 final_obj_paths(bat 手工执行后即存在),保证链接命令完整 - 附带:--run 在 phase2command 模式下跳过(exe 尚未链接,多文件+单文件两处);BuildPipeline._phase2_write_cmd 补 global _phase2_bat_init,避免每次调用重复写 header
This commit is contained in:
1 parent
146b9a9652
commit
347998664e
3 files changed
+45
-26
No files matched your search
@@ -485,29 +485,30 @@ def free_llc_task(task: LlcTask | t.CPtr):
|
||||
task.ModuleSha1 = None
|
||||
|
||||
|
||||
def _phase2_write_cmd(cmd: str) -> None:
|
||||
"""--phase2command 模式:把命令追加写入 bat(不执行)
|
||||
|
||||
首次调用写入 header(@echo off + 说明),后续命令以 \r\n 分行追加,
|
||||
与 cmd.exe 批处理格式一致。bat 路径由模块级 _phase2_cmd_path 指定。
|
||||
"""
|
||||
if _phase2_cmd_path is None or cmd is None:
|
||||
return
|
||||
f: fileio.File | t.CPtr = fileio.File(_phase2_cmd_path, fileio.MODE.A)
|
||||
if f.closed:
|
||||
VLogger.error("phase2command: bat 打开失败", "phase2cmd")
|
||||
return
|
||||
if _phase2_bat_init == 0:
|
||||
_phase2_bat_init = 1
|
||||
hdr1: str = "@echo off\r\n"
|
||||
hdr2: str = "rem TransPyV --phase2command generated commands\r\n"
|
||||
f.write(hdr1, string.strlen(hdr1))
|
||||
f.write(hdr2, string.strlen(hdr2))
|
||||
f.write(cmd, string.strlen(cmd))
|
||||
f.write("\r\n", 2)
|
||||
f.close()
|
||||
|
||||
|
||||
def _phase2_write_cmd(cmd: str) -> None:
|
||||
"""--phase2command 模式:把命令追加写入 bat(不执行)
|
||||
|
||||
首次调用写入 header(@echo off + 说明),后续命令以 \r\n 分行追加,
|
||||
与 cmd.exe 批处理格式一致。bat 路径由模块级 _phase2_cmd_path 指定。
|
||||
"""
|
||||
global _phase2_bat_init
|
||||
if _phase2_cmd_path is None or cmd is None:
|
||||
return
|
||||
f: fileio.File | t.CPtr = fileio.File(_phase2_cmd_path, fileio.MODE.A)
|
||||
if f.closed:
|
||||
VLogger.error("phase2command: bat 打开失败", "phase2cmd")
|
||||
return
|
||||
if _phase2_bat_init == 0:
|
||||
_phase2_bat_init = 1
|
||||
hdr1: str = "@echo off\r\n"
|
||||
hdr2: str = "rem TransPyV --phase2command generated commands\r\n"
|
||||
f.write(hdr1, string.strlen(hdr1))
|
||||
f.write(hdr2, string.strlen(hdr2))
|
||||
f.write(cmd, string.strlen(cmd))
|
||||
f.write("\r\n", 2)
|
||||
f.close()
|
||||
|
||||
|
||||
def _run_cmd_wait(cmd: str) -> int:
|
||||
"""CreateProcessA 同步执行命令并等待退出,返回退出码。
|
||||
|
||||
|
||||
@@ -1408,7 +1408,18 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
else:
|
||||
# .obj 缺失:纯声明模块(text.ll 无 define 行,如 stdio.vp 全 pass)
|
||||
# 无需 .obj,静默跳过;实现文件缺失才是编译产物异常(fail-fast)
|
||||
if StubMergerIR.IsDeclOnlyModule(temp_dir, td_len_pc, rsha1_pc) != 1:
|
||||
# phase2command 模式:.obj 尚未生成(由手工执行 bat 产生),
|
||||
# 缺失属预期——路径照常加入链接命令,跳过缺失报错。
|
||||
if BuildPipeline._phase2_cmd_path is not None:
|
||||
op_len_p2: t.CSizeT = string.strlen(obj_path_pc)
|
||||
if fop_pos + op_len_p2 + 2 < OBJ_PATHS_SIZE + 512:
|
||||
if fop_pos > 0:
|
||||
final_obj_paths[fop_pos] = ' '
|
||||
fop_pos += 1
|
||||
string.strcpy(final_obj_paths + fop_pos, obj_path_pc)
|
||||
fop_pos += op_len_p2
|
||||
final_obj_paths[fop_pos] = '\0'
|
||||
elif StubMergerIR.IsDeclOnlyModule(temp_dir, td_len_pc, rsha1_pc) != 1:
|
||||
fb_pc: str = VLogger.fmt_buf()
|
||||
if fb_pc is not None:
|
||||
viperlib.snprintf(fb_pc, 1024, "可达模块 .obj 缺失: %s", obj_path_pc)
|
||||
@@ -1434,7 +1445,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "输出: %s", exe_path)
|
||||
VLogger.success(fb, "PhaseC")
|
||||
if args.get_bool("run"):
|
||||
if args.get_bool("run") and BuildPipeline._phase2_cmd_path is not None:
|
||||
# phase2command 模式:exe 尚未链接(命令在 bat 中),跳过 --run
|
||||
fb_p2run: str = VLogger.fmt_buf()
|
||||
if fb_p2run is not None:
|
||||
viperlib.snprintf(fb_p2run, 1024, "phase2command 模式:跳过 --run(exe 尚未链接)")
|
||||
VLogger.info(fb_p2run, "phase2cmd")
|
||||
elif args.get_bool("run"):
|
||||
fb: str = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "执行: %s", exe_path)
|
||||
|
||||
+2
-1
@@ -633,7 +633,8 @@ Target: %s
|
||||
viperlib.snprintf(fb8, 1024, "输出: %s/%s", output_dir, linker_output)
|
||||
log.info(fb8)
|
||||
# --run 模式:执行生成的可执行文件
|
||||
if args.get_bool("run"):
|
||||
# phase2command 模式:exe 尚未链接(命令在 bat 中),跳过 --run
|
||||
if args.get_bool("run") and BuildPipeline._phase2_cmd_path is None:
|
||||
exe_path: bytes = stdlib.malloc(string.strlen(output_dir) + string.strlen(linker_output) + 2)
|
||||
if exe_path is not None:
|
||||
viperlib.snprintf(exe_path, 256, "%s/%s", output_dir, linker_output)
|
||||
|
||||
Reference in new issue
Block a user