Skip to content

Commit 58d3645

Browse files
committed
fix(provider): 报错路径改为相对仓库根,协议里仍给绝对路径
学员看到的断言报错原先顶着一长串 /home/... 前缀 —— mcpp 传给编译器的是 绝对路径,__FILE__ 便是绝对的。生成的清单加上 -fmacro-prefix-map 让它 相对仓库根,噪声消失。 但协议要求绝对路径:d2x 靠 diagnostics.file 打开编辑器、监听文件变更。 所以在协议边界上还原成绝对。展示归展示,定位归定位。
1 parent becc8e4 commit 58d3645

2 files changed

Lines changed: 18 additions & 5 deletions

File tree

d2x/buildtools/mcpp/src/main.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,16 @@ int cmd_check(const fs::path& root, std::string_view id) {
9898

9999
auto report = d2x::runner::judge_run(ran.exit_code, result_file);
100100

101+
// 侧信道里的 file 来自 __FILE__,而生成的清单加了 -fmacro-prefix-map
102+
// 让它相对仓库根(学员看到的报错才不会顶着一长串 /home/... 前缀)。
103+
// 但协议要求绝对路径 —— d2x 靠它开编辑器、靠它监听文件变更 —— 所以
104+
// 在协议边界上还原。展示归展示,定位归定位。
101105
std::vector<std::string> diags;
102106
for (const auto& f : report.failures) {
103-
diags.push_back(d2x::emit::diagnostic(f.file, f.line, f.expr, f.expected, f.actual));
107+
auto abs = f.file.empty() || fs::path(f.file).is_absolute()
108+
? f.file
109+
: (root / f.file).lexically_normal().string();
110+
diags.push_back(d2x::emit::diagnostic(abs, f.line, f.expr, f.expected, f.actual));
104111
}
105112

106113
d2x::emit::verdict(d2x::runner::to_string(report.outcome), "run", ran.exit_code, diags);

d2x/buildtools/mcpp/src/manifest.cppm

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ std::string relative_to_member(const fs::path& repo_root, const fs::path& file)
3939
return std::format("{}/{}", kToRoot, rel);
4040
}
4141

42-
void write_package_header(std::ostream& out, std::string_view name) {
42+
void write_package_header(std::ostream& out, std::string_view name, const fs::path& repo_root) {
4343
std::println(out, "# 由 d2x-buildtools-mcpp 生成,请勿手工编辑。");
4444
std::println(out, "[package]");
4545
std::println(out, "name = \"{}\"", name);
@@ -49,6 +49,12 @@ void write_package_header(std::ostream& out, std::string_view name) {
4949
std::println(out, "[build]");
5050
// 显式清空源码 glob:练习不是这个包的「源码」,它们只是各自 target 的入口。
5151
std::println(out, "sources = []");
52+
// 让 __FILE__ 变成相对仓库根的路径。mcpp 传给编译器的是绝对路径,
53+
// 于是 d2x_assert 的报错会印出一长串 /home/... 前缀,对学员是噪声。
54+
// 这只影响宏展开出来的字符串,不影响编译器自身诊断里的路径。
55+
// 前缀必须是编译器实际看到的绝对路径,不能用 kToRoot 那种相对形式。
56+
std::println(out, "cxxflags = [\"-fmacro-prefix-map={}/=\"]",
57+
repo_root.generic_string());
5258
std::println(out, "");
5359
// 脚手架走正经的库依赖,而不是把仓库根塞进 include 搜索路径。
5460
// 后者会让练习能 #include 仓库里任何文件,是个隐患。
@@ -96,7 +102,7 @@ export void write_full(const fs::path& repo_root, const std::vector<Exercise>& a
96102
std::vector<std::string> members;
97103
for (const auto& [name, list] : by_member) {
98104
std::ostringstream buf;
99-
write_package_header(buf, name);
105+
write_package_header(buf, name, repo_root);
100106
for (const auto* ex : list) write_target(buf, repo_root, *ex);
101107
write_if_changed(root / name / "mcpp.toml", buf.str());
102108
members.push_back(name);
@@ -105,7 +111,7 @@ export void write_full(const fs::path& repo_root, const std::vector<Exercise>& a
105111
// _current 也是这个 workspace 的成员,占位清单先写空壳
106112
members.push_back("_current");
107113
write_if_changed(root / "_current" / "mcpp.toml",
108-
[&] { std::ostringstream b; write_package_header(b, "_current"); return b.str(); }());
114+
[&] { std::ostringstream b; write_package_header(b, "_current", repo_root); return b.str(); }());
109115

110116
std::ostringstream ws;
111117
std::println(ws, "# 由 d2x-buildtools-mcpp 生成,请勿手工编辑。");
@@ -124,7 +130,7 @@ export void write_full(const fs::path& repo_root, const std::vector<Exercise>& a
124130
// 切题 0.118s、切回 0.018s。
125131
export void write_current(const fs::path& repo_root, const Exercise& ex) {
126132
std::ostringstream buf;
127-
write_package_header(buf, "_current");
133+
write_package_header(buf, "_current", repo_root);
128134
write_target(buf, repo_root, ex);
129135
write_if_changed(build_dir(repo_root) / "_current" / "mcpp.toml", buf.str());
130136
}

0 commit comments

Comments
 (0)