自举实验失败,C1 编译 Test 成功,暂未达到自举收敛点

This commit is contained in:
2026-07-30 15:44:32 +08:00
parent 68481a5a7f
commit 32af3f93fa
22 changed files with 2158 additions and 442 deletions

View File

@@ -30,7 +30,7 @@ import lib.Projectrans.Config as Config
_mbuddy: memhub.MemBuddy | t.CPtr
# 源代码缓冲区大小1MB
SRC_BUF_SIZE: t.CDefine = 1048576
SRC_BUF_SIZE: t.CDefine = 1048576 # 2^20 = 1MB
# ============================================================
@@ -282,8 +282,76 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s
return 0
def _CollectObjFilesImpl(base_dir: str, bd_len: t.CSizeT,
out_buf: bytes, out_pos: t.CSizeT, out_size: t.CSizeT) -> t.CSizeT:
"""递归扫描 base_dir收集 .obj 文件路径到 out_buf返回新的 out_pos
支持切片子目录(如 dir/43/{sha1}.obj
"""
find_data: w32.win32file.WIN32_FIND_DATAA | t.CPtr = _mbuddy.alloc(w32.win32file.WIN32_FIND_DATAA.__sizeof__())
if find_data is None:
return out_pos
string.memset(find_data, 0, w32.win32file.WIN32_FIND_DATAA.__sizeof__())
pattern: bytes = _mbuddy.alloc(bd_len + 8)
if pattern is None:
return out_pos
viperlib.snprintf(pattern, bd_len + 8, "%s/*", base_dir)
handle: w32.win32base.HANDLE = w32.win32file.FindFirstFileA(pattern, find_data)
_mbuddy.free(pattern)
if handle == w32.win32base.INVALID_HANDLE_VALUE:
return out_pos
while True:
fname: str = find_data.cFileName
if fname is not None:
fname_len: t.CSizeT = string.strlen(fname)
if fname_len > 0:
# 跳过 . 和 ..
is_dot: int = 0
if fname_len == 1 and fname[0] == '.':
is_dot = 1
elif fname_len == 2 and fname[0] == '.' and fname[1] == '.':
is_dot = 1
if is_dot == 0:
attrs: ULONG = find_data.dwFileAttributes
is_dir: int = 0
if (attrs & w32.win32file.FILE_ATTRIBUTE_DIRECTORY) != 0:
is_dir = 1
if is_dir != 0:
# 递归扫描子目录
sub_dir: bytes = _mbuddy.alloc(bd_len + fname_len + 2)
if sub_dir is not None:
viperlib.snprintf(sub_dir, bd_len + fname_len + 2, "%s/%s", base_dir, fname)
sub_len: t.CSizeT = string.strlen(sub_dir)
out_pos = _CollectObjFilesImpl(sub_dir, sub_len, out_buf, out_pos, out_size)
_mbuddy.free(sub_dir)
else:
# 检查是否是 .obj 文件
if fname_len > 4:
if fname[fname_len - 4] == '.' and fname[fname_len - 3] == 'o' and fname[fname_len - 2] == 'b' and fname[fname_len - 1] == 'j':
need: t.CSizeT = bd_len + 1 + fname_len + 2
if out_pos + need < out_size:
if out_pos > 0:
out_buf[out_pos] = ' '
out_pos += 1
viperlib.snprintf(out_buf + out_pos, need, "%s/%s", base_dir, fname)
out_pos += bd_len + 1 + fname_len
else:
break
if w32.win32file.FindNextFileA(handle, find_data) == 0:
break
w32.win32file.FindClose(handle)
return out_pos
def collect_obj_files(includes_binary_dir: str, out_buf: bytes, out_size: t.CSizeT) -> t.CSizeT:
"""扫描 includes_binary_dir 目录,收集所有 .obj 文件路径到 out_buf
"""递归扫描 includes_binary_dir 目录,收集所有 .obj 文件路径到 out_buf
支持切片子目录(如 includes_binary_dir/43/{sha1}.obj
Args:
includes_binary_dir: includes.binary 目录路径
@@ -297,47 +365,8 @@ def collect_obj_files(includes_binary_dir: str, out_buf: bytes, out_size: t.CSiz
return 0
out_buf[0] = '\0'
out_pos: t.CSizeT = 0
# 构造搜索模式: dir/*.obj
dir_len: t.CSizeT = string.strlen(includes_binary_dir)
pattern: bytes = _mbuddy.alloc(dir_len + 8)
if pattern is None:
return 0
viperlib.snprintf(pattern, dir_len + 8, "%s/*.obj", includes_binary_dir)
# FindFirstFileA
find_data: w32.win32file.WIN32_FIND_DATAA | t.CPtr = _mbuddy.alloc(w32.win32file.WIN32_FIND_DATAA.__sizeof__())
if find_data is None:
return 0
string.memset(find_data, 0, w32.win32file.WIN32_FIND_DATAA.__sizeof__())
handle: w32.win32base.HANDLE = w32.win32file.FindFirstFileA(pattern, find_data)
if handle == w32.win32base.INVALID_HANDLE_VALUE:
return 0
# 需要 win32base 的 INVALID_HANDLE_VALUE
while True:
fname: str = find_data.cFileName
if fname is not None:
fname_len: t.CSizeT = string.strlen(fname)
# 构造完整路径并追加到 out_buf
# 路径格式: "dir/fname "
need: t.CSizeT = dir_len + 1 + fname_len + 2
if out_pos + need < out_size:
if out_pos > 0:
out_buf[out_pos] = ' '
out_pos += 1
viperlib.snprintf(out_buf + out_pos, need, "%s/%s", includes_binary_dir, fname)
out_pos += dir_len + 1 + fname_len
else:
# 缓冲区不足,停止
break
if w32.win32file.FindNextFileA(handle, find_data) == 0:
break
w32.win32file.FindClose(handle)
out_pos: t.CSizeT = _CollectObjFilesImpl(includes_binary_dir, dir_len, out_buf, 0, out_size)
out_buf[out_pos] = '\0'
return out_pos
@@ -509,13 +538,23 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: t.CSizeT,
viperlib.snprintf(cmd, cmd_len, "%s %s -o %s %s",
linker_cmd, obj_paths, linker_output, linker_flags)
# 用 stdlib.system() 直接在控制台运行链接,输出直接显示
# 避免 subprocess 管道捕获丢失输出TransPyV 标准句柄可能无效)
sys_ret: int = stdlib.system(cmd)
if sys_ret != 0:
# 用 subprocess.run 捕获 clang++ 的 stdout/stderr 输出
# 之前用 stdlib.system() 无法捕获具体错误undefined reference 等),
# 导致 1.txt 中只看到"链接失败,返回码: 1"而看不到未解析符号
result: subprocess.CompletedProcess | t.CPtr = subprocess.run(cmd, True, True)
if result is None:
VLogger.error("subprocess.run 返回 None", "link")
return 1
if result.returncode != 0:
# 先用 stdio.printf 直接输出 clang++ 的完整错误输出(含 undefined reference
# 必须在 VLogger.error 之前输出,因为 VLogger.error 会调用 sys.exit(1) 终止进程
if result.stdout is not None:
stdio.printf("=== clang++ 链接错误输出 ===\n%s\n", result.stdout)
if result.stderr is not None:
stdio.printf("=== clang++ stderr ===\n%s\n", result.stderr)
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
if fb is not None:
viperlib.snprintf(fb, 1024, "链接失败,返回码: %d, 命令: %s", sys_ret, cmd)
viperlib.snprintf(fb, 1024, "链接失败,返回码: %d, 命令: %s", result.returncode, cmd)
VLogger.error(fb, "link")
return 1
return 0