diff options
-rw-r--r-- | libbuild2/adhoc-rule-regex-pattern.cxx | 3 | ||||
-rw-r--r-- | libbuild2/algorithm.hxx | 16 | ||||
-rw-r--r-- | libbuild2/context.hxx | 12 | ||||
-rw-r--r-- | libbuild2/operation.hxx | 4 | ||||
-rw-r--r-- | libbuild2/target.cxx | 33 | ||||
-rw-r--r-- | libbuild2/target.hxx | 8 | ||||
-rw-r--r-- | libbuild2/target.ixx | 20 |
7 files changed, 59 insertions, 37 deletions
diff --git a/libbuild2/adhoc-rule-regex-pattern.cxx b/libbuild2/adhoc-rule-regex-pattern.cxx index c621b67..9550527 100644 --- a/libbuild2/adhoc-rule-regex-pattern.cxx +++ b/libbuild2/adhoc-rule-regex-pattern.cxx @@ -405,7 +405,8 @@ namespace build2 continue; // @@ TODO: it could be handy to mark a prerequisite (e.g., a tool) - // ad hoc so that it doesn't interfere with the $< list. + // ad hoc so that it doesn't interfere with the $< list. Also + // clean=false. // pts.push_back (prerequisite_target (&pt, false /* adhoc */)); } diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx index 984b786..73705d8 100644 --- a/libbuild2/algorithm.hxx +++ b/libbuild2/algorithm.hxx @@ -375,6 +375,18 @@ namespace build2 // the target is a member of a group, then first do this to the group's // prerequisites. // + // Regarding clean, it may seem more natural to only clean prerequisites + // that are in the same base rather than root scope. While it's often true + // for simple projects, in more complex cases it's not unusual to have + // common intermediate build results (object files, utility libraries, etc) + // reside in the parent and/or sibling directories. With such arrangements, + // cleaning only in base (even from the project root) may leave such + // intermediate build results laying around (since there is no reason to + // list them as prerequisites of any directory aliases). So we clean in the + // root scope by default but any target-prerequisite relationship can be + // marked not to trigger a clean with the clean=false prerequisite-specific + // value (see the include variable for details). + // using match_search = function< prerequisite_target (action, const target&, @@ -386,8 +398,8 @@ namespace build2 // As above but go into group members. // - // Note that if we cleaning, this function doesn't go into group members, as - // an optimization (the group should clean everything up). + // Note that if we are cleaning, this function doesn't go into group + // members, as an optimization (the group should clean everything up). // using match_search_member = function< prerequisite_target (action, diff --git a/libbuild2/context.hxx b/libbuild2/context.hxx index c93c1c9..7ac4af4 100644 --- a/libbuild2/context.hxx +++ b/libbuild2/context.hxx @@ -411,6 +411,9 @@ namespace build2 // const variable* var_extension; + // Note that this variable can also be specified as prerequisite-specific + // (see the `include` variable for details). + // // [bool] target visibility // const variable* var_clean; @@ -450,6 +453,15 @@ namespace build2 // A rule with the "pass-through" semantics should treat the adhoc value // the same as true. // + // Sometimes it may be desirable to apply exclusions only to specific + // operations. The initial idea was to extend this value to allow + // specifying the operation (e.g., clean@false). However, later we + // realized that we could reuse the "operation variables" (clean, install, + // test) with a more natural-looking result. Note that currently we only + // recognize the built-in clean variable (for other variables we will need + // some kind of registration in an operation-to-variable map, probably in + // root scope). + // // To query this value in rule implementations use the include() helpers // from <libbuild2/prerequisites.hxx>. // diff --git a/libbuild2/operation.hxx b/libbuild2/operation.hxx index de3ae7c..e115ac0 100644 --- a/libbuild2/operation.hxx +++ b/libbuild2/operation.hxx @@ -124,8 +124,8 @@ namespace build2 void (*operation_post) (const values&, operation_id); void (*meta_operation_post) (const values&); - // Optional prerequisite inclusion/exclusion override callback. See - // include() for details. + // Optional prerequisite exclusion override callback. See include() for + // details. Note that it's not called for include_type::normal; // include_type (*include) (action, const target&, diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx index 7db5c66..bc5dbba 100644 --- a/libbuild2/target.cxx +++ b/libbuild2/target.cxx @@ -544,25 +544,38 @@ namespace build2 include_type include_impl (action a, const target& t, - const string& v, const prerequisite& p, const target* m) { context& ctx (t.ctx); - include_type r (false); + include_type r (include_type::normal); - if (v == "false") r = include_type::excluded; - else if (v == "adhoc") r = include_type::adhoc; - else if (v == "true") r = include_type::normal; - else - fail << "invalid " << ctx.var_include->name << " variable value " - << "'" << v << "' specified for prerequisite " << p; + // If var_clean is defined, then it takes precedence over include for + // the clean operation. + // + lookup l; + if (a.operation () == clean_id && (l = p.vars[ctx.var_clean])) + { + r = cast<bool> (l) ? include_type::normal : include_type::excluded; + } + else if (const string* v = cast_null<string> (p.vars[ctx.var_include])) + { + if (*v == "false") r = include_type::excluded; + else if (*v == "adhoc") r = include_type::adhoc; + else if (*v == "true") r = include_type::normal; + else + fail << "invalid " << ctx.var_include->name << " variable value " + << "'" << *v << "' specified for prerequisite " << p; + } // Call the meta-operation override, if any (currently used by dist). // - if (auto f = ctx.current_mif->include) - r = f (a, t, prerequisite_member {p, m}, r); + if (r != include_type::normal) + { + if (auto f = ctx.current_mif->include) + r = f (a, t, prerequisite_member {p, m}, r); + } return r; } diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx index 8193f35..a5940ab 100644 --- a/libbuild2/target.hxx +++ b/libbuild2/target.hxx @@ -874,15 +874,11 @@ namespace build2 uint8_t unmark (const target*&); - // Helper for dealing with the prerequisite inclusion/exclusion (the - // 'include' buildfile variable, see var_include in context.hxx). + // Helper for dealing with the prerequisite inclusion/exclusion (see + // var_include in context.hxx). // // Note that the include(prerequisite_member) overload is also provided. // - // @@ Maybe this filtering should be incorporated into *_prerequisites() and - // *_prerequisite_members() logic? Could make normal > adhoc > excluded and - // then pass the "threshold". - // include_type include (action, const target&, diff --git a/libbuild2/target.ixx b/libbuild2/target.ixx index 1c8dd8d..50750ca 100644 --- a/libbuild2/target.ixx +++ b/libbuild2/target.ixx @@ -287,27 +287,15 @@ namespace build2 // include() // LIBBUILD2_SYMEXPORT include_type - include_impl (action, - const target&, - const string&, - const prerequisite&, - const target*); + include_impl (action, const target&, const prerequisite&, const target*); inline include_type include (action a, const target& t, const prerequisite& p, const target* m) { - // Most of the time this variable will not be specified, so let's optimize - // for that. + // Most of the time no prerequisite-specific variables will be specified, + // so let's optimize for that. // - if (p.vars.empty ()) - return true; - - const string* v (cast_null<string> (p.vars[t.ctx.var_include])); - - if (v == nullptr) - return true; - - return include_impl (a, t, *v, p, m); + return p.vars.empty () ? include_type (true) : include_impl (a, t, p, m); } // group_prerequisites |