From 9f5c4c1ae3bff517eefb39130287016514fb31c7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 6 Jan 2017 17:28:45 +0200 Subject: Store platform targets as typed target_triplet --- build2/cc/common | 14 +++---- build2/cc/guess.cxx | 4 +- build2/cc/init.cxx | 55 +++++++++++---------------- build2/cc/link.cxx | 2 +- build2/cc/module.cxx | 104 +++++++++++++++++++++++++++------------------------ 5 files changed, 87 insertions(+), 92 deletions(-) (limited to 'build2/cc') diff --git a/build2/cc/common b/build2/cc/common index 3974a03..2c79fa6 100644 --- a/build2/cc/common +++ b/build2/cc/common @@ -97,10 +97,10 @@ namespace build2 // Cached values for some commonly-used variables/values. // - const string& cid; // x.id - const string& ctg; // x.target - const string& tsys; // x.target.system - const string& tclass; // x.target.class + const string& cid; // x.id + const target_triplet& ctg; // x.target + const string& tsys; // x.target.system + const string& tclass; // x.target.class const string& tstd; // Translated x_std value (can be empty). @@ -140,9 +140,7 @@ namespace build2 const char* install, const char* uninstall, const string& id, - const string& tg, - const string& ts, - const string& tc, + const target_triplet& tg, const string& std, const process_path* pkgc, const dir_paths& sld, @@ -155,7 +153,7 @@ namespace build2 x_link (link), x_install (install), x_uninstall (uninstall), - cid (id), ctg (tg), tsys (ts), tclass (tc), + cid (id), ctg (tg), tsys (ctg.system), tclass (ctg.class_), tstd (std), pkgconfig (pkgc), sys_lib_dirs (sld), sys_inc_dirs (sid), x_src (src), x_hdr (hdr), x_inc (inc) {} diff --git a/build2/cc/guess.cxx b/build2/cc/guess.cxx index e0b4911..8b45420 100644 --- a/build2/cc/guess.cxx +++ b/build2/cc/guess.cxx @@ -946,8 +946,8 @@ namespace build2 // Now we need to map x86, x64, and ARM to the target triplets. The // problem is, there aren't any established ones so we got to invent - // them ourselves. Based on the discussion in , we need - // something in the CPU-VENDOR-OS-ABI form. + // them ourselves. Based on the discussion in , + // we need something in the CPU-VENDOR-OS-ABI form. // // The CPU part is fairly straightforward with x86 mapped to 'i386' (or // maybe 'i686'), x64 to 'x86_64', and ARM to 'arm' (it could also diff --git a/build2/cc/init.cxx b/build2/cc/init.cxx index 32ea8f3..a162daa 100644 --- a/build2/cc/init.cxx +++ b/build2/cc/init.cxx @@ -4,8 +4,6 @@ #include -#include - #include #include #include @@ -56,9 +54,9 @@ namespace build2 // Hint variables (not overridable). // - v.insert ("config.cc.id"); - v.insert ("config.cc.target"); - v.insert ("config.cc.pattern"); + v.insert ("config.cc.id"); + v.insert ("config.cc.pattern"); + v.insert ("config.cc.target"); // Target type, for example, "C library" or "C++ library". Should be set // on the target by the matching rule to the name of the module (e.g., @@ -115,31 +113,20 @@ namespace build2 // config.cc.target // { - // This value must be hinted and already canonicalized. + // This value must be hinted. // - const string& s (cast (hints["config.cc.target"])); + const auto& t (cast (hints["config.cc.target"])); - try - { - //@@ We do it in the hinting module and here. Any way not to - // duplicate the effort? Maybe move the splitting here and - // simply duplicate the values there? - // - triplet t (s); - - // Enter as cc.target.{cpu,vendor,system,version,class}. - // - rs.assign ("cc.target") = s; - rs.assign ("cc.target.cpu") = move (t.cpu); - rs.assign ("cc.target.vendor") = move (t.vendor); - rs.assign ("cc.target.system") = move (t.system); - rs.assign ("cc.target.version") = move (t.version); - rs.assign ("cc.target.class") = move (t.class_); - } - catch (const invalid_argument& e) - { - assert (false); // Should have been caught by the hinting module. - } + // Also enter as cc.target.{cpu,vendor,system,version,class} for + // convenience of access. + // + rs.assign ("cc.target.cpu") = t.cpu; + rs.assign ("cc.target.vendor") = t.vendor; + rs.assign ("cc.target.system") = t.system; + rs.assign ("cc.target.version") = t.version; + rs.assign ("cc.target.class") = t.class_; + + rs.assign ("cc.target") = t; } // config.cc.pattern @@ -182,10 +169,11 @@ namespace build2 variable_map h; if (first) { - h.assign ("config.bin.target") = cast (rs["cc.target"]); + h.assign ("config.bin.target") = + cast (rs["cc.target"]).string (); if (auto l = hints["config.bin.pattern"]) - h.assign ("config.bin.pattern") = cast (l); + h.assign ("config.bin.pattern") = cast (l); } load_module ("bin.config", rs, rs, loc, false, h); @@ -197,8 +185,8 @@ namespace build2 // if (first) { - const string& ct (cast (rs["cc.target"])); - const string& bt (cast (rs["bin.target"])); + const auto& ct (cast (rs["cc.target"])); + const auto& bt (cast (rs["bin.target"])); if (bt != ct) fail (loc) << "cc and bin module target mismatch" << @@ -245,7 +233,8 @@ namespace build2 // Prepare configuration hints. // variable_map h; - h.assign ("config.pkgconfig.target") = cast (rs["cc.target"]); + h.assign ("config.pkgconfig.target") = + cast (rs["cc.target"]); load_module ("pkgconfig.config", rs, rs, loc, true, h); } diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx index c90fcb1..f55013f 100644 --- a/build2/cc/link.cxx +++ b/build2/cc/link.cxx @@ -1046,7 +1046,7 @@ namespace build2 // Next check the target. While it might be incorporated into the linker // checksum, it also might not (e.g., VC link.exe). // - if (dd.expect (ctg) != nullptr) + if (dd.expect (ctg.string ()) != nullptr) l4 ([&]{trace << "target mismatch forcing update of " << t;}); // Start building the command line. While we don't yet know whether we diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx index 5ac10f7..067aea3 100644 --- a/build2/cc/module.cxx +++ b/build2/cc/module.cxx @@ -6,8 +6,6 @@ #include // left, setw() -#include - #include #include #include @@ -93,31 +91,33 @@ namespace build2 // Split/canonicalize the target. First see if the user asked us to // use config.sub. // - string ct, st; - triplet tt; - - if (ops.config_sub_specified ()) + target_triplet tt; { - st = run (ops.config_sub (), - ci.target.c_str (), - [] (string& l) {return move (l);}); - l5 ([&]{trace << "config.sub target: '" << st << "'";}); - } + string ct; - try - { - tt = triplet (st.empty () ? ci.target : st, ct); - l5 ([&]{trace << "canonical target: '" << ct << "'; " - << "class: " << tt.class_;}); - } - catch (const invalid_argument& e) - { - // This is where we suggest that the user specifies --config-sub to - // help us out. - // - fail << "unable to parse " << x_lang << " compiler target '" - << ci.target << "': " << e.what () << - info << "consider using the --config-sub option"; + if (ops.config_sub_specified ()) + { + ct = run (ops.config_sub (), + ci.target.c_str (), + [] (string& l) {return move (l);}); + l5 ([&]{trace << "config.sub target: '" << ct << "'";}); + } + + try + { + tt = target_triplet (ct.empty () ? ci.target : ct); + l5 ([&]{trace << "canonical target: '" << tt.string () << "'; " + << "class: " << tt.class_;}); + } + catch (const invalid_argument& e) + { + // This is where we suggest that the user specifies --config-sub to + // help us out. + // + fail << "unable to parse " << x_lang << " compiler target '" + << ci.target << "': " << e.what () << + info << "consider using the --config-sub option"; + } } // Translate x_std value (if any) to the compiler option (if any). @@ -177,6 +177,8 @@ namespace build2 } { + const string& ct (tt.string ()); // Canonical target. + dr << " signature " << ci.signature << '\n' << " target " << ct; @@ -232,14 +234,16 @@ namespace build2 rs.assign (x_signature) = move (ci.signature); rs.assign (x_checksum) = move (ci.checksum); - // Enter as x.target.{cpu,vendor,system,version,class}. + // Also enter as x.target.{cpu,vendor,system,version,class} for + // convenience of access. // - rs.assign (x_target) = move (ct); - rs.assign (x_target_cpu) = move (tt.cpu); - rs.assign (x_target_vendor) = move (tt.vendor); - rs.assign (x_target_system) = move (tt.system); - rs.assign (x_target_version) = move (tt.version); - rs.assign (x_target_class) = move (tt.class_); + rs.assign (x_target_cpu) = tt.cpu; + rs.assign (x_target_vendor) = tt.vendor; + rs.assign (x_target_system) = tt.system; + rs.assign (x_target_version) = tt.version; + rs.assign (x_target_class) = tt.class_; + + rs.assign (x_target) = move (tt); // config.x.{p,c,l}options // config.x.libs @@ -278,7 +282,7 @@ namespace build2 variable_map h; h.assign ("config.cc.id") = cast (rs[x_id]); - h.assign ("config.cc.target") = cast (rs[x_target]); + h.assign ("config.cc.target") = cast (rs[x_target]); if (!ci.cc_pattern.empty ()) h.assign ("config.cc.pattern") = move (ci.cc_pattern); @@ -294,25 +298,29 @@ namespace build2 // matched ours since it could have been loaded by another c-family // module. // - auto check = [&rs, &loc, this](const char* cvar, - const variable& xvar, - const char* w) - { - const string& cv (cast (rs[cvar])); - const string& xv (cast (rs[xvar])); - - if (cv != xv) - fail (loc) << "cc and " << x << " module " << w << " mismatch" << - info << cvar << " is " << cv << - info << xvar.name << " is " << xv; - }; - // Note that we don't require that patterns match. Presumably, if the // toolchain id and target are the same, then where exactly the tools // come from doesn't really matter. // - check ("cc.id", x_id, "toolchain"); - check ("cc.target", x_target, "target"); + { + const auto& cv (cast (rs["cc.id"])); + const auto& xv (cast (rs[x_id])); + + if (cv != xv) + fail (loc) << "cc and " << x << " module toolchain mismatch" << + info << "cc.id is " << cv << + info << x_id.name << " is " << xv; + } + + { + const auto& cv (cast (rs["cc.target"])); + const auto& xv (cast (rs[x_target])); + + if (cv != xv) + fail (loc) << "cc and " << x << " module target mismatch" << + info << "cc.target is " << cv << + info << x_target.name << " is " << xv; + } } } -- cgit v1.1