自举实验失败,C1 编译 Test 成功,暂未达到自举收敛点
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user