修正了一些错误
This commit is contained in:
@@ -3,7 +3,9 @@ from stdint import *
|
||||
import memhub
|
||||
import string
|
||||
import stdio
|
||||
import stdlib
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
from json.__parser import parse as json_parse
|
||||
from json import JsonValue, JSON_OBJECT, JSON_INT
|
||||
import w32.fileio as fileio
|
||||
@@ -50,86 +52,132 @@ def Load_project_config(path: str) -> int:
|
||||
global IncludesDir
|
||||
|
||||
if path is None:
|
||||
stdio.printf("[CFG] FAIL: path is None\n")
|
||||
stdio.fflush(0)
|
||||
return 1
|
||||
if _mbuddy is None:
|
||||
stdio.printf("[CFG] FAIL: _mbuddy is None\n")
|
||||
stdio.fflush(0)
|
||||
return 1
|
||||
|
||||
# 打开文件
|
||||
stdio.printf("[CFG] before File ctor path=%s\n", path)
|
||||
stdio.fflush(0)
|
||||
f: fileio.File | t.CPtr = fileio.File(path, fileio.MODE.R)
|
||||
f_closed_flag: int = 1
|
||||
if f is not None:
|
||||
if f.closed:
|
||||
f_closed_flag = 1
|
||||
else:
|
||||
f_closed_flag = 0
|
||||
stdio.printf("[CFG] after File ctor f=%p closed=%d\n", f, f_closed_flag)
|
||||
stdio.fflush(0)
|
||||
if f is None:
|
||||
stdio.printf("[CFG] FAIL: File ctor returned None\n")
|
||||
stdio.fflush(0)
|
||||
return 1
|
||||
if f.closed:
|
||||
stdio.printf("[CFG] FAIL: f.closed is True\n")
|
||||
stdio.fflush(0)
|
||||
return 1
|
||||
|
||||
# 分配读取缓冲区
|
||||
CFG_BUF_SIZE: t.CSizeT = 8192
|
||||
buf: bytes = _mbuddy.alloc(CFG_BUF_SIZE)
|
||||
if buf is None:
|
||||
stdio.printf("[CFG] FAIL: alloc buf failed\n")
|
||||
stdio.fflush(0)
|
||||
f.close()
|
||||
return 1
|
||||
|
||||
stdio.printf("[CFG] before read_all\n")
|
||||
stdio.fflush(0)
|
||||
bytes_read: t.CInt64T = f.read_all(buf, CFG_BUF_SIZE)
|
||||
f.close()
|
||||
stdio.printf("[CFG] after read_all bytes_read=%d\n", bytes_read)
|
||||
stdio.fflush(0)
|
||||
if bytes_read <= 0:
|
||||
stdio.printf("[CFG] FAIL: bytes_read <= 0\n")
|
||||
stdio.fflush(0)
|
||||
return 1
|
||||
|
||||
# 解析 JSON
|
||||
stdio.printf("[CFG] before json_parse\n")
|
||||
stdio.fflush(0)
|
||||
root: JsonValue | t.CPtr = json_parse(_mbuddy, buf)
|
||||
stdio.printf("[CFG] after json_parse root=%p\n", root)
|
||||
stdio.fflush(0)
|
||||
if root is None:
|
||||
stdio.printf("[CFG] FAIL: json_parse returned None\n")
|
||||
stdio.fflush(0)
|
||||
return 1
|
||||
if not root.is_object():
|
||||
stdio.printf("[CFG] FAIL: root is not object\n")
|
||||
stdio.fflush(0)
|
||||
return 1
|
||||
stdio.printf("[CFG] root is object OK\n")
|
||||
stdio.fflush(0)
|
||||
|
||||
# 读取顶层字段
|
||||
SourceDir = root["source_dir"].as_string() if root["source_dir"] is not None else None
|
||||
# 读取顶层字段(使用显式 __getitem__ 调用,兼容旧编译器二进制)
|
||||
sd_val: JsonValue | t.CPtr = root.__getitem__("source_dir")
|
||||
SourceDir = sd_val.as_string() if sd_val is not None else None
|
||||
# build_dir: 统一构建目录(默认 ./.tpv_build),temp 和 output 作为其子目录
|
||||
bd_val: JsonValue | t.CPtr = root["build_dir"]
|
||||
bd_val: JsonValue | t.CPtr = root.__getitem__("build_dir")
|
||||
if bd_val is not None and bd_val.is_string():
|
||||
BuildDir = bd_val.as_string()
|
||||
else:
|
||||
BuildDir = "./.tpv_build"
|
||||
ProjectName = root["name"].as_string() if root["name"] is not None else None
|
||||
ProjectVersion = root["version"].as_string() if root["version"] is not None else None
|
||||
name_val: JsonValue | t.CPtr = root.__getitem__("name")
|
||||
ProjectName = name_val.as_string() if name_val is not None else None
|
||||
ver_val: JsonValue | t.CPtr = root.__getitem__("version")
|
||||
ProjectVersion = ver_val.as_string() if ver_val is not None else None
|
||||
|
||||
# 读取 compiler 子对象
|
||||
compiler: JsonValue | t.CPtr = root["compiler"]
|
||||
compiler: JsonValue | t.CPtr = root.__getitem__("compiler")
|
||||
if compiler is not None and compiler.is_object():
|
||||
CompilerCmd = compiler["cmd"].as_string() if compiler["cmd"] is not None else None
|
||||
cc_cmd_val: JsonValue | t.CPtr = compiler.__getitem__("cmd")
|
||||
CompilerCmd = cc_cmd_val.as_string() if cc_cmd_val is not None else None
|
||||
# 读取 compiler.flags 数组,拼接成空格分隔的字符串
|
||||
cc_flags_val: JsonValue | t.CPtr = compiler["flags"]
|
||||
cc_flags_val: JsonValue | t.CPtr = compiler.__getitem__("flags")
|
||||
CompilerFlags = _join_flags_array(cc_flags_val)
|
||||
|
||||
# 读取 linker 子对象
|
||||
linker: JsonValue | t.CPtr = root["linker"]
|
||||
linker: JsonValue | t.CPtr = root.__getitem__("linker")
|
||||
if linker is not None and linker.is_object():
|
||||
LinkerCmd = linker["cmd"].as_string() if linker["cmd"] is not None else None
|
||||
LinkerOutput = linker["output"].as_string() if linker["output"] is not None else None
|
||||
ld_cmd_val: JsonValue | t.CPtr = linker.__getitem__("cmd")
|
||||
LinkerCmd = ld_cmd_val.as_string() if ld_cmd_val is not None else None
|
||||
ld_out_val: JsonValue | t.CPtr = linker.__getitem__("output")
|
||||
LinkerOutput = ld_out_val.as_string() if ld_out_val is not None else None
|
||||
# 读取 linker.flags 数组,拼接成空格分隔的字符串
|
||||
ld_flags_val: JsonValue | t.CPtr = linker["flags"]
|
||||
ld_flags_val: JsonValue | t.CPtr = linker.__getitem__("flags")
|
||||
LinkerFlags = _join_flags_array(ld_flags_val)
|
||||
|
||||
# 读取 target 子对象
|
||||
target: JsonValue | t.CPtr = root["target"]
|
||||
target: JsonValue | t.CPtr = root.__getitem__("target")
|
||||
if target is not None and target.is_object():
|
||||
TargetTriple = target["triple"].as_string() if target["triple"] is not None else None
|
||||
TargetDataLayout = target["datalayout"].as_string() if target["datalayout"] is not None else None
|
||||
tgt_triple_val: JsonValue | t.CPtr = target.__getitem__("triple")
|
||||
TargetTriple = tgt_triple_val.as_string() if tgt_triple_val is not None else None
|
||||
tgt_dl_val: JsonValue | t.CPtr = target.__getitem__("datalayout")
|
||||
TargetDataLayout = tgt_dl_val.as_string() if tgt_dl_val is not None else None
|
||||
|
||||
# 读取 options 子对象
|
||||
# Sha1SliceLevel: SHA1 切片层数(默认 1,每层取 SHA1 前 2 字符作为子目录)
|
||||
# level=0 → 不切片,文件直接放 base_dir
|
||||
# level=1 → b7/{sha1}.ext
|
||||
# level=2 → b7/90/{sha1}.ext
|
||||
options: JsonValue | t.CPtr = root["options"]
|
||||
options: JsonValue | t.CPtr = root.__getitem__("options")
|
||||
Sha1SliceLevel = 1
|
||||
StrictMode = 1
|
||||
if options is not None and options.is_object():
|
||||
sl: JsonValue | t.CPtr = options["sha1_slice_level"]
|
||||
sl: JsonValue | t.CPtr = options.__getitem__("sha1_slice_level")
|
||||
if sl is not None and sl.is_int():
|
||||
Sha1SliceLevel = sl.as_int()
|
||||
sm: JsonValue | t.CPtr = options["strict_mode"]
|
||||
sm: JsonValue | t.CPtr = options.__getitem__("strict_mode")
|
||||
if sm is not None and sm.is_bool():
|
||||
StrictMode = 1 if sm.as_bool() else 0
|
||||
|
||||
# 读取 includes 数组(取首个元素作为 includes 目录)
|
||||
includes_val: JsonValue | t.CPtr = root["includes"]
|
||||
includes_val: JsonValue | t.CPtr = root.__getitem__("includes")
|
||||
if includes_val is not None and includes_val.is_array():
|
||||
arr_len: t.CSizeT = includes_val.__len__()
|
||||
if arr_len > 0:
|
||||
@@ -307,24 +355,38 @@ def get_includes_binary_dir() -> str:
|
||||
|
||||
|
||||
def print_config():
|
||||
"""打印当前配置(调试用)"""
|
||||
"""打印当前配置"""
|
||||
buf: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if buf is None:
|
||||
return
|
||||
if ProjectName is not None:
|
||||
stdio.printf(" project: %s v%s\n", ProjectName, ProjectVersion if ProjectVersion is not None else "?")
|
||||
viperlib.snprintf(buf, 1024, "project: %s v%s", ProjectName,
|
||||
ProjectVersion if ProjectVersion is not None else "?")
|
||||
VLogger.info(buf, "config")
|
||||
if SourceDir is not None:
|
||||
stdio.printf(" source_dir: %s\n", SourceDir)
|
||||
viperlib.snprintf(buf, 1024, "source_dir: %s", SourceDir)
|
||||
VLogger.info(buf, "config")
|
||||
if BuildDir is not None:
|
||||
stdio.printf(" build_dir: %s\n", BuildDir)
|
||||
viperlib.snprintf(buf, 1024, "build_dir: %s", BuildDir)
|
||||
VLogger.info(buf, "config")
|
||||
if TempDir is not None:
|
||||
stdio.printf(" temp_dir: %s\n", TempDir)
|
||||
viperlib.snprintf(buf, 1024, "temp_dir: %s", TempDir)
|
||||
VLogger.info(buf, "config")
|
||||
if OutputDir is not None:
|
||||
stdio.printf(" output_dir: %s\n", OutputDir)
|
||||
viperlib.snprintf(buf, 1024, "output_dir: %s", OutputDir)
|
||||
VLogger.info(buf, "config")
|
||||
if CompilerCmd is not None:
|
||||
stdio.printf(" compiler: %s\n", CompilerCmd)
|
||||
viperlib.snprintf(buf, 1024, "compiler: %s", CompilerCmd)
|
||||
VLogger.info(buf, "config")
|
||||
if LinkerCmd is not None:
|
||||
stdio.printf(" linker: %s -> %s\n", LinkerCmd, LinkerOutput if LinkerOutput is not None else "?")
|
||||
viperlib.snprintf(buf, 1024, "linker: %s -> %s", LinkerCmd,
|
||||
LinkerOutput if LinkerOutput is not None else "?")
|
||||
VLogger.info(buf, "config")
|
||||
if IncludesDir is not None:
|
||||
stdio.printf(" includes: %s\n", IncludesDir)
|
||||
stdio.printf(" sha1_slice_level: %d\n", Sha1SliceLevel)
|
||||
viperlib.snprintf(buf, 1024, "includes: %s", IncludesDir)
|
||||
VLogger.info(buf, "config")
|
||||
viperlib.snprintf(buf, 1024, "sha1_slice_level: %d", Sha1SliceLevel)
|
||||
VLogger.info(buf, "config")
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -63,12 +63,14 @@ def compute_sha1(pool: memhub.MemBuddy | t.CPtr, content: str) -> str:
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CleanDir - 删除目录中所有文件(非递归,保留目录本身)
|
||||
# CleanDir - 递归删除目录中所有文件和子目录(保留 dir_path 本身)
|
||||
#
|
||||
# 用于 --clean 选项:清理 temp_dir 和 output_dir 中的旧文件。
|
||||
# SHA1 分片目录结构(如 temp/1c/、temp/7a/)需要递归清理,
|
||||
# 否则旧的截断文件(如 256KB text.ll)会被 Phase1 跳过逻辑复用。
|
||||
# ============================================================
|
||||
def CleanDir(dir_path: str) -> int:
|
||||
"""删除目录中所有文件(非递归),返回删除的文件数,-1 表示错误"""
|
||||
"""递归删除目录中所有文件和子目录,保留 dir_path 本身,返回删除的文件数,-1 表示错误"""
|
||||
if dir_path is None:
|
||||
return -1
|
||||
dir_len: t.CSizeT = string.strlen(dir_path)
|
||||
@@ -104,8 +106,19 @@ def CleanDir(dir_path: str) -> int:
|
||||
full_path: bytes = stdlib.malloc(dir_len + fname_len + 2)
|
||||
if full_path is not None:
|
||||
viperlib.snprintf(full_path, dir_len + fname_len + 2, "%s/%s", dir_path, fname)
|
||||
if w32.win32file.DeleteFileA(full_path) != 0:
|
||||
deleted += 1
|
||||
# 检查是否为目录(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
is_dir: t.CUInt32T = find_data.dwFileAttributes & w32.win32file.FILE_ATTRIBUTE_DIRECTORY
|
||||
if is_dir != 0:
|
||||
# 递归清理子目录中的文件
|
||||
sub_deleted: int = CleanDir(full_path)
|
||||
if sub_deleted > 0:
|
||||
deleted += sub_deleted
|
||||
# 删除空子目录(RemoveDirectoryA 要求目录为空)
|
||||
w32.win32file.RemoveDirectoryA(full_path)
|
||||
else:
|
||||
# 删除文件
|
||||
if w32.win32file.DeleteFileA(full_path) != 0:
|
||||
deleted += 1
|
||||
stdlib.free(full_path)
|
||||
|
||||
if w32.win32file.FindNextFileA(handle, find_data) == 0:
|
||||
|
||||
Reference in New Issue
Block a user