@@ -26,6 +26,19 @@ std::vector<std::string> std_module_build_commands(const Toolchain& tc,
2626 const std::filesystem::path& bmiPath,
2727 std::string_view sysrootFlag);
2828
29+ std::optional<std::filesystem::path> find_libcxx_std_compat_source (
30+ const std::filesystem::path& cxx_binary,
31+ const std::string& envPrefix);
32+
33+ std::filesystem::path std_compat_bmi_path (const std::filesystem::path& cacheDir);
34+ std::filesystem::path staged_std_compat_bmi_path (const std::filesystem::path& outputDir);
35+
36+ std::vector<std::string> std_compat_build_commands (const Toolchain& tc,
37+ const std::filesystem::path& cacheDir,
38+ const std::filesystem::path& bmiPath,
39+ const std::filesystem::path& stdBmiPath,
40+ std::string_view sysrootFlag);
41+
2942std::filesystem::path archive_tool (const Toolchain& tc);
3043
3144// Locate clang-scan-deps in the same bin/ directory as clang++.
@@ -125,6 +138,11 @@ void enrich_toolchain(Toolchain& tc, const std::string& envPrefix) {
125138 tc.stdModuleSource = *p;
126139 tc.hasImportStd = true ;
127140 }
141+ if (tc.hasImportStd ) {
142+ if (auto p = find_libcxx_std_compat_source (tc.binaryPath , envPrefix)) {
143+ tc.stdCompatSource = *p;
144+ }
145+ }
128146}
129147
130148std::filesystem::path std_bmi_path (const std::filesystem::path& cacheDir) {
@@ -173,4 +191,57 @@ std::optional<std::filesystem::path> find_scan_deps(const Toolchain& tc) {
173191 return std::nullopt ;
174192}
175193
194+ std::optional<std::filesystem::path> find_libcxx_std_compat_source (
195+ const std::filesystem::path& cxx_binary,
196+ const std::string& envPrefix)
197+ {
198+ // Same search strategy as find_libcxx_std_module_source but for std.compat
199+ auto root = cxx_binary.parent_path ().parent_path ();
200+ auto p = root / " share" / " libc++" / " v1" / " std.compat.cppm" ;
201+ if (std::filesystem::exists (p)) return p;
202+ return std::nullopt ;
203+ }
204+
205+ std::filesystem::path std_compat_bmi_path (const std::filesystem::path& cacheDir) {
206+ return cacheDir / " pcm.cache" / " std.compat.pcm" ;
207+ }
208+
209+ std::filesystem::path staged_std_compat_bmi_path (const std::filesystem::path& outputDir) {
210+ return outputDir / " pcm.cache" / " std.compat.pcm" ;
211+ }
212+
213+ std::vector<std::string> std_compat_build_commands (const Toolchain& tc,
214+ const std::filesystem::path& cacheDir,
215+ const std::filesystem::path& bmiPath,
216+ const std::filesystem::path& stdBmiPath,
217+ std::string_view sysrootFlag)
218+ {
219+ auto relBmi = std::filesystem::relative (bmiPath, cacheDir).string ();
220+ auto relStdBmi = std::filesystem::relative (stdBmiPath, cacheDir).string ();
221+ // std.compat depends on std, so we need -fmodule-file=std=<std.pcm>
222+ // Note: the path after = must NOT be shell-quoted separately; the
223+ // entire -fmodule-file flag is a single token to the compiler.
224+ return {
225+ std::format (" cd {} && {}{} -std=c++23 -Wno-reserved-module-identifier{} "
226+ " -fmodule-file=std={} "
227+ " --precompile {} -o {} 2>&1" ,
228+ mcpp::xlings::shq (cacheDir.string ()),
229+ mcpp::toolchain::compiler_env_prefix (tc),
230+ mcpp::xlings::shq (tc.binaryPath .string ()),
231+ sysrootFlag,
232+ relStdBmi,
233+ mcpp::xlings::shq (tc.stdCompatSource .string ()),
234+ mcpp::xlings::shq (relBmi)),
235+ std::format (" cd {} && {}{} -std=c++23 -Wno-reserved-module-identifier{} "
236+ " -fmodule-file=std={} "
237+ " {} -c -o std.compat.o 2>&1" ,
238+ mcpp::xlings::shq (cacheDir.string ()),
239+ mcpp::toolchain::compiler_env_prefix (tc),
240+ mcpp::xlings::shq (tc.binaryPath .string ()),
241+ sysrootFlag,
242+ relStdBmi,
243+ mcpp::xlings::shq (relBmi))
244+ };
245+ }
246+
176247} // namespace mcpp::toolchain::clang
0 commit comments