From e879c347f4f05dac5405bcc45ae2d5c9dde5447c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 30 Aug 2016 15:30:39 +0200 Subject: Add support for target visibility, use for dist, test, install This means we can no longer write: install = false Now it should be: *: install = false --- build/root.build | 3 +-- build2/bin/init.cxx | 3 +-- build2/c/init.cxx | 2 +- build2/config/operation.cxx | 4 ++-- build2/context.cxx | 2 +- build2/cxx/init.cxx | 2 +- build2/dist/init.cxx | 7 +++++-- build2/dump.cxx | 4 ++-- build2/install/init.cxx | 7 +++---- build2/module.cxx | 2 -- build2/parser.cxx | 22 +++++++++++++++------- build2/scope.cxx | 10 +++++++++- build2/test/init.cxx | 12 ++++++------ build2/variable | 24 ++++++++++++++++++++++-- buildfile | 5 ++++- 15 files changed, 73 insertions(+), 36 deletions(-) diff --git a/build/root.build b/build/root.build index fd751bc..730200b 100644 --- a/build/root.build +++ b/build/root.build @@ -13,7 +13,6 @@ cxx{*}: extension = cxx cxx.poptions =+ -I$out_root -I$src_root -# All exe{} in tests/ are, well, tests. Don't install them. +# All exe{} in tests/ are, well, tests. # tests/exe{*}: test = true -tests/: install = false diff --git a/build2/bin/init.cxx b/build2/bin/init.cxx index 5a13a87..59d9ce6 100644 --- a/build2/bin/init.cxx +++ b/build2/bin/init.cxx @@ -83,7 +83,6 @@ namespace build2 v.insert ("bin.exe.suffix"); v.insert> ("bin.lib.version", - false, variable_visibility::project); } @@ -202,7 +201,7 @@ namespace build2 if (v == nullptr) fail (loc) << "unable to determine binutils target" << - info << "consider specifying it with " << var.name << + info << "consider specifying it with " << var << info << "or first load a module that can provide it as a hint, " << "such as c or cxx"; diff --git a/build2/c/init.cxx b/build2/c/init.cxx index 7d104b0..503d942 100644 --- a/build2/c/init.cxx +++ b/build2/c/init.cxx @@ -159,7 +159,7 @@ namespace build2 v["cc.type"], v["cc.system"], - v.insert ("c.std", false, variable_visibility::project), + v.insert ("c.std", variable_visibility::project), v.insert ("c.id"), v.insert ("c.id.type"), diff --git a/build2/config/operation.cxx b/build2/config/operation.cxx index e6ab14a..78c63b1 100644 --- a/build2/config/operation.cxx +++ b/build2/config/operation.cxx @@ -187,7 +187,7 @@ namespace build2 // something is broken. // if (r == nullptr) - fail (loc) << "inherited variable " << var.name << " value " + fail (loc) << "inherited variable " << var << " value " << "is not from a root scope"; // If none of the outer project's configurations use this value, @@ -198,7 +198,7 @@ namespace build2 { diag_record dr; dr << warn (loc) << "saving previously inherited variable " - << var.name; + << var; dr << info (loc) << "because project " << r->out_path () << " no longer uses it in its configuration"; diff --git a/build2/context.cxx b/build2/context.cxx index a3678dd..1c50610 100644 --- a/build2/context.cxx +++ b/build2/context.cxx @@ -235,7 +235,7 @@ namespace build2 // v.insert ("subprojects"); - v.insert ("extension", false, variable_visibility::project); + v.insert ("extension", variable_visibility::target); } gs.assign ("build.work") = work; diff --git a/build2/cxx/init.cxx b/build2/cxx/init.cxx index 9aa30dc..de52b47 100644 --- a/build2/cxx/init.cxx +++ b/build2/cxx/init.cxx @@ -159,7 +159,7 @@ namespace build2 v["cc.type"], v["cc.system"], - v.insert ("cxx.std", false, variable_visibility::project), + v.insert ("cxx.std", variable_visibility::project), v.insert ("cxx.id"), v.insert ("cxx.id.type"), diff --git a/build2/dist/init.cxx b/build2/dist/init.cxx index 338f6c8..2bf26e0 100644 --- a/build2/dist/init.cxx +++ b/build2/dist/init.cxx @@ -49,8 +49,11 @@ namespace build2 v.insert ("dist.cmd"); v.insert ("dist.archives"); - v.insert ("dist"); // Flag. - v.insert ("dist.package"); // Project's package name. + v.insert ("dist", variable_visibility::target); // Flag. + + // Project's package name. + // + v.insert ("dist.package", variable_visibility::project); } } diff --git a/build2/dump.cxx b/build2/dump.cxx index 506ebff..9c26235 100644 --- a/build2/dump.cxx +++ b/build2/dump.cxx @@ -74,7 +74,7 @@ namespace build2 const value& v (p.second); assert (v.type == nullptr); - os << var.name << (v.extra == 1 ? " =+ " : " += "); + os << var << (v.extra == 1 ? " =+ " : " += "); dump_value (os, v, false); } else @@ -86,7 +86,7 @@ namespace build2 if (var.type != nullptr) os << '[' << var.type->name << "] "; - os << var.name << " = "; + os << var << " = "; // If this variable is overriden, print both the override and the // original values. diff --git a/build2/install/init.cxx b/build2/install/init.cxx index f91e9dc..73e4c1e 100644 --- a/build2/install/init.cxx +++ b/build2/install/init.cxx @@ -189,10 +189,9 @@ namespace build2 // way we distinguish between the two is via the presence/absence of // the trailing directory separator. // - v.insert ("install", false, variable_visibility::project); - v.insert ("install.mode", false, variable_visibility::project); - v.insert ("install.subdirs", false, - variable_visibility::project); + v.insert ("install", variable_visibility::target); + v.insert ("install.mode", variable_visibility::project); + v.insert ("install.subdirs", variable_visibility::project); } // Register our alias and file rules. diff --git a/build2/module.cxx b/build2/module.cxx index e1e8afd..432c595 100644 --- a/build2/module.cxx +++ b/build2/module.cxx @@ -101,10 +101,8 @@ namespace build2 i->second.init (rs, bs, loc, i->second.module, f, opt, hints)); const variable& lv (var_pool.insert (name + ".loaded", - false, variable_visibility::project)); const variable& cv (var_pool.insert (name + ".configured", - false, variable_visibility::project)); bs.assign (lv) = l; bs.assign (cv) = c; diff --git a/build2/parser.cxx b/build2/parser.cxx index 689db66..1bc3519 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -488,6 +488,11 @@ namespace build2 { // Scope variable. // + if (var.visibility == variable_visibility::target) + fail (ploc) << "variable " << var << " has target " + << "visibility but assigned in a scope" << + info << "consider changing to '.../*: " << var << "'"; + enter_scope sg (*this, move (n.dir)); variable (t, tt, var, att); } @@ -604,13 +609,11 @@ namespace build2 // if (att == type::prepend && lhs.extra == 2) fail (at) << "prepend to a previously appended target " - << "type/pattern-specific variable " - << var.name; + << "type/pattern-specific variable " << var; if (att == type::append && lhs.extra == 1) fail (at) << "append to a previously prepended target " - << "type/pattern-specific variable " - << var.name; + << "type/pattern-specific variable " << var; // Do untyped prepend/append. // @@ -620,7 +623,7 @@ namespace build2 if (lhs.extra != 0 && lhs.type != nullptr) fail (at) << "typed prepend/append to target type/pattern-" - << "specific variable " << var.name; + << "specific variable " << var; } } @@ -723,6 +726,11 @@ namespace build2 // variable_attributes (var); + if (var.visibility == variable_visibility::target) + fail (nloc) << "variable " << var << " has target visibility but " + << "assigned in a scope" << + info << "consider changing to '*: " << var << "'"; + variable (t, tt, var, tt); if (tt == type::newline) @@ -1532,7 +1540,7 @@ namespace build2 if (var.type == nullptr) var.type = type; else if (var.type != type) - fail (l) << "changing variable " << var.name << " type from " + fail (l) << "changing variable " << var << " type from " << var.type->name << " to " << type->name; } } @@ -2371,7 +2379,7 @@ namespace build2 // @@ TMP this isn't proving to be particularly useful. // //if (var.name.find ('.') != string::npos) - //fail (loc) << "undefined/null namespace variable " << var.name; + //fail (loc) << "undefined/null namespace variable " << var; // See if we should set the NULL indicator. // diff --git a/build2/scope.cxx b/build2/scope.cxx index 885a8d2..9cbeca1 100644 --- a/build2/scope.cxx +++ b/build2/scope.cxx @@ -18,6 +18,8 @@ namespace build2 const target_type* gt, const string* gn, size_t start_d) const { + assert (tt != nullptr || var.visibility != variable_visibility::target); + size_t d (0); // Process target type/pattern-specific prepend/append values. @@ -131,7 +133,10 @@ namespace build2 } } - if (++d >= start_d) + // Note that we still increment the lookup depth so that we can compare + // depths of variables with different visibilities. + // + if (++d >= start_d && var.visibility != variable_visibility::target) { if (const value* v = s->vars.find (var)) return make_pair (lookup (v, &s->vars), d); @@ -142,6 +147,7 @@ namespace build2 case variable_visibility::scope: s = nullptr; break; + case variable_visibility::target: case variable_visibility::project: s = s->root () ? nullptr : s->parent_scope (); break; @@ -230,6 +236,8 @@ namespace build2 } case variable_visibility::normal: break; + case variable_visibility::target: + assert (false); } return true; diff --git a/build2/test/init.cxx b/build2/test/init.cxx index bd03f00..5b01bce 100644 --- a/build2/test/init.cxx +++ b/build2/test/init.cxx @@ -40,12 +40,12 @@ namespace build2 // Note: none are overridable. // - v.insert ("test"); - v.insert ("test.input"); - v.insert ("test.output"); - v.insert ("test.roundtrip"); - v.insert ("test.options"); - v.insert ("test.arguments"); + v.insert ("test", variable_visibility::target); + v.insert ("test.input", variable_visibility::project); + v.insert ("test.output", variable_visibility::project); + v.insert ("test.roundtrip", variable_visibility::project); + v.insert ("test.options", variable_visibility::project); + v.insert ("test.arguments", variable_visibility::project); } } diff --git a/build2/variable b/build2/variable index fb44bb4..000ac9c 100644 --- a/build2/variable +++ b/build2/variable @@ -80,9 +80,13 @@ namespace build2 enum class variable_visibility { + target, // Target and target type/pattern-specific. scope, // This scope (no outer scopes). project, // This project (no outer projects). normal // All outer scopes. + + // Note that the search for target type/pattern-specific terminates at + // the project boundary. }; // variable @@ -119,6 +123,9 @@ namespace build2 inline bool operator== (const variable& x, const variable& y) {return x.name == y.name;} + inline ostream& + operator<< (ostream& os, const variable& v) {return os << v.name;} + // // class value @@ -697,8 +704,14 @@ namespace build2 struct variable_pool: private variable_pool_base { const variable& + insert (string name, variable_visibility v = variable_visibility::normal) + { + return insert (move (name), nullptr, v, false); + } + + const variable& insert (string name, - bool overridable = false, + bool overridable, variable_visibility v = variable_visibility::normal) { return insert (move (name), nullptr, v, overridable); @@ -706,8 +719,15 @@ namespace build2 template const variable& + insert (string name, variable_visibility v = variable_visibility::normal) + { + return insert (move (name), &value_traits::value_type, v, false); + } + + template + const variable& insert (string name, - bool overridable = false, + bool overridable, variable_visibility v = variable_visibility::normal) { return insert ( diff --git a/buildfile b/buildfile index 7e6d682..45bcdcc 100644 --- a/buildfile +++ b/buildfile @@ -11,4 +11,7 @@ file{INSTALL.cli config.guess config.sub manifest} include $d -doc{INSTALL*}: install = false +# Don't install tests or the INSTALL file. +# +dir{tests/}: install = false +doc{INSTALL}@./: install = false -- cgit v1.1