feat(linker): TPV 支持 project.vpj linker.dynamic_libs 动态链接 .dll/.so(Config 解析+绝对路径解析+链接命令合并 static/dynamic,Viper str+= 拼接改用 snprintf)

This commit is contained in:
TermiNexus committed 2026-09-01 22:01:20 +08:00
1 parent 75db09e18a
commit 8dda9f7c2d
4 files changed
+80 -14

No files matched your search

+40 -2
View File
@@ -34,6 +34,7 @@ LinkerCmd: str = None
LinkerFlags: str = None # 链接器参数(空格分隔,从 linker.flags 数组拼接)
LinkerOutput: str = None
LinkerStaticLibs: str = None # 显式静态链接文件(空格分隔绝对路径,从 linker.static_libs 数组)
LinkerDynamicLibs: str = None # 显式动态链接文件(空格分隔绝对路径,从 linker.dynamic_libs 数组,.dll/.so)
TargetTriple: str = None
TargetDataLayout: str = None
ProjectDir: str = None # project.vpj 所在目录(resolve_paths 设置)
@@ -58,7 +59,7 @@ def Load_project_config(path: str) -> int:
0 表示成功,非 0 表示失败
"""
global SourceDir, BuildDir, TempDir, OutputDir, ProjectName, ProjectVersion
global CompilerCmd, CompilerFlags, LinkerCmd, LinkerFlags, LinkerOutput, LinkerStaticLibs
global CompilerCmd, CompilerFlags, LinkerCmd, LinkerFlags, LinkerOutput, LinkerStaticLibs, LinkerDynamicLibs
global TargetTriple, TargetDataLayout, Sha1SliceLevel, StrictMode
global IncludesDir, IncludesDirs
@@ -124,6 +125,10 @@ def Load_project_config(path: str) -> int:
# 先拼接原样字符串,resolve_paths 中再基于 project_dir 解析绝对路径
sl_val: JsonValue | t.CPtr = linker["static_libs"]
LinkerStaticLibs = _join_flags_array(sl_val)
# 读取 linker.dynamic_libs 数组:显式动态链接文件(.dll/.so),
# 同样先拼接原样字符串,resolve_paths 中基于 project_dir 解析绝对路径
dl_val: JsonValue | t.CPtr = linker["dynamic_libs"]
LinkerDynamicLibs = _join_flags_array(dl_val)
# 读取 target 子对象
target: JsonValue | t.CPtr = root["target"]
@@ -397,7 +402,7 @@ def resolve_paths(project_dir: str) -> int:
0 表示成功,非 0 表示失败
"""
global SourceDir, BuildDir, TempDir, OutputDir, IncludesDir, IncludesDirs
global ProjectDir, LinkerStaticLibs
global ProjectDir, LinkerStaticLibs, LinkerDynamicLibs
if project_dir is None:
return 1
if _mbuddy is None:
@@ -488,6 +493,39 @@ def resolve_paths(project_dir: str) -> int:
sl_pos += jl
sl_out[sl_pos] = '\0'
LinkerStaticLibs = sl_out
# linker.dynamic_libs 显式动态链接文件(.dll/.so)同样基于 project_dir
# 逐段解析为绝对路径
if LinkerDynamicLibs is not None:
dl_total: t.CSizeT = string.strlen(LinkerDynamicLibs)
dl_out: str = _mbuddy.alloc(dl_total * 3 + 64)
if dl_out is not None:
dl_out[0] = '\0'
dl_pos: t.CSizeT = 0
dl_i: t.CSizeT = 0
while dl_i < dl_total:
while dl_i < dl_total and LinkerDynamicLibs[dl_i] == ' ':
dl_i += 1
if dl_i >= dl_total:
break
dl_start: t.CSizeT = dl_i
while dl_i < dl_total and LinkerDynamicLibs[dl_i] != ' ':
dl_i += 1
seg_len: t.CSizeT = dl_i - dl_start
if seg_len > 0:
seg_buf: str = _mbuddy.alloc(seg_len + 1)
if seg_buf is not None:
string.strncpy(seg_buf, LinkerDynamicLibs + dl_start, seg_len)
seg_buf[seg_len] = '\0'
joined: str = _join_path(seg_buf, project_dir)
if joined is not None:
jl: t.CSizeT = string.strlen(joined)
if dl_pos > 0:
dl_out[dl_pos] = ' '
dl_pos += 1
string.strcpy(dl_out + dl_pos, joined)
dl_pos += jl
dl_out[dl_pos] = '\0'
LinkerDynamicLibs = dl_out
# linker.flags 中 `-T <脚本>` 的链接脚本路径同样基于 project_dir 解析,
# 否则 subprocess 按进程 cwd(TransPyC/)找 linker.ld → ld.lld 报
# "cannot find linker script linker.ld"