From ec203677f1de13c200e54813db73a8ed5be8d4c9 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 12 Jul 2020 09:58:44 +0200 Subject: Cache subprojects variable value in scope::root_extra --- build2/b.cxx | 4 ++-- libbuild2/config/operation.cxx | 16 ++++++------- libbuild2/dist/operation.cxx | 8 +++---- libbuild2/file.cxx | 52 ++++++++++++++---------------------------- libbuild2/file.hxx | 7 ------ libbuild2/operation.cxx | 2 +- libbuild2/scope.cxx | 18 +++++++++++++++ libbuild2/scope.hxx | 11 +++++++++ 8 files changed, 61 insertions(+), 57 deletions(-) diff --git a/build2/b.cxx b/build2/b.cxx index 61cb931..4e9ebf7 100644 --- a/build2/b.cxx +++ b/build2/b.cxx @@ -1103,9 +1103,9 @@ main (int argc, char* argv[]) // Note that the subprojects variable has already been processed // and converted to a map by the bootstrap_src() call above. // - if (auto l = rs.vars[ctx->var_subprojects]) + if (const subprojects* ps = *rs.root_extra->subprojects) { - for (const auto& p: cast (l)) + for (const auto& p: *ps) { if (out_base.sub (out_root / p.second)) fail << tn << " is in a subproject of " << out_root << diff --git a/libbuild2/config/operation.cxx b/libbuild2/config/operation.cxx index 6e28b0a..c606d09 100644 --- a/libbuild2/config/operation.cxx +++ b/libbuild2/config/operation.cxx @@ -592,9 +592,9 @@ namespace build2 // Configure subprojects that have been loaded. // - if (auto l = rs.vars[ctx.var_subprojects]) + if (const subprojects* ps = *rs.root_extra->subprojects) { - for (auto p: cast (l)) + for (auto p: *ps) { const dir_path& pd (p.second); dir_path out_nroot (out_root / pd); @@ -633,9 +633,9 @@ namespace build2 // Configure subprojects. Since we don't load buildfiles if configuring // a forward, we do it for all known subprojects. // - if (auto l = rs.vars[ctx.var_subprojects]) + if (const subprojects* ps = *rs.root_extra->subprojects) { - for (auto p: cast (l)) + for (auto p: *ps) { dir_path out_nroot (out_root / p.second); const scope& nrs (ctx.scopes.find (out_nroot)); @@ -860,9 +860,9 @@ namespace build2 // Disfigure subprojects. Since we don't load buildfiles during // disfigure, we do it for all known subprojects. // - if (auto l = rs.vars[ctx.var_subprojects]) + if (const subprojects* ps = *rs.root_extra->subprojects) { - for (auto p: cast (l)) + for (auto p: *ps) { const dir_path& pd (p.second); dir_path out_nroot (out_root / pd); @@ -962,9 +962,9 @@ namespace build2 bool r (false); - if (auto l = rs.vars[ctx.var_subprojects]) + if (const subprojects* ps = *rs.root_extra->subprojects) { - for (auto p: cast (l)) + for (auto p: *ps) { dir_path out_nroot (out_root / p.second); const scope& nrs (ctx.scopes.find (out_nroot)); diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx index 8dd8a6e..cce2239 100644 --- a/libbuild2/dist/operation.cxx +++ b/libbuild2/dist/operation.cxx @@ -232,9 +232,9 @@ namespace build2 // The same for subprojects that have been loaded. // - if (auto l = rs->vars[ctx.var_subprojects]) + if (const subprojects* ps = *rs->root_extra->subprojects) { - for (auto p: cast (l)) + for (auto p: *ps) { const dir_path& pd (p.second); dir_path out_nroot (out_root / pd); @@ -373,9 +373,9 @@ namespace build2 const scope* srs (rs); const module::callbacks* cbs (&mod.callbacks_); - if (auto l = rs->vars[ctx.var_subprojects]) + if (const subprojects* ps = *rs->root_extra->subprojects) { - for (auto p: cast (l)) + for (auto p: *ps) { const dir_path& pd (p.second); if (dl.sub (pd)) diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index f91dbbd..81fca32 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -62,24 +62,6 @@ namespace build2 const path alt_buildfile_file ("build2file"); const path alt_buildignore_file (".build2ignore"); - ostream& - operator<< (ostream& os, const subprojects& sps) - { - for (auto b (sps.begin ()), i (b); os && i != sps.end (); ++i) - { - // See find_subprojects() for details. - // - const project_name& n ( - path::traits_type::is_separator (i->first.string ().back ()) - ? empty_project_name - : i->first); - - os << (i != b ? " " : "") << n << '@' << i->second; - } - - return os; - } - // Check if the standard/alternative file/directory exists, returning empty // path if it does not. // @@ -592,6 +574,7 @@ namespace build2 new scope::root_extra_type { nullopt /* project */, nullopt /* amalgamation */, + nullopt /* subprojects */, a, a ? alt_build_ext : std_build_ext, a ? alt_build_dir : std_build_dir, @@ -936,10 +919,12 @@ namespace build2 if (simple) { - // Simple project: no name and disabled amalgamation. + // Simple project: no name, disabled amalgamation, no subprojects. // rs.root_extra->project = nullptr; rs.root_extra->amalgamation = nullptr; + rs.root_extra->subprojects = nullptr; + } // We assume that bootstrap out cannot load this file explicitly. It // feels wrong to allow this since that makes the whole bootstrap @@ -1221,6 +1206,8 @@ namespace build2 v = move (sps); } } + + rs.root_extra->subprojects = cast_null (v); } } @@ -1265,12 +1252,10 @@ namespace build2 bool bootstrapped (scope& rs) { - // Use the subprojects variable set by bootstrap_src() as an indicator. - // It should either be NULL or typed (so we assume that the user will - // never set it to NULL). + // Use the subprojects value cached at the end of bootstrap_src() as an + // indicator. // - auto l (rs.vars[rs.ctx.var_subprojects]); - return l.defined () && (l->null || l->type != nullptr); + return rs.root_extra != nullptr && rs.root_extra->subprojects; } // Return true if the inner/outer project (identified by out/src_root) of @@ -1377,9 +1362,9 @@ namespace build2 scope* r (&root); - if (auto l = root.vars[ctx.var_subprojects]) + if (const subprojects* ps = *root.root_extra->subprojects) { - for (const auto& p: cast (l)) + for (const auto& p: *ps) { dir_path out_root (root.out_path () / p.second); @@ -2159,12 +2144,10 @@ namespace build2 break; } - if (auto l = r->vars[ctx.var_subprojects]) + if (const subprojects* ps = *r->root_extra->subprojects) { - const auto& m (cast (l)); - auto i (m.find (proj)); - - if (i != m.end ()) + auto i (ps->find (proj)); + if (i != ps->end ()) { const dir_path& d ((*i).second); out_root = r->out_path () / d; @@ -2334,12 +2317,11 @@ namespace build2 if (project (*root) == *proj) break; - if (auto l = root->vars[ctx.var_subprojects]) + if (const subprojects* ps = *root->root_extra->subprojects) { - const auto& m (cast (l)); - auto i (m.find (*proj)); + auto i (ps->find (*proj)); - if (i != m.end ()) + if (i != ps->end ()) { const dir_path& d ((*i).second); altn = nullopt; diff --git a/libbuild2/file.hxx b/libbuild2/file.hxx index aa30e39..e0291fe 100644 --- a/libbuild2/file.hxx +++ b/libbuild2/file.hxx @@ -4,8 +4,6 @@ #ifndef LIBBUILD2_FILE_HXX #define LIBBUILD2_FILE_HXX -#include - #include #include #include @@ -20,11 +18,6 @@ namespace build2 { class lexer; - using subprojects = std::map; - - LIBBUILD2_SYMEXPORT ostream& - operator<< (ostream&, const subprojects&); // Print as name@dir sequence. - LIBBUILD2_SYMEXPORT extern const dir_path std_build_dir; // build/ // build/root.build diff --git a/libbuild2/operation.cxx b/libbuild2/operation.cxx index 6acc39f..a14dfb7 100644 --- a/libbuild2/operation.cxx +++ b/libbuild2/operation.cxx @@ -553,7 +553,7 @@ namespace build2 << "src_root: " << cast (rs[ctx.var_src_root]) << endl << "out_root: " << cast (rs[ctx.var_out_root]) << endl << "amalgamation: " << (*rs.root_extra->amalgamation != nullptr ? **rs.root_extra->amalgamation : empty_dir_path) << endl - << "subprojects: " << cast_empty (rs[ctx.var_subprojects]) << endl + << "subprojects: " << (*rs.root_extra->subprojects != nullptr ? **rs.root_extra->subprojects : subprojects ()) << endl << "operations:"; print_ops (rs.root_extra->operations, ctx.operation_table); cout << endl << "meta-operations:"; print_ops (rs.root_extra->meta_operations, ctx.meta_operation_table); cout << endl; } diff --git a/libbuild2/scope.cxx b/libbuild2/scope.cxx index 92fc12c..f8fc634 100644 --- a/libbuild2/scope.cxx +++ b/libbuild2/scope.cxx @@ -10,6 +10,24 @@ using namespace std; namespace build2 { + ostream& + operator<< (ostream& os, const subprojects& sps) + { + for (auto b (sps.begin ()), i (b); os && i != sps.end (); ++i) + { + // See find_subprojects() for details. + // + const project_name& n ( + path::traits_type::is_separator (i->first.string ().back ()) + ? empty_project_name + : i->first); + + os << (i != b ? " " : "") << n << '@' << i->second; + } + + return os; + } + // scope // pair scope:: diff --git a/libbuild2/scope.hxx b/libbuild2/scope.hxx index 48731dc..25657a3 100644 --- a/libbuild2/scope.hxx +++ b/libbuild2/scope.hxx @@ -27,6 +27,11 @@ namespace build2 { class dir; + using subprojects = std::map; + + LIBBUILD2_SYMEXPORT ostream& + operator<< (ostream&, const subprojects&); // Print as name@dir sequence. + class LIBBUILD2_SYMEXPORT scope { public: @@ -429,6 +434,12 @@ namespace build2 // optional amalgamation; + // This project's subprojects (var_subprojects value). Absent means it + // is not yet determined (happens at the end of bootstrap_src()). NULL + // means there are no subprojects. + // + optional subprojects; + bool altn; // True if using alternative build file/directory naming. // Build file/directory naming scheme used by this project. -- cgit v1.1