aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-07-02 07:51:07 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-07-02 07:51:07 +0200
commit4bab5c56cd1c91a928af73e0d428d8cc361600f4 (patch)
treedeccae44ecd64dae3566e902a3ee4fd8b7353e1a
parent47d266e501522ccb217ec3a7aeebdfb54f3b30fb (diff)
Cache project name in root_extra
-rw-r--r--libbuild2/file.cxx37
-rw-r--r--libbuild2/operation.cxx2
-rw-r--r--libbuild2/scope.hxx12
-rw-r--r--libbuild2/scope.ixx7
-rw-r--r--libbuild2/version/init.cxx16
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<project_name> (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<project_name> (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<project_name> (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<project_name> (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<project_name> (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<project_name> (rs[ctx.var_project]) << endl
+ << "project: " << project (rs) << endl
<< "version: " << cast_empty<string> (rs[ctx.var_version]) << endl
<< "summary: " << cast_empty<string> (rs[ctx.var_project_summary]) << endl
<< "url: " << cast_empty<string> (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<const project_name*> 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<project_name> (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<project_name> (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<project_name> (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<project_name> (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);