修正了一些错误
This commit is contained in:
@@ -17,6 +17,7 @@ import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Handles.HandlesImports as HandlesImports
|
||||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||||
import lib.core.BuildPipeline as BuildPipeline
|
||||
import lib.core.StubMerger as StubMerger
|
||||
import lib.Projectrans.Utils as Utils
|
||||
@@ -138,7 +139,10 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr,
|
||||
ent.Path = full_path
|
||||
ent.Sha1 = sha1_val
|
||||
file_count += 1
|
||||
stdio.printf("[project] %s (sha1=%s)\n", fname, sha1_val)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "%s (sha1=%s)", fname, sha1_val)
|
||||
VLogger.info(fb, "project")
|
||||
stdlib.free(sbuf)
|
||||
# full_path 不释放:ent.Path 引用它
|
||||
|
||||
@@ -165,10 +169,16 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
Returns: 0 成功,非 0 失败
|
||||
"""
|
||||
if source_dir is None:
|
||||
stdio.printf("[project] source_dir 为空\n")
|
||||
VLogger.error("source_dir 为空", "project")
|
||||
return 1
|
||||
|
||||
stdio.printf("[project] 多文件项目编译: %s\n", source_dir)
|
||||
stdio.printf("[DBG] RunMultiFileProject enter src=%s\n", source_dir)
|
||||
stdio.fflush(0)
|
||||
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "多文件项目编译: %s", source_dir)
|
||||
VLogger.info(fb, "project")
|
||||
|
||||
# === 1. 递归扫描 source_dir 下的 .py 文件(包括子目录)===
|
||||
entry_size: t.CSizeT = SrcFileEntry.__sizeof__()
|
||||
@@ -178,7 +188,12 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
string.memset(entries, 0, MAX_SRC_FILES * entry_size)
|
||||
|
||||
file_count: int = _ScanDirForPyFiles(mb, source_dir, entries, entry_size, 0, MAX_SRC_FILES)
|
||||
stdio.printf("[project] 共 %d 个源文件\n", file_count)
|
||||
stdio.printf("[DBG] scan done file_count=%d\n", file_count)
|
||||
stdio.fflush(0)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "共 %d 个源文件", file_count)
|
||||
VLogger.info(fb, "project")
|
||||
|
||||
if file_count == 0:
|
||||
stdlib.free(entries)
|
||||
@@ -191,34 +206,47 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
BuildPipeline.ensure_dir(temp_dir)
|
||||
BuildPipeline.ensure_dir(output_dir)
|
||||
|
||||
# 追加 App 源文件 SHA1 到 _sha1_map.txt(供日志转存和符号查找使用)
|
||||
# 格式: {sha1}:App/{filename}\n (与 includes 条目格式对应)
|
||||
# 追加 App 源文件 SHA1 到 _sha1_map.txt(人类可读输出,程序内部不读取此文件)
|
||||
# 格式: {sha1}:{rel_path}\n (保留目录结构,如 lib/core/VLogger.py)
|
||||
# 同步追加到内存存储器(AppendToSha1MapStore,供跨模块 CDefine 查找)
|
||||
td_len_am: t.CSizeT = string.strlen(temp_dir)
|
||||
src_dir_len_am: t.CSizeT = string.strlen(source_dir)
|
||||
map_path_am: bytes = stdlib.malloc(td_len_am + 32)
|
||||
if map_path_am is not None:
|
||||
viperlib.snprintf(map_path_am, td_len_am + 32, "%s/_sha1_map.txt", temp_dir)
|
||||
mf: fileio.File | t.CPtr = fileio.File(map_path_am, fileio.MODE.A)
|
||||
line_am: bytes = stdlib.malloc(512)
|
||||
# 先遍历一次填充内存存储器(不依赖文件 I/O),再写入 _sha1_map.txt
|
||||
app_filled: int = 0
|
||||
for i in range(file_count):
|
||||
ea_am: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
|
||||
ent_am: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_am, t.CPtr))
|
||||
if ent_am is None or ent_am.Path is None or ent_am.Sha1 is None:
|
||||
continue
|
||||
# 计算相对路径(去除 source_dir 前缀,保留目录结构)
|
||||
p_str: str = ent_am.Path
|
||||
p_len: t.CSizeT = string.strlen(p_str)
|
||||
rel_path_am: str = p_str
|
||||
if p_len > src_dir_len_am + 1:
|
||||
if string.strncmp(p_str, source_dir, src_dir_len_am) == 0:
|
||||
rel_path_am = p_str + src_dir_len_am + 1
|
||||
# 同步追加到内存存储器(供跨模块 CDefine 查找)
|
||||
# rel_path_am 格式如 "lib/core/StubMerger.py",与 _sha1_map.txt 一致
|
||||
if StubMerger.AppendToSha1MapStore(ent_am.Sha1, rel_path_am) == 0:
|
||||
app_filled += 1
|
||||
# 写入 _sha1_map.txt(人类可读输出)
|
||||
if not mf.closed and line_am is not None:
|
||||
viperlib.snprintf(line_am, 512, "%s:%s\n", ent_am.Sha1, rel_path_am)
|
||||
ll_am: t.CSizeT = string.strlen(line_am)
|
||||
mf.write(line_am, ll_am)
|
||||
if line_am is not None:
|
||||
stdlib.free(line_am)
|
||||
if not mf.closed:
|
||||
line_am: bytes = stdlib.malloc(512)
|
||||
if line_am is not None:
|
||||
for i in range(file_count):
|
||||
ea_am: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
|
||||
ent_am: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_am, t.CPtr))
|
||||
if ent_am is None or ent_am.Path is None or ent_am.Sha1 is None:
|
||||
continue
|
||||
# 从路径提取文件名(最后一个 / 或 \\ 之后的部分)
|
||||
p_str: str = ent_am.Path
|
||||
p_len: t.CSizeT = string.strlen(p_str)
|
||||
f_start: t.CSizeT = 0
|
||||
for j in range(p_len):
|
||||
if p_str[j] == '/' or p_str[j] == '\\':
|
||||
f_start = j + 1
|
||||
viperlib.snprintf(line_am, 512, "%s:App/%s\n", ent_am.Sha1, p_str + f_start)
|
||||
ll_am: t.CSizeT = string.strlen(line_am)
|
||||
mf.write(line_am, ll_am)
|
||||
stdlib.free(line_am)
|
||||
mf.close()
|
||||
stdio.printf("[project] 已追加 %d 个 App 文件到 _sha1_map.txt\n", file_count)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "已追加 %d 个 App 文件到 _sha1_map.txt 和内存存储器", app_filled)
|
||||
VLogger.info(fb, "project")
|
||||
stdlib.free(map_path_am)
|
||||
|
||||
# 构建模块 SHA1 映射(供跨模块函数调用名混淆使用)
|
||||
@@ -231,6 +259,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
# 追加用户源文件的 (模块名, SHA1) 到全局映射
|
||||
# 使跨模块方法调用能通过 from_imports + _lookup_module_sha1 找到正确的 SHA1
|
||||
if pb_sha1_arr is not None and pb_mod_arr is not None:
|
||||
src_dir_len_us: t.CSizeT = string.strlen(source_dir)
|
||||
for i in range(file_count):
|
||||
ea_us: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
|
||||
ent_us: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_us, t.CPtr))
|
||||
@@ -238,24 +267,26 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
continue
|
||||
if pb_inc_count >= StubMerger.MAX_INCLUDES:
|
||||
break
|
||||
# 从路径提取模块名(文件名去掉 .py 后缀)
|
||||
# 计算相对路径并转换为点分模块名(保留完整包路径)
|
||||
path_str: str = ent_us.Path
|
||||
path_len: t.CSizeT = string.strlen(path_str)
|
||||
fname_start: t.CSizeT = 0
|
||||
for j in range(path_len):
|
||||
if path_str[j] == '/' or path_str[j] == '\\':
|
||||
fname_start = j + 1
|
||||
mod_len: t.CSizeT = path_len - fname_start
|
||||
if mod_len < 4:
|
||||
path_len_us: t.CSizeT = string.strlen(path_str)
|
||||
rel_path_us: str = path_str
|
||||
if path_len_us > src_dir_len_us + 1:
|
||||
if string.strncmp(path_str, source_dir, src_dir_len_us) == 0:
|
||||
rel_path_us = path_str + src_dir_len_us + 1
|
||||
# 使用 _PathToModuleName 转换为点分模块名(处理 __init__.py → 包名)
|
||||
mod_name_us: str = StubMerger._PathToModuleName(rel_path_us)
|
||||
if mod_name_us is None:
|
||||
continue
|
||||
mod_len -= 3
|
||||
if mod_len >= 64:
|
||||
mod_len = 63
|
||||
# 写入模块名
|
||||
mod_idx: t.CSizeT = t.CSizeT(pb_inc_count) * 64
|
||||
for k in range(mod_len):
|
||||
pb_mod_arr[mod_idx + k] = path_str[fname_start + k]
|
||||
pb_mod_arr[mod_idx + mod_len] = '\0'
|
||||
mn_len_us: t.CSizeT = string.strlen(mod_name_us)
|
||||
if mn_len_us >= 64:
|
||||
string.strncpy(pb_mod_arr + mod_idx, mod_name_us, 63)
|
||||
pb_mod_arr[mod_idx + 63] = '\0'
|
||||
else:
|
||||
string.strcpy(pb_mod_arr + mod_idx, mod_name_us)
|
||||
stdlib.free(mod_name_us)
|
||||
# 写入 SHA1
|
||||
sha1_idx: t.CSizeT = t.CSizeT(pb_inc_count) * 17
|
||||
string.strcpy(pb_sha1_arr + sha1_idx, ent_us.Sha1)
|
||||
@@ -265,36 +296,60 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
|
||||
# === 2. Phase A: 为每个文件生成 stub + text ===
|
||||
if do_phase1 != 0:
|
||||
stdio.printf("[DBG] before Phase A\n")
|
||||
stdio.fflush(0)
|
||||
if log is not None:
|
||||
log.banner("Phase A: 生成 stub + text")
|
||||
|
||||
# === Phase A-pre: 预注册所有源文件的 struct/enum/union ===
|
||||
# 解决循环引用问题:circ_a 翻译时需要知道 circ_b.ClassB 的 struct 定义
|
||||
# 仅注册 struct/enum/union(declare_only=1),不翻译方法体
|
||||
stdio.printf("[Phase A-pre] 预注册 struct/enum/union...\n")
|
||||
# 多遍扫描:解决跨文件继承的字母序问题(如 HandlesAnnAssign.py 在 HandlesBase.py 之前,
|
||||
# AnnAssignHandle 继承 Mixin 时 Mixin 未注册)。每遍注册新类后,下一遍子类可继承。
|
||||
VLogger.info("预注册 struct/enum/union...", "PhaseA")
|
||||
src_dir_len_pre: t.CSizeT = string.strlen(source_dir)
|
||||
for i in range(file_count):
|
||||
ea_pre: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
|
||||
ent_pre: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_pre, t.CPtr))
|
||||
if ent_pre is None or ent_pre.Path is None:
|
||||
continue
|
||||
pkg_pre: str = None
|
||||
if string.strlen(ent_pre.Path) > src_dir_len_pre + 1:
|
||||
rel_path_pre: str = ent_pre.Path + src_dir_len_pre + 1
|
||||
pkg_pre = HandlesImports.compute_package_from_relpath(mb, rel_path_pre)
|
||||
tr_pre: HandlesTranslator.Translator | t.CPtr = BuildPipeline.TranslateFileGetTrans(mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1)
|
||||
if tr_pre is None:
|
||||
stdio.printf("[Phase A-pre] 警告: 预注册失败: %s\n", ent_pre.Path)
|
||||
stdio.printf("[Phase A-pre] 预注册完成\n")
|
||||
PHASE_A_PRE_MAX_PASSES: t.CInt = 3
|
||||
for pass_i in range(PHASE_A_PRE_MAX_PASSES):
|
||||
struct_count_before: int = HandlesStruct.get_struct_count()
|
||||
stdio.printf("[DBG] PhaseA-pre pass=%d struct_count_before=%d\n", pass_i, struct_count_before)
|
||||
stdio.fflush(0)
|
||||
for i in range(file_count):
|
||||
ea_pre: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
|
||||
ent_pre: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_pre, t.CPtr))
|
||||
if ent_pre is None or ent_pre.Path is None:
|
||||
continue
|
||||
pkg_pre: str = None
|
||||
if string.strlen(ent_pre.Path) > src_dir_len_pre + 1:
|
||||
rel_path_pre: str = ent_pre.Path + src_dir_len_pre + 1
|
||||
pkg_pre = HandlesImports.compute_package_from_relpath(mb, rel_path_pre)
|
||||
stdio.printf("[DBG] PhaseA-pre pass=%d file=%s\n", pass_i, ent_pre.Path)
|
||||
stdio.fflush(0)
|
||||
tr_pre: HandlesTranslator.Translator | t.CPtr = BuildPipeline.TranslateFileGetTrans(mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1)
|
||||
if tr_pre is None:
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "预注册失败: %s", ent_pre.Path)
|
||||
VLogger.warning(fb, "PhaseA")
|
||||
struct_count_after: int = HandlesStruct.get_struct_count()
|
||||
stdio.printf("[DBG] PhaseA-pre pass=%d done struct_count_after=%d\n", pass_i, struct_count_after)
|
||||
stdio.fflush(0)
|
||||
# 收敛检查:本遍没有新结构体注册 → 所有类已注册
|
||||
if struct_count_after == struct_count_before:
|
||||
break
|
||||
VLogger.info("预注册完成", "PhaseA")
|
||||
|
||||
PHASE_A_IR_SIZE: t.CSizeT = 262144
|
||||
PHASE_A_IR_SIZE: t.CSizeT = 1048576
|
||||
td_len_pa: t.CSizeT = string.strlen(temp_dir)
|
||||
|
||||
stdio.printf("[DBG] PhaseA full-translate start\n")
|
||||
stdio.fflush(0)
|
||||
for i in range(file_count):
|
||||
ea: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
|
||||
ent: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
|
||||
if ent is None or ent.Path is None:
|
||||
continue
|
||||
stdio.printf("[DBG] PhaseA file=%s\n", ent.Path)
|
||||
stdio.fflush(0)
|
||||
|
||||
# 计算源文件的包名(相对 source_dir 的目录部分)
|
||||
src_dir_len_pa: t.CSizeT = string.strlen(source_dir)
|
||||
@@ -352,12 +407,14 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
stdlib.free(deps_path_a)
|
||||
|
||||
if do_phase2 == 0:
|
||||
stdio.printf("[project] Phase A 完成(仅 stub 生成)\n")
|
||||
VLogger.info("Phase A 完成(仅 stub 生成)", "project")
|
||||
stdlib.free(entries)
|
||||
return 0
|
||||
|
||||
# === 3. Phase B: 编译每个文件为 .obj ===
|
||||
if do_phase2 != 0:
|
||||
stdio.printf("[DBG] before Phase B\n")
|
||||
stdio.fflush(0)
|
||||
if log is not None:
|
||||
log.banner("Phase B: 编译 .obj")
|
||||
|
||||
@@ -384,28 +441,51 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
ent: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
|
||||
if ent is None or ent.Path is None or ent.Sha1 is None:
|
||||
continue
|
||||
stdio.printf("[DBG] PhaseB file=%s\n", ent.Path)
|
||||
stdio.fflush(0)
|
||||
|
||||
# 组合本地 stub + 所有依赖 stub + 本地 text → 完整 IR
|
||||
stdio.printf("[DBG] PhaseB step=alloc combined_ir\n")
|
||||
stdio.fflush(0)
|
||||
combined_ir: bytes = stdlib.malloc(COMBINED_IR_SIZE)
|
||||
if combined_ir is None:
|
||||
stdio.printf("[Phase B] combined_ir 分配失败: %s\n", ent.Path)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "combined_ir 分配失败: %s", ent.Path)
|
||||
VLogger.error(fb, "PhaseB")
|
||||
continue
|
||||
stdio.printf("[DBG] PhaseB step=BuildCombinedIR sha1=%s\n", ent.Sha1)
|
||||
stdio.fflush(0)
|
||||
combined_len: t.CSizeT = StubMerger.BuildCombinedIR(temp_dir, ent.Sha1, combined_ir, COMBINED_IR_SIZE)
|
||||
stdio.printf("[DBG] PhaseB step=BuildCombinedIR done len=%d\n", combined_len)
|
||||
stdio.fflush(0)
|
||||
if combined_len == 0:
|
||||
stdio.printf("[Phase B] BuildCombinedIR 失败: %s\n", ent.Path)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "BuildCombinedIR 失败: %s", ent.Path)
|
||||
VLogger.error(fb, "PhaseB")
|
||||
stdlib.free(combined_ir)
|
||||
continue
|
||||
|
||||
# 编译为 .obj
|
||||
stdio.printf("[DBG] PhaseB step=compile_module_to_obj\n")
|
||||
stdio.fflush(0)
|
||||
cret: int = BuildPipeline.compile_module_to_obj(
|
||||
combined_ir, combined_len, temp_dir, output_dir, ent.Sha1,
|
||||
cc_cmd, cc_flags)
|
||||
stdio.printf("[DBG] PhaseB step=compile_module_to_obj done cret=%d\n", cret)
|
||||
stdio.fflush(0)
|
||||
stdlib.free(combined_ir)
|
||||
if cret != 0:
|
||||
stdio.printf("[FATAL][Phase B] llc 编译失败,终止编译: %s\n", ent.Path)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "llc 编译失败,终止编译: %s", ent.Path)
|
||||
VLogger.error(fb, "PhaseB")
|
||||
sys.exit(1)
|
||||
|
||||
compiled_count += 1
|
||||
stdio.printf("[DBG] PhaseB step=obj_path construct\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
# 构造 .obj 路径,检测是否是 main 模块(test_main.py 或 main.py)
|
||||
od_len: t.CSizeT = string.strlen(output_dir)
|
||||
@@ -424,7 +504,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
if op_sliced_len < 512:
|
||||
string.strcpy(main_obj_path, obj_path_sliced)
|
||||
else:
|
||||
stdio.printf("[Phase B] 警告: main_obj_path 缓冲区不足\n")
|
||||
VLogger.warning("main_obj_path 缓冲区不足", "PhaseB")
|
||||
else:
|
||||
# 其他模块: 追加到 obj_paths
|
||||
if obj_pos + op_sliced_len + 2 < OBJ_PATHS_SIZE:
|
||||
@@ -435,13 +515,20 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
obj_pos += op_sliced_len
|
||||
obj_paths[obj_pos] = '\0'
|
||||
else:
|
||||
stdio.printf("[Phase B] 警告: .obj 路径缓冲区不足\n")
|
||||
VLogger.warning(".obj 路径缓冲区不足", "PhaseB")
|
||||
stdlib.free(obj_path_sliced)
|
||||
stdio.printf("[DBG] PhaseB step=obj_path done\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
stdio.printf("[Phase B] 编译完成: %d/%d\n", compiled_count, file_count)
|
||||
stdio.printf("[DBG] PhaseB loop done compiled_count=%d\n", compiled_count)
|
||||
stdio.fflush(0)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "编译完成: %d/%d", compiled_count, file_count)
|
||||
VLogger.success(fb, "PhaseB")
|
||||
|
||||
if compiled_count == 0:
|
||||
stdio.printf("[Phase B] 无成功编译的文件\n")
|
||||
VLogger.error("无成功编译的文件", "PhaseB")
|
||||
stdlib.free(entries)
|
||||
return 1
|
||||
|
||||
@@ -449,198 +536,191 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
# includes.binary 可能缺少某些 includes .obj(如 testcheck.py),
|
||||
# 这些文件被用户项目导入但未被 TransPyV 自身依赖,Projectrans.py 未编译它们。
|
||||
# 检测并编译缺失的 includes 文件到 output_dir,加入链接命令。
|
||||
# 数据来源:StubMerger 全局内存存储器(不读取 _sha1_map.txt 文件)
|
||||
if includes_dir is not None and includes_binary_dir is not None:
|
||||
stdio.printf("[DBG] PhaseB+ start\n")
|
||||
stdio.fflush(0)
|
||||
inc_compiled: int = 0
|
||||
td_len_mi: t.CSizeT = string.strlen(temp_dir)
|
||||
map_path_mi: bytes = stdlib.malloc(td_len_mi + 32)
|
||||
if map_path_mi is not None:
|
||||
viperlib.snprintf(map_path_mi, td_len_mi + 32, "%s/_sha1_map.txt", temp_dir)
|
||||
mapf_mi: fileio.File | t.CPtr = fileio.File(map_path_mi, fileio.MODE.R)
|
||||
if not mapf_mi.closed:
|
||||
map_buf_mi: bytes = stdlib.malloc(65536)
|
||||
if map_buf_mi is not None:
|
||||
map_br_mi: t.CInt64T = mapf_mi.read_all(map_buf_mi, 65536)
|
||||
mapf_mi.close()
|
||||
if map_br_mi > 0:
|
||||
if map_br_mi < 65536:
|
||||
map_buf_mi[map_br_mi] = '\0'
|
||||
else:
|
||||
map_buf_mi[65535] = '\0'
|
||||
map_len_mi: t.CSizeT = map_br_mi
|
||||
mpos_mi: t.CSizeT = 0
|
||||
while mpos_mi < map_len_mi:
|
||||
ml_start_mi: t.CSizeT = mpos_mi
|
||||
while mpos_mi < map_len_mi:
|
||||
if map_buf_mi[mpos_mi] == '\n':
|
||||
break
|
||||
mpos_mi += 1
|
||||
ml_len_mi: t.CSizeT = mpos_mi - ml_start_mi
|
||||
mpos_mi += 1
|
||||
# 从全局存储器获取 SHA1/模块名/rel_path 数组(直接访问器,避免 box 解引用问题)
|
||||
store_count_mi: int = StubMerger.GetSha1StoreCount()
|
||||
stdio.printf("[DBG] PhaseB+ store_count=%d\n", store_count_mi)
|
||||
stdio.fflush(0)
|
||||
if store_count_mi > 0:
|
||||
store_sha1_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreArrPtr()
|
||||
store_mod_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreModArrPtr()
|
||||
store_rel_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreRelArrPtr()
|
||||
stdio.printf("[DBG] PhaseB+ arrs ok sha1=%p mod=%p rel=%p\n", store_sha1_arr_mi, store_mod_arr_mi, store_rel_arr_mi)
|
||||
stdio.fflush(0)
|
||||
for si_mi in range(store_count_mi):
|
||||
# 获取当前条目的 SHA1 和 rel_path
|
||||
inc_sha1_mi: str = store_sha1_arr_mi + t.CSizeT(si_mi) * 17
|
||||
inc_rel_mi: str = store_rel_arr_mi + t.CSizeT(si_mi) * StubMerger.MAX_REL_PATH_LEN
|
||||
stdio.printf("[DBG] PhaseB+ iter=%d sha1=%s rel=%s\n", si_mi, inc_sha1_mi, inc_rel_mi)
|
||||
stdio.fflush(0)
|
||||
|
||||
# 最小长度: 16(sha1)+1(:)+9(includes/)+1+1+1 = 29
|
||||
if ml_len_mi < 26:
|
||||
continue
|
||||
if map_buf_mi[ml_start_mi + 16] != ':':
|
||||
continue
|
||||
rp_start_mi: t.CSizeT = ml_start_mi + 17
|
||||
if string.strncmp(map_buf_mi + rp_start_mi, "includes/", 9) != 0:
|
||||
continue
|
||||
# 检查 .obj 是否已存在于 includes.binary
|
||||
ibd_len_mi: t.CSizeT = string.strlen(includes_binary_dir)
|
||||
check_pat_mi: bytes = stdlib.malloc(ibd_len_mi + 35)
|
||||
if check_pat_mi is None:
|
||||
continue
|
||||
viperlib.snprintf(check_pat_mi, ibd_len_mi + 35, "%s/%s*.obj", includes_binary_dir, inc_sha1_mi)
|
||||
check_fd_mi: w32.win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(w32.win32file.WIN32_FIND_DATAA.__sizeof__())
|
||||
obj_exists_mi: int = 0
|
||||
if check_fd_mi is not None:
|
||||
string.memset(check_fd_mi, 0, w32.win32file.WIN32_FIND_DATAA.__sizeof__())
|
||||
check_h_mi: w32.win32base.HANDLE = w32.win32file.FindFirstFileA(check_pat_mi, check_fd_mi)
|
||||
if check_h_mi != w32.win32base.INVALID_HANDLE_VALUE:
|
||||
w32.win32file.FindClose(check_h_mi)
|
||||
obj_exists_mi = 1
|
||||
if obj_exists_mi != 0:
|
||||
continue
|
||||
|
||||
# 提取 SHA1
|
||||
inc_sha1_mi: str = stdlib.malloc(17)
|
||||
if inc_sha1_mi is None:
|
||||
continue
|
||||
string.strncpy(inc_sha1_mi, map_buf_mi + ml_start_mi, 16)
|
||||
inc_sha1_mi[16] = '\0'
|
||||
# .obj 不存在,需要编译
|
||||
# 构造源文件路径: {includes_dir}/{rel_path}
|
||||
rel_path_len_mi: t.CSizeT = string.strlen(inc_rel_mi)
|
||||
inc_dir_len_mi: t.CSizeT = string.strlen(includes_dir)
|
||||
src_fp_mi: bytes = stdlib.malloc(inc_dir_len_mi + 1 + rel_path_len_mi + 1)
|
||||
if src_fp_mi is None:
|
||||
continue
|
||||
viperlib.snprintf(src_fp_mi, inc_dir_len_mi + 1 + rel_path_len_mi + 1,
|
||||
"%s/%s", includes_dir, inc_rel_mi)
|
||||
|
||||
# 检查 .obj 是否已存在于 includes.binary
|
||||
ibd_len_mi: t.CSizeT = string.strlen(includes_binary_dir)
|
||||
check_pat_mi: bytes = stdlib.malloc(ibd_len_mi + 35)
|
||||
if check_pat_mi is None:
|
||||
continue
|
||||
viperlib.snprintf(check_pat_mi, ibd_len_mi + 35, "%s/%s*.obj", includes_binary_dir, inc_sha1_mi)
|
||||
check_fd_mi: w32.win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(w32.win32file.WIN32_FIND_DATAA.__sizeof__())
|
||||
obj_exists_mi: int = 0
|
||||
if check_fd_mi is not None:
|
||||
string.memset(check_fd_mi, 0, w32.win32file.WIN32_FIND_DATAA.__sizeof__())
|
||||
check_h_mi: w32.win32base.HANDLE = w32.win32file.FindFirstFileA(check_pat_mi, check_fd_mi)
|
||||
if check_h_mi != w32.win32base.INVALID_HANDLE_VALUE:
|
||||
w32.win32file.FindClose(check_h_mi)
|
||||
obj_exists_mi = 1
|
||||
if obj_exists_mi != 0:
|
||||
continue
|
||||
# 检查是否为声明文件(只有 declare 没有实质 define)
|
||||
# 判断方法: text.ll 中若有混淆函数 define(含 @")则为实现文件
|
||||
is_decl_mi: int = -1
|
||||
tpath_mi: str = StubMerger._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "text.ll")
|
||||
if tpath_mi is not None:
|
||||
tf_mi: fileio.File | t.CPtr = fileio.File(tpath_mi, fileio.MODE.R)
|
||||
if not tf_mi.closed:
|
||||
is_decl_mi = 1
|
||||
tbuf_mi: bytes = stdlib.malloc(StubMerger.STUB_READ_BUF_SIZE)
|
||||
if tbuf_mi is not None:
|
||||
tbr_mi: t.CInt64T = tf_mi.read_all(tbuf_mi, StubMerger.STUB_READ_BUF_SIZE)
|
||||
if tbr_mi > 0:
|
||||
if tbr_mi < StubMerger.STUB_READ_BUF_SIZE:
|
||||
tbuf_mi[tbr_mi] = '\0'
|
||||
else:
|
||||
tbuf_mi[StubMerger.STUB_READ_BUF_SIZE - 1] = '\0'
|
||||
# 逐行扫描: 找 define 行中含 @" 的(混淆函数名)
|
||||
tpos_mi: t.CSizeT = 0
|
||||
while tpos_mi < tbr_mi:
|
||||
tls_mi: t.CSizeT = tpos_mi
|
||||
while tpos_mi < tbr_mi:
|
||||
if tbuf_mi[tpos_mi] == '\n':
|
||||
break
|
||||
tpos_mi += 1
|
||||
tll_mi: t.CSizeT = tpos_mi - tls_mi
|
||||
if tpos_mi < tbr_mi:
|
||||
tpos_mi += 1
|
||||
if tll_mi >= 7 and string.strncmp(tbuf_mi + tls_mi, "define ", 7) == 0:
|
||||
# 临时在行尾加 \0 供 strstr 使用
|
||||
saved_mi: t.CChar = tbuf_mi[tls_mi + tll_mi]
|
||||
tbuf_mi[tls_mi + tll_mi] = '\0'
|
||||
if string.strstr(tbuf_mi + tls_mi, "@\"") is not None:
|
||||
tbuf_mi[tls_mi + tll_mi] = saved_mi
|
||||
is_decl_mi = 0
|
||||
break
|
||||
tbuf_mi[tls_mi + tll_mi] = saved_mi
|
||||
stdlib.free(tbuf_mi)
|
||||
tf_mi.close()
|
||||
stdlib.free(tpath_mi)
|
||||
# is_decl_mi == -1: text.ll 不存在(Phase1 未翻译此文件,可能不被项目导入)
|
||||
# is_decl_mi == 1: 声明文件(仅 declare 无 define)
|
||||
# 两种情况都跳过:不编译未被 Phase1 翻译的 includes 文件
|
||||
if is_decl_mi != 0:
|
||||
continue
|
||||
|
||||
# .obj 不存在,需要编译
|
||||
# 构造源文件路径: {includes_dir}/{rel_path_without_includes_prefix}
|
||||
rel_path_len_mi: t.CSizeT = ml_len_mi - 26
|
||||
inc_dir_len_mi: t.CSizeT = string.strlen(includes_dir)
|
||||
src_fp_mi: bytes = stdlib.malloc(inc_dir_len_mi + 1 + rel_path_len_mi + 1)
|
||||
if src_fp_mi is None:
|
||||
continue
|
||||
viperlib.snprintf(src_fp_mi, inc_dir_len_mi + 1 + rel_path_len_mi + 1,
|
||||
"%s/%s", includes_dir, map_buf_mi + rp_start_mi + 9)
|
||||
# 尝试 BuildCombinedIR(stub/text 应已由 Phase1 生成)
|
||||
inc_combined_mi: bytes = stdlib.malloc(COMBINED_IR_SIZE)
|
||||
inc_combined_len_mi: t.CSizeT = 0
|
||||
if inc_combined_mi is not None:
|
||||
inc_combined_len_mi = StubMerger.BuildCombinedIR(temp_dir, inc_sha1_mi, inc_combined_mi, COMBINED_IR_SIZE)
|
||||
|
||||
# 检查是否为声明文件(只有 declare 没有实质 define)
|
||||
# 判断方法: text.ll 中若有混淆函数 define(含 @\")则为实现文件
|
||||
is_decl_mi: int = -1
|
||||
tpath_mi: str = StubMerger._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "text.ll")
|
||||
if tpath_mi is not None:
|
||||
tf_mi: fileio.File | t.CPtr = fileio.File(tpath_mi, fileio.MODE.R)
|
||||
if not tf_mi.closed:
|
||||
is_decl_mi = 1
|
||||
tbuf_mi: bytes = stdlib.malloc(StubMerger.STUB_READ_BUF_SIZE)
|
||||
if tbuf_mi is not None:
|
||||
tbr_mi: t.CInt64T = tf_mi.read_all(tbuf_mi, StubMerger.STUB_READ_BUF_SIZE)
|
||||
if tbr_mi > 0:
|
||||
if tbr_mi < StubMerger.STUB_READ_BUF_SIZE:
|
||||
tbuf_mi[tbr_mi] = '\0'
|
||||
else:
|
||||
tbuf_mi[StubMerger.STUB_READ_BUF_SIZE - 1] = '\0'
|
||||
# 逐行扫描: 找 define 行中含 @\" 的(混淆函数名)
|
||||
tpos_mi: t.CSizeT = 0
|
||||
while tpos_mi < tbr_mi:
|
||||
tls_mi: t.CSizeT = tpos_mi
|
||||
while tpos_mi < tbr_mi:
|
||||
if tbuf_mi[tpos_mi] == '\n':
|
||||
break
|
||||
tpos_mi += 1
|
||||
tll_mi: t.CSizeT = tpos_mi - tls_mi
|
||||
if tpos_mi < tbr_mi:
|
||||
tpos_mi += 1
|
||||
if tll_mi >= 7 and string.strncmp(tbuf_mi + tls_mi, "define ", 7) == 0:
|
||||
# 临时在行尾加 \0 供 strstr 使用
|
||||
saved_mi: t.CChar = tbuf_mi[tls_mi + tll_mi]
|
||||
tbuf_mi[tls_mi + tll_mi] = '\0'
|
||||
if string.strstr(tbuf_mi + tls_mi, "@\"") is not None:
|
||||
tbuf_mi[tls_mi + tll_mi] = saved_mi
|
||||
is_decl_mi = 0
|
||||
break
|
||||
tbuf_mi[tls_mi + tll_mi] = saved_mi
|
||||
stdlib.free(tbuf_mi)
|
||||
tf_mi.close()
|
||||
stdlib.free(tpath_mi)
|
||||
if is_decl_mi == 1:
|
||||
continue
|
||||
# 如果 stub/text 不存在,翻译源文件并保存 stub + text,然后重试
|
||||
if inc_combined_len_mi == 0 and inc_combined_mi is not None:
|
||||
# 计算 includes 文件的包名(相对 includes_dir 的目录部分)
|
||||
inc_pkg_mi: str = None
|
||||
if string.strlen(src_fp_mi) > inc_dir_len_mi + 1:
|
||||
inc_rel_mi2: str = src_fp_mi + inc_dir_len_mi + 1
|
||||
inc_pkg_mi = HandlesImports.compute_package_from_relpath(mb, inc_rel_mi2)
|
||||
tr_mi: HandlesTranslator.Translator | t.CPtr = BuildPipeline.TranslateFileGetTrans(mb, src_fp_mi, inc_sha1_mi, inc_pkg_mi)
|
||||
if tr_mi is not None:
|
||||
PBP_IR_SIZE: t.CSizeT = 1048576
|
||||
# 保存 stub.ll (切片路径)
|
||||
inc_stub_buf: bytes = stdlib.malloc(PBP_IR_SIZE)
|
||||
if inc_stub_buf is not None:
|
||||
tr_mi.dump_ir(inc_stub_buf, PBP_IR_SIZE, llvmlite.OUTPUT_STUB)
|
||||
inc_stub_len: t.CSizeT = string.strlen(inc_stub_buf)
|
||||
inc_stub_path: str = StubMerger._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "stub.ll")
|
||||
if inc_stub_path is not None:
|
||||
isf: fileio.File | t.CPtr = fileio.File(inc_stub_path, fileio.MODE.W)
|
||||
if not isf.closed:
|
||||
isf.write(inc_stub_buf, inc_stub_len)
|
||||
isf.close()
|
||||
stdlib.free(inc_stub_path)
|
||||
stdlib.free(inc_stub_buf)
|
||||
# 保存 text.ll (切片路径)
|
||||
inc_text_buf: bytes = stdlib.malloc(PBP_IR_SIZE)
|
||||
if inc_text_buf is not None:
|
||||
tr_mi.dump_ir(inc_text_buf, PBP_IR_SIZE, llvmlite.OUTPUT_TEXT)
|
||||
inc_text_len: t.CSizeT = string.strlen(inc_text_buf)
|
||||
inc_text_path: str = StubMerger._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "text.ll")
|
||||
if inc_text_path is not None:
|
||||
itf: fileio.File | t.CPtr = fileio.File(inc_text_path, fileio.MODE.W)
|
||||
if not itf.closed:
|
||||
itf.write(inc_text_buf, inc_text_len)
|
||||
itf.close()
|
||||
stdlib.free(inc_text_path)
|
||||
stdlib.free(inc_text_buf)
|
||||
# 重试 BuildCombinedIR
|
||||
inc_combined_len_mi = StubMerger.BuildCombinedIR(temp_dir, inc_sha1_mi, inc_combined_mi, COMBINED_IR_SIZE)
|
||||
|
||||
# 尝试 BuildCombinedIR(stub/text 应已由 Phase1 生成)
|
||||
inc_combined_mi: bytes = stdlib.malloc(COMBINED_IR_SIZE)
|
||||
inc_combined_len_mi: t.CSizeT = 0
|
||||
if inc_combined_mi is not None:
|
||||
inc_combined_len_mi = StubMerger.BuildCombinedIR(temp_dir, inc_sha1_mi, inc_combined_mi, COMBINED_IR_SIZE)
|
||||
if inc_combined_len_mi == 0:
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "BuildCombinedIR 失败: %s", src_fp_mi)
|
||||
VLogger.error(fb, "PhaseB+")
|
||||
if inc_combined_mi is not None:
|
||||
stdlib.free(inc_combined_mi)
|
||||
continue
|
||||
|
||||
# 如果 stub/text 不存在,翻译源文件并保存 stub + text,然后重试
|
||||
if inc_combined_len_mi == 0 and inc_combined_mi is not None:
|
||||
# 计算 includes 文件的包名(相对 includes_dir 的目录部分)
|
||||
inc_pkg_mi: str = None
|
||||
if string.strlen(src_fp_mi) > inc_dir_len_mi + 1:
|
||||
inc_rel_mi: str = src_fp_mi + inc_dir_len_mi + 1
|
||||
inc_pkg_mi = HandlesImports.compute_package_from_relpath(mb, inc_rel_mi)
|
||||
tr_mi: HandlesTranslator.Translator | t.CPtr = BuildPipeline.TranslateFileGetTrans(mb, src_fp_mi, inc_sha1_mi, inc_pkg_mi)
|
||||
if tr_mi is not None:
|
||||
PBP_IR_SIZE: t.CSizeT = 262144
|
||||
# 保存 stub.ll (切片路径)
|
||||
inc_stub_buf: bytes = stdlib.malloc(PBP_IR_SIZE)
|
||||
if inc_stub_buf is not None:
|
||||
tr_mi.dump_ir(inc_stub_buf, PBP_IR_SIZE, llvmlite.OUTPUT_STUB)
|
||||
inc_stub_len: t.CSizeT = string.strlen(inc_stub_buf)
|
||||
inc_stub_path: str = StubMerger._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "stub.ll")
|
||||
if inc_stub_path is not None:
|
||||
isf: fileio.File | t.CPtr = fileio.File(inc_stub_path, fileio.MODE.W)
|
||||
if not isf.closed:
|
||||
isf.write(inc_stub_buf, inc_stub_len)
|
||||
isf.close()
|
||||
stdlib.free(inc_stub_path)
|
||||
stdlib.free(inc_stub_buf)
|
||||
# 保存 text.ll (切片路径)
|
||||
inc_text_buf: bytes = stdlib.malloc(PBP_IR_SIZE)
|
||||
if inc_text_buf is not None:
|
||||
tr_mi.dump_ir(inc_text_buf, PBP_IR_SIZE, llvmlite.OUTPUT_TEXT)
|
||||
inc_text_len: t.CSizeT = string.strlen(inc_text_buf)
|
||||
inc_text_path: str = StubMerger._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "text.ll")
|
||||
if inc_text_path is not None:
|
||||
itf: fileio.File | t.CPtr = fileio.File(inc_text_path, fileio.MODE.W)
|
||||
if not itf.closed:
|
||||
itf.write(inc_text_buf, inc_text_len)
|
||||
itf.close()
|
||||
stdlib.free(inc_text_path)
|
||||
stdlib.free(inc_text_buf)
|
||||
# 重试 BuildCombinedIR
|
||||
inc_combined_len_mi = StubMerger.BuildCombinedIR(temp_dir, inc_sha1_mi, inc_combined_mi, COMBINED_IR_SIZE)
|
||||
# 编译为 .obj
|
||||
inc_cret_mi: int = BuildPipeline.compile_module_to_obj(
|
||||
inc_combined_mi, inc_combined_len_mi, temp_dir, output_dir, inc_sha1_mi,
|
||||
cc_cmd, cc_flags)
|
||||
stdlib.free(inc_combined_mi)
|
||||
if inc_cret_mi != 0:
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "llc 编译失败,终止编译: %s", src_fp_mi)
|
||||
VLogger.error(fb, "PhaseB+")
|
||||
sys.exit(1)
|
||||
|
||||
if inc_combined_len_mi == 0:
|
||||
stdio.printf("[Phase B+] BuildCombinedIR 失败: %s\n", src_fp_mi)
|
||||
if inc_combined_mi is not None:
|
||||
stdlib.free(inc_combined_mi)
|
||||
continue
|
||||
inc_compiled += 1
|
||||
|
||||
# 编译为 .obj
|
||||
inc_cret_mi: int = BuildPipeline.compile_module_to_obj(
|
||||
inc_combined_mi, inc_combined_len_mi, temp_dir, output_dir, inc_sha1_mi,
|
||||
cc_cmd, cc_flags)
|
||||
stdlib.free(inc_combined_mi)
|
||||
if inc_cret_mi != 0:
|
||||
stdio.printf("[FATAL][Phase B+] llc 编译失败,终止编译: %s\n", src_fp_mi)
|
||||
sys.exit(1)
|
||||
# 添加到 obj_paths (切片路径)
|
||||
od_len_mi: t.CSizeT = string.strlen(output_dir)
|
||||
inc_obj_sliced: str = StubMerger._sliced_path(output_dir, od_len_mi, inc_sha1_mi, "obj")
|
||||
if inc_obj_sliced is not None:
|
||||
inc_obj_len: t.CSizeT = string.strlen(inc_obj_sliced)
|
||||
if obj_pos + inc_obj_len + 2 < OBJ_PATHS_SIZE:
|
||||
if obj_pos > 0:
|
||||
obj_paths[obj_pos] = ' '
|
||||
obj_pos += 1
|
||||
string.strcpy(obj_paths + obj_pos, inc_obj_sliced)
|
||||
obj_pos += inc_obj_len
|
||||
obj_paths[obj_pos] = '\0'
|
||||
stdlib.free(inc_obj_sliced)
|
||||
|
||||
inc_compiled += 1
|
||||
|
||||
# 添加到 obj_paths (切片路径)
|
||||
od_len_mi: t.CSizeT = string.strlen(output_dir)
|
||||
inc_obj_sliced: str = StubMerger._sliced_path(output_dir, od_len_mi, inc_sha1_mi, "obj")
|
||||
if inc_obj_sliced is not None:
|
||||
inc_obj_len: t.CSizeT = string.strlen(inc_obj_sliced)
|
||||
if obj_pos + inc_obj_len + 2 < OBJ_PATHS_SIZE:
|
||||
if obj_pos > 0:
|
||||
obj_paths[obj_pos] = ' '
|
||||
obj_pos += 1
|
||||
string.strcpy(obj_paths + obj_pos, inc_obj_sliced)
|
||||
obj_pos += inc_obj_len
|
||||
obj_paths[obj_pos] = '\0'
|
||||
stdlib.free(inc_obj_sliced)
|
||||
|
||||
stdio.printf("[Phase B+] 编译缺失 includes: %d 个\n", inc_compiled)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "编译缺失 includes: %d 个", inc_compiled)
|
||||
VLogger.info(fb, "PhaseB+")
|
||||
|
||||
# === 4. Phase C: 链接所有 .obj → .exe ===
|
||||
stdio.printf("[DBG] PhaseC start\n")
|
||||
stdio.fflush(0)
|
||||
if log is not None:
|
||||
log.banner("Phase C: 链接")
|
||||
|
||||
@@ -674,20 +754,33 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
|
||||
final_obj_paths[fop_pos] = '\0'
|
||||
|
||||
obj_paths_len: t.CSizeT = fop_pos
|
||||
stdio.printf("[DBG] PhaseC before link_objs_to_exe len=%d\n", obj_paths_len)
|
||||
stdio.fflush(0)
|
||||
lret: int = BuildPipeline.link_objs_to_exe(
|
||||
final_obj_paths, obj_paths_len,
|
||||
linker_cmd, linker_flags, exe_path,
|
||||
includes_binary_dir)
|
||||
stdio.printf("[DBG] PhaseC link_objs_to_exe done lret=%d\n", lret)
|
||||
stdio.fflush(0)
|
||||
|
||||
if lret == 0:
|
||||
stdio.printf("输出: %s\n", exe_path)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "输出: %s", exe_path)
|
||||
VLogger.success(fb, "PhaseC")
|
||||
if args.get_bool("run"):
|
||||
stdio.printf("[run] 执行: %s\n", exe_path)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "执行: %s", exe_path)
|
||||
VLogger.info(fb, "run")
|
||||
rp: subprocess.CompletedProcess | t.CPtr = subprocess.run(exe_path, False, False)
|
||||
if rp is not None:
|
||||
stdio.printf("[run] 退出码: %d\n", rp.returncode)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "退出码: %d", rp.returncode)
|
||||
VLogger.info(fb, "run")
|
||||
else:
|
||||
stdio.printf("[Phase C] 链接失败\n")
|
||||
VLogger.error("链接失败", "PhaseC")
|
||||
stdlib.free(entries)
|
||||
return 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user