@@ -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。
125131export 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