From 4bab5c56cd1c91a928af73e0d428d8cc361600f4 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 2 Jul 2020 07:51:07 +0200 Subject: Cache project name in root_extra --- libbuild2/file.cxx | 37 +++++++++++++++++++++++++++++-------- libbuild2/operation.cxx | 2 +- libbuild2/scope.hxx | 12 ++++++++++++ libbuild2/scope.ixx | 7 +++++-- libbuild2/version/init.cxx | 16 ++++++++-------- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index e0467ad..4431bd1 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -497,6 +497,7 @@ namespace build2 root.root_extra.reset ( new scope::root_extra_type { + nullopt /* project */, nullopt /* amalgamation */, a, a ? alt_build_ext : std_build_ext, @@ -646,8 +647,6 @@ namespace build2 } } - - // Extract the project name from bootstrap.build. // static project_name @@ -673,10 +672,14 @@ namespace build2 altn = s.root_extra->altn; else assert (*altn == s.root_extra->altn); - } - if (lookup l = s.vars[ctx.var_project]) - return cast (l); + if (s.root_extra->project) + { + return (*s.root_extra->project != nullptr + ? **s.root_extra->project + : empty_project_name); + } + } src_root = s.src_path_; } @@ -856,6 +859,7 @@ namespace build2 if (bf.empty ()) { r = false; + rs.root_extra->project = nullptr; // Simple project. } // We assume that bootstrap out cannot load this file explicitly. It // feels wrong to allow this since that makes the whole bootstrap @@ -864,6 +868,20 @@ namespace build2 // else if (rs.buildfiles.insert (bf).second) { + // Extract and pre-cache the project name before loading + // bootstrap.build. + // + // @@ TODO: optimize by extracting both of them at once? + // + auto pp (extract_variable (ctx, bf, *ctx.var_project, 1)); + + if (!pp.second) + fail << "variable " << *ctx.var_project << " expected as a first " + << "line in " << bf; + + const project_name pn (cast (move (pp.first))); + rs.root_extra->project = &pn; + // Deal with the empty amalgamation variable (which indicates that // amalgamating this project is disabled). We go through all this // trouble of extracting its value manually (and thus requiring its @@ -882,6 +900,10 @@ namespace build2 source (p, rs, rs, bf); } + // Update to point to the variable value. + // + rs.root_extra->project = &cast (rs.vars[ctx.var_project]); + // Detect and diagnose the case where the amalgamation variable is not // the second line. // @@ -2001,8 +2023,7 @@ namespace build2 // First check the amalgamation itself. // - if (r != &iroot && - cast (r->vars[ctx.var_project]) == proj) + if (r != &iroot && project (*r) == proj) { out_root = r->out_path (); break; @@ -2137,7 +2158,7 @@ namespace build2 // Now we know this project's name as well as all its subprojects. // - if (cast (root->vars[ctx.var_project]) == proj) + if (project (*root) == proj) break; if (auto l = root->vars[ctx.var_subprojects]) diff --git a/libbuild2/operation.cxx b/libbuild2/operation.cxx index 37baddd..6dd46c7 100644 --- a/libbuild2/operation.cxx +++ b/libbuild2/operation.cxx @@ -546,7 +546,7 @@ namespace build2 // This could be a simple project that doesn't set project name. // cout - << "project: " << cast_empty (rs[ctx.var_project]) << endl + << "project: " << project (rs) << endl << "version: " << cast_empty (rs[ctx.var_version]) << endl << "summary: " << cast_empty (rs[ctx.var_project_summary]) << endl << "url: " << cast_empty (rs[ctx.var_project_url]) << endl diff --git a/libbuild2/scope.hxx b/libbuild2/scope.hxx index 027fa46..bd1a70b 100644 --- a/libbuild2/scope.hxx +++ b/libbuild2/scope.hxx @@ -416,6 +416,14 @@ namespace build2 public: struct root_extra_type { + // This project's name (var_project value). Absent means it is not yet + // determined. NULL means simple project. Empty means unnamed project. + // + // Note that it is set to point to a temporary value before loading + // bootstrap.build and to a permanent one (from the variable) after. + // + optional project; + // This project's amalgamation (var_amalgamation value). Absent means it // is not yet determined. NULL means amalgamation is disabled. // @@ -562,6 +570,10 @@ namespace build2 // Return the project name or empty if unnamed. // + // Note that this function and named_project() below expect the root scope + // to either be already bootstrapped or being src-bootstrapped (see + // bootstrap_src()). + // const project_name& project (const scope& root); diff --git a/libbuild2/scope.ixx b/libbuild2/scope.ixx index a3a417f..01d239b 100644 --- a/libbuild2/scope.ixx +++ b/libbuild2/scope.ixx @@ -162,8 +162,11 @@ namespace build2 inline const project_name& project (const scope& rs) { - auto l (rs[rs.ctx.var_project]); - return l ? cast (l) : empty_project_name; + assert (rs.root_extra != nullptr && rs.root_extra->project); + + return *rs.root_extra->project != nullptr + ? **rs.root_extra->project + : empty_project_name; } inline const project_name& diff --git a/libbuild2/version/init.cxx b/libbuild2/version/init.cxx index 7c5d589..681b6a4 100644 --- a/libbuild2/version/init.cxx +++ b/libbuild2/version/init.cxx @@ -68,19 +68,19 @@ namespace build2 { if (nv.name == "name") { - auto* pn (cast_null (rs.vars[ctx.var_project])); + const project_name& pn (project (rs)); - if (pn == nullptr) + if (pn.empty ()) fail (l) << "version module loaded in unnamed project"; - if (nv.value != pn->string ()) + if (nv.value != pn.string ()) { path bf (rs.src_path () / rs.root_extra->bootstrap_file); location ml (f, nv.value_line, nv.value_column); location bl (bf); fail (ml) << "package name " << nv.value << " does not match " - << "build system project name " << *pn << + << "build system project name " << pn << info (bl) << "build system project name specified here"; } } @@ -273,7 +273,7 @@ namespace build2 // Create the module instance. // extra.set_module ( - new module (cast (rs.vars[ctx.var_project]), + new module (project (rs), move (v), committed, rewritten, @@ -298,8 +298,6 @@ namespace build2 if (!first) fail (l) << "multiple version module initializations"; - context& ctx (rs.ctx); - // Load in.base (in.* variables, in{} target type). // load_module (rs, rs, "in.base", l); @@ -324,7 +322,9 @@ namespace build2 if (!val) { - string p (cast (rs.vars[ctx.var_project]).string ()); + // We've already verified in boot() it is named. + // + string p (project (rs).string ()); p += '-'; p += v.string (); val = move (p); -- cgit v1.1