@@ -23,6 +23,7 @@ import mcpp.build.plan;
2323import mcpp.build.flags;
2424import mcpp.build.compile_commands;
2525import mcpp.dyndep;
26+ import mcpp.toolchain.detect;
2627import mcpp.xlings;
2728
2829export namespace mcpp ::build {
@@ -67,6 +68,16 @@ std::string escape_ninja_path(const std::filesystem::path& p) {
6768 return out;
6869}
6970
71+ std::string escape_ninja_variable_value (std::string_view s) {
72+ std::string out;
73+ out.reserve (s.size ());
74+ for (char c : s) {
75+ if (c == ' $' ) out += " $$" ;
76+ else out.push_back (c);
77+ }
78+ return out;
79+ }
80+
7081void write_file (const std::filesystem::path& p, std::string_view content) {
7182 std::filesystem::create_directories (p.parent_path ());
7283 std::ofstream os (p);
@@ -147,7 +158,8 @@ bool is_c_source(const std::filesystem::path& src) {
147158} // namespace
148159
149160std::string emit_ninja_string (const BuildPlan& plan) {
150- bool dyndep = dyndep_mode_enabled ();
161+ bool dyndep = dyndep_mode_enabled ()
162+ && plan.toolchain .compiler == mcpp::toolchain::CompilerId::GCC;
151163 std::string out;
152164 auto append = [&](std::string s) { out += std::move (s); };
153165
@@ -167,6 +179,7 @@ std::string emit_ninja_string(const BuildPlan& plan) {
167179
168180 append (std::format (" cxx = {}\n " , escape_ninja_path (flags.cxxBinary )));
169181 append (std::format (" cxxflags = {}\n " , flags.cxx ));
182+ append (std::format (" toolenv = {}\n " , escape_ninja_variable_value (flags.toolEnv )));
170183 if (need_c_rule) {
171184 append (std::format (" cc = {}\n " , escape_ninja_path (flags.ccBinary )));
172185 append (std::format (" cflags = {}\n " , flags.cc ));
@@ -208,7 +221,7 @@ std::string emit_ninja_string(const BuildPlan& plan) {
208221 " if [ -n \" $bmi_out\" ] && [ -f \" $bmi_out\" ]; then "
209222 " cp -p \" $bmi_out\" \" $bmi_out.bak\" ; "
210223 " fi && "
211- " $cxx $cxxflags -c $in -o $out && "
224+ " $toolenv $ cxx $cxxflags -c $in -o $out && "
212225 " if [ -n \" $bmi_out\" ] && [ -f \" $bmi_out.bak\" ] && "
213226 " cmp -s \" $bmi_out\" \" $bmi_out.bak\" ; then "
214227 " mv \" $bmi_out.bak\" \" $bmi_out\" ; "
@@ -221,38 +234,38 @@ std::string emit_ninja_string(const BuildPlan& plan) {
221234 append (" \n " );
222235
223236 append (" rule cxx_object\n " );
224- append (" command = $cxx $cxxflags -c $in -o $out\n " );
237+ append (" command = $toolenv $ cxx $cxxflags -c $in -o $out\n " );
225238 append (" description = OBJ $out\n " );
226239 if (dyndep)
227240 append (" restat = 1\n " );
228241 append (" \n " );
229242
230243 if (need_c_rule) {
231244 append (" rule c_object\n " );
232- append (" command = $cc $cflags -c $in -o $out\n " );
245+ append (" command = $toolenv $ cc $cflags -c $in -o $out\n " );
233246 append (" description = CC $out\n " );
234247 if (dyndep)
235248 append (" restat = 1\n " );
236249 append (" \n " );
237250 }
238251
239252 append (" rule cxx_link\n " );
240- append (" command = $cxx $in -o $out $ldflags\n " );
253+ append (" command = $toolenv $ cxx $in -o $out $ldflags\n " );
241254 append (" description = LINK $out\n\n " );
242255
243256 append (" rule cxx_archive\n " );
244- append (" command = $ar rcs $out $in\n " );
257+ append (" command = $toolenv $ ar rcs $out $in\n " );
245258 append (" description = AR $out\n\n " );
246259
247260 append (" rule cxx_shared\n " );
248- append (" command = $cxx -shared $in -o $out $ldflags\n " );
261+ append (" command = $toolenv $ cxx -shared $in -o $out $ldflags\n " );
249262 append (" description = SHARED $out\n\n " );
250263
251264 if (dyndep) {
252265 // Scan rule: produce P1689 .ddi for one TU.
253266 // -E -M -MM -MF gives us the dep file; -fdeps-* gives us the .ddi.
254267 append (" rule cxx_scan\n " );
255- append (" command = $cxx $cxxflags -fdeps-format=p1689r5 "
268+ append (" command = $toolenv $ cxx $cxxflags -fdeps-format=p1689r5 "
256269 " -fdeps-file=$out -fdeps-target=$compile_target "
257270 " -M -MM -MF $out.dep -E $in -o $compile_target\n " );
258271 append (" description = SCAN $out\n\n " );
@@ -268,10 +281,13 @@ std::string emit_ninja_string(const BuildPlan& plan) {
268281 auto std_bmi_dst = std::filesystem::path (" gcm.cache" ) / " std.gcm" ;
269282 auto std_o_dst = std::filesystem::path (" obj" ) / " std.o" ;
270283
271- append (std::format (" build {} : cp_bmi {}\n " , escape_ninja_path (std_bmi_dst),
272- escape_ninja_path (plan.stdBmiPath )));
273- append (std::format (" build {} : cp_bmi {}\n\n " , escape_ninja_path (std_o_dst),
274- escape_ninja_path (plan.stdObjectPath )));
284+ bool has_std_artifacts = !plan.stdBmiPath .empty () && !plan.stdObjectPath .empty ();
285+ if (has_std_artifacts) {
286+ append (std::format (" build {} : cp_bmi {}\n " , escape_ninja_path (std_bmi_dst),
287+ escape_ninja_path (plan.stdBmiPath )));
288+ append (std::format (" build {} : cp_bmi {}\n\n " , escape_ninja_path (std_o_dst),
289+ escape_ninja_path (plan.stdObjectPath )));
290+ }
275291
276292 auto bmi_path = [](std::string_view name) {
277293 std::string s = " gcm.cache/" ;
@@ -366,7 +382,8 @@ std::string emit_ninja_string(const BuildPlan& plan) {
366382 if (rule != " c_object" ) {
367383 for (auto & imp : cu.imports ) {
368384 if (imp == " std" || imp == " std.compat" ) {
369- implicit += " gcm.cache/std.gcm" ;
385+ if (has_std_artifacts)
386+ implicit += " gcm.cache/std.gcm" ;
370387 continue ;
371388 }
372389 implicit += " " + bmi_path (imp);
@@ -397,14 +414,16 @@ std::string emit_ninja_string(const BuildPlan& plan) {
397414 switch (lu.kind ) {
398415 case LinkUnit::Binary:
399416 case LinkUnit::TestBinary:
400- ins += " " + escape_ninja_path (std_o_dst);
417+ if (has_std_artifacts)
418+ ins += " " + escape_ninja_path (std_o_dst);
401419 rule = " cxx_link" ;
402420 break ;
403421 case LinkUnit::StaticLibrary:
404422 rule = " cxx_archive" ;
405423 break ;
406424 case LinkUnit::SharedLibrary:
407- ins += " " + escape_ninja_path (std_o_dst);
425+ if (has_std_artifacts)
426+ ins += " " + escape_ninja_path (std_o_dst);
408427 rule = " cxx_shared" ;
409428 break ;
410429 }
0 commit comments