From 5c8de4f515c99d894bec764a6793352c9cad0825 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 16 Jun 2017 16:22:48 +0200 Subject: Add support for explicitly specifying module name on mxx{} target --- build2/algorithm.hxx | 10 +++++++--- build2/algorithm.ixx | 32 ++++++++++++++++++++++++++++++++ build2/cc/compile.cxx | 51 +++++++++++++++++++++++++++++++-------------------- build2/target.hxx | 14 ++++++++++++-- 4 files changed, 82 insertions(+), 25 deletions(-) (limited to 'build2') diff --git a/build2/algorithm.hxx b/build2/algorithm.hxx index 49ca7a7..fc5e02a 100644 --- a/build2/algorithm.hxx +++ b/build2/algorithm.hxx @@ -24,6 +24,11 @@ namespace build2 const target& search (const target&, const prerequisite&); + // As above but only search for an already existing target. + // + const target* + search_existing (const target&, const prerequisite&); + // As above but specify the prerequisite to search as a key. // const target& @@ -72,9 +77,8 @@ namespace build2 const target& search (const target&, name, const scope&); - // As above but only search for an already existing target. Unlike the above - // version, this one can be called during the execute phase. Return NULL for - // unknown target types. + // Unlike the above version, this one can be called during the execute + // phase. Return NULL for unknown target types. // const target* search_existing (const name&, diff --git a/build2/algorithm.ixx b/build2/algorithm.ixx index 27759c9..4885ecf 100644 --- a/build2/algorithm.ixx +++ b/build2/algorithm.ixx @@ -29,6 +29,38 @@ namespace build2 return *r; } + const target* + search_existing_target (const prerequisite_key&); // + + const target* + import_existing (const prerequisite_key&); // + + inline const target* + search_existing (const prerequisite& p) + { + assert (phase == run_phase::match); // Could be relaxed. + + const target* r (p.target.load (memory_order_consume)); + + if (r == nullptr) + { + const prerequisite_key& pk (p.key ()); + r = pk.proj ? import_existing (pk) : search_existing_target (pk); + + if (r != nullptr) + { + const target* e (nullptr); + if (!p.target.compare_exchange_strong ( + e, r, + memory_order_release, + memory_order_consume)) + assert (e == r); + } + } + + return r; + } + inline const target& search (const target& t, const target_type& tt, const prerequisite_key& k) { diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx index 265b1a9..c23eff2 100644 --- a/build2/cc/compile.cxx +++ b/build2/cc/compile.cxx @@ -2780,37 +2780,48 @@ namespace build2 continue; // Find the mxx{} prerequisite and extract its "file name" for the - // fuzzy match. + // fuzzy match unless the user specified the module name explicitly. // - string f; for (prerequisite_member p: group_prerequisite_members (act, *pt)) { if (p.is_a (*x_mod)) { - //@@ MOD: TODO check if module name set? Won't we have to search - // it for that? Search to existing only? - - // Add the directory part if it is relative. The idea is to - // include it into the module match, say hello.core vs - // hello/mxx{core}. Why not for absolute? Good question. What - // if it contains special components, say, ../mxx{core}? + // Check for an explicit module name. Only look for an existing + // target (which means the name can only be specified on the + // target itself, no target type/pattern-spec). // - const dir_path& d (p.dir ()); + const target* t (p.search_existing ()); + const string* n (t != nullptr + ? cast_null (t->vars[c_module_name]) + : nullptr); + if (n != nullptr) + done = check (pt, *n, false); + else + { + // Fuzzy match. + // + string f; - if (!d.empty () && d.relative ()) - f = d.representation (); // Includes trailing slash. + // Add the directory part if it is relative. The idea is to + // include it into the module match, say hello.core vs + // hello/mxx{core}. + // + // @@ MOD: Why not for absolute? Good question. What if it + // contains special components, say, ../mxx{core}? + // + const dir_path& d (p.dir ()); - f += p.name (); + if (!d.empty () && d.relative ()) + f = d.representation (); // Includes trailing slash. + + f += p.name (); + done = check (pt, f, true); + } break; } } - if (f.empty ()) // bmi{} without mxx{}? Good luck with that. - continue; - - // Check if it resolves any of our imports. - // - if ((done = check (pt, f, true))) + if (done) break; } @@ -2880,7 +2891,7 @@ namespace build2 info << "guessed: " << in << info << "actual: " << mn << info << "consider adjusting module interface file names or" << - info << "consider explicitly specifying module name with @@ MOD"; + info << "consider specifying module name with cc.module_name"; } } } diff --git a/build2/target.hxx b/build2/target.hxx index 418a8ea..906d92d 100644 --- a/build2/target.hxx +++ b/build2/target.hxx @@ -29,8 +29,10 @@ namespace build2 extern size_t current_on; // From . - const target& - search (const target&, const prerequisite&); // From . + // From . + // + const target& search (const target&, const prerequisite&); + const target* search_existing (const prerequisite&); // Target state. // @@ -906,6 +908,14 @@ namespace build2 return target != nullptr ? target : prerequisite.target.load (mo); } + const target_type* + search_existing () const + { + return target != nullptr + ? target + : build2::search_existing (prerequisite); + } + // Return as a new prerequisite instance. // prerequisite_type -- cgit v1.1