更新,可自举
This commit is contained in:
1 parent
07db560510
commit
ab0f37e1a8
35 files changed
+3759
-1518
No files matched your search
@@ -35,6 +35,7 @@ LinkerFlags: str = None # 链接器参数(空格分隔,从 linker.
|
||||
LinkerOutput: str = None
|
||||
TargetTriple: str = None
|
||||
TargetDataLayout: str = None
|
||||
ProjectDir: str = None # project.vpj 所在目录(resolve_paths 设置)
|
||||
Sha1SliceLevel: int = 0 # SHA1 切片层数(目录分散等级)
|
||||
StrictMode: int = 0
|
||||
IncludesDir: str = None # includes 目录路径(从 includes 数组首元素,兼容单目录场景)
|
||||
@@ -146,7 +147,7 @@ def Load_project_config(path: str) -> int:
|
||||
# 读取 includes 数组(支持多目录:首元素存 IncludesDir,全部拼接存 IncludesDirs)
|
||||
includes_val: JsonValue | t.CPtr = root["includes"]
|
||||
if includes_val is not None and includes_val.is_array():
|
||||
arr_len: t.CSizeT = includes_val.__len__()
|
||||
arr_len: t.CSizeT = len(includes_val)
|
||||
inc_buf: bytes = stdlib.malloc(2048)
|
||||
if inc_buf is not None:
|
||||
inc_buf[0] = '\0'
|
||||
@@ -186,12 +187,10 @@ def _join_flags_array(flags_val: JsonValue | t.CPtr) -> str:
|
||||
Returns:
|
||||
空格分隔的字符串,或 None 如果 flags_val 为 None 或非数组或空数组
|
||||
"""
|
||||
if flags_val is None:
|
||||
return None
|
||||
if not flags_val.is_array():
|
||||
return None
|
||||
if flags_val is None: return None
|
||||
if not flags_val.is_array(): return None
|
||||
|
||||
arr_len: t.CSizeT = flags_val.__len__()
|
||||
arr_len: t.CSizeT = len(flags_val)
|
||||
if arr_len == 0:
|
||||
return None
|
||||
|
||||
@@ -385,11 +384,14 @@ def resolve_paths(project_dir: str) -> int:
|
||||
0 表示成功,非 0 表示失败
|
||||
"""
|
||||
global SourceDir, BuildDir, TempDir, OutputDir, IncludesDir, IncludesDirs
|
||||
global ProjectDir
|
||||
if project_dir is None:
|
||||
return 1
|
||||
if _mbuddy is None:
|
||||
return 1
|
||||
|
||||
ProjectDir = project_dir
|
||||
|
||||
SourceDir = _join_path(SourceDir, project_dir)
|
||||
BuildDir = _join_path(BuildDir, project_dir)
|
||||
|
||||
@@ -441,9 +443,103 @@ def resolve_paths(project_dir: str) -> int:
|
||||
IncludesDirs = id_out
|
||||
if IncludesDir is not None:
|
||||
IncludesDir = _join_path(IncludesDir, project_dir)
|
||||
# linker.flags 中 `-T <脚本>` 的链接脚本路径同样基于 project_dir 解析,
|
||||
# 否则 subprocess 按进程 cwd(TransPyC/)找 linker.ld → ld.lld 报
|
||||
# "cannot find linker script linker.ld"
|
||||
_resolve_linker_t_paths(project_dir)
|
||||
return 0
|
||||
|
||||
|
||||
def _join_path_abs(rel: str, project_dir: str) -> str:
|
||||
"""将相对路径基于 project_dir 拼接为绝对路径(用于 -T 链接脚本等)
|
||||
|
||||
已为绝对路径(/ \\ 开头)或盘符形式(x:)时原样返回。
|
||||
"""
|
||||
if rel is None:
|
||||
return None
|
||||
rel_len: t.CSizeT = string.strlen(rel)
|
||||
if rel_len == 0:
|
||||
return rel
|
||||
if rel[0] == '/' or rel[0] == '\\':
|
||||
return rel
|
||||
if rel_len >= 2 and rel[1] == ':':
|
||||
return rel
|
||||
dir_len: t.CSizeT = string.strlen(project_dir)
|
||||
if dir_len == 0:
|
||||
return rel
|
||||
total_len: t.CSizeT = dir_len + 1 + rel_len + 1
|
||||
buf: str = _mbuddy.alloc(total_len)
|
||||
if buf is None:
|
||||
return rel
|
||||
viperlib.snprintf(buf, total_len, "%s/%s", project_dir, rel)
|
||||
return buf
|
||||
|
||||
|
||||
def _resolve_linker_t_paths(project_dir: str) -> None:
|
||||
"""将 LinkerFlags 中 `-T <相对路径>` 的链接脚本路径解析为绝对路径
|
||||
|
||||
ld.lld 的 -T 参数若是相对路径,将按 subprocess 进程 cwd 解析而找不到
|
||||
脚本。逐 token 扫描 LinkerFlags,遇 -T 其后 token 若非绝对路径则基于
|
||||
project_dir 拼接(与 resolve_paths 对其他相对路径的处理保持一致)。
|
||||
"""
|
||||
global LinkerFlags
|
||||
if LinkerFlags is None or project_dir is None:
|
||||
return
|
||||
fl_total: t.CSizeT = string.strlen(LinkerFlags)
|
||||
if fl_total == 0:
|
||||
return
|
||||
out: str = _mbuddy.alloc(fl_total * 2 + 512)
|
||||
if out is None:
|
||||
return
|
||||
out[0] = '\0'
|
||||
out_pos: t.CSizeT = 0
|
||||
i: t.CSizeT = 0
|
||||
prev_is_t: int = 0 # 前一 token 是否为 -T
|
||||
while i < fl_total:
|
||||
# 跳过前导空格
|
||||
while i < fl_total and LinkerFlags[i] == ' ':
|
||||
i += 1
|
||||
if i >= fl_total:
|
||||
break
|
||||
start: t.CSizeT = i
|
||||
while i < fl_total and LinkerFlags[i] != ' ':
|
||||
i += 1
|
||||
tok_len: t.CSizeT = i - start
|
||||
is_t_flag: int = 0
|
||||
if tok_len == 2 and LinkerFlags[start] == '-' and LinkerFlags[start + 1] == 'T':
|
||||
is_t_flag = 1
|
||||
# 输出分隔符(前一 token 之后)
|
||||
if out_pos > 0:
|
||||
out[out_pos] = ' '
|
||||
out_pos += 1
|
||||
if is_t_flag:
|
||||
string.strcpy(out + out_pos, "-T")
|
||||
out_pos += 2
|
||||
elif prev_is_t != 0:
|
||||
# -T 后的脚本路径:非绝对路径则基于 project_dir 拼接
|
||||
tok_buf: str = _mbuddy.alloc(tok_len + 1)
|
||||
if tok_buf is not None:
|
||||
string.memcpy(tok_buf, LinkerFlags + start, tok_len)
|
||||
tok_buf[tok_len] = '\0'
|
||||
abs_path: str = _join_path_abs(tok_buf, project_dir)
|
||||
if abs_path is not None:
|
||||
p_len: t.CSizeT = string.strlen(abs_path)
|
||||
string.strcpy(out + out_pos, abs_path)
|
||||
out_pos += p_len
|
||||
else:
|
||||
string.memcpy(out + out_pos, LinkerFlags + start, tok_len)
|
||||
out_pos += tok_len
|
||||
else:
|
||||
string.memcpy(out + out_pos, LinkerFlags + start, tok_len)
|
||||
out_pos += tok_len
|
||||
else:
|
||||
string.memcpy(out + out_pos, LinkerFlags + start, tok_len)
|
||||
out_pos += tok_len
|
||||
prev_is_t = is_t_flag
|
||||
out[out_pos] = '\0'
|
||||
LinkerFlags = out
|
||||
|
||||
|
||||
def get_includes_binary_dir() -> str:
|
||||
"""获取 includes.binary 目录路径(includes 目录 + 缓存后缀)
|
||||
|
||||
|
||||
@@ -89,16 +89,18 @@ def compute_sha1(pool: memhub.MemBuddy | t.CPtr, content: str) -> str:
|
||||
|
||||
|
||||
# ============================================================
|
||||
# is_vp_or_py_at - 检查路径段是否以 .vp/.py 后缀结尾
|
||||
# is_vp_at - 检查路径段是否以 .vp 后缀结尾
|
||||
# ============================================================
|
||||
def is_vp_or_py_at(p: str, start: t.CSizeT, plen: t.CSizeT) -> int:
|
||||
"""检查 p[start, start+plen) 是否以 .vp/.py 后缀结尾(1=是,0=否)"""
|
||||
def is_vp_at(p: str, start: t.CSizeT, plen: t.CSizeT) -> int:
|
||||
"""检查 p[start, start+plen) 是否以 .vp 后缀结尾(1=是,0=否)。
|
||||
|
||||
不再识别 .py(移除 vp -> py 后缀识别回退:Viper 源文件仅 .vp)。
|
||||
"""
|
||||
if p is None or plen <= 3:
|
||||
return 0
|
||||
base: t.CSizeT = start + plen - 3
|
||||
if p[base] == '.':
|
||||
if p[base + 1] == 'v' and p[base + 2] == 'p': return 1
|
||||
if p[base + 1] == 'p' and p[base + 2] == 'y': return 1
|
||||
if p[base] == '.' and p[base + 1] == 'v' and p[base + 2] == 'p':
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -167,8 +169,8 @@ def PathToModuleName(path: str, strip_includes_prefix: int) -> str:
|
||||
if psep_ch == '/' or psep_ch == '\\':
|
||||
path_start = prefix_len
|
||||
plen = plen - prefix_len
|
||||
# 去掉 .vp 或 .py 后缀(.vp 为 Viper 源,.py 向后兼容)
|
||||
if is_vp_or_py_at(path, path_start, plen) != 0:
|
||||
# 去掉 .vp 后缀(Viper 源文件仅 .vp,不再识别 .py)
|
||||
if is_vp_at(path, path_start, plen) != 0:
|
||||
plen -= 3
|
||||
if plen == 0:
|
||||
return None
|
||||
|
||||
Reference in new issue
Block a user