From 3cc5e3bd441fc9d18fece3d9e99fae75c78438e7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 28 Jun 2018 09:44:15 +0200 Subject: Implement support for excluded and ad hoc prerequisites The inclusion/exclusion is controlled via the 'include' prerequisite-specific variable. Valid values are: false - exclude true - include adhoc - include but treat as an ad hoc input For example: lib{foo}: cxx{win32-utility}: include = ($cxx.targe.class == 'windows') exe{bar}: libs{plugin}: include = adhoc --- build2/cc/common.cxx | 5 ++++- build2/cc/compile-rule.cxx | 48 +++++++++++++++++++++++++++++++++++-------- build2/cc/install-rule.cxx | 2 ++ build2/cc/link-rule.cxx | 50 +++++++++++++++++++++++++++++++++------------ build2/cc/windows-rpath.cxx | 4 ++-- 5 files changed, 85 insertions(+), 24 deletions(-) (limited to 'build2/cc') diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx index 0778acf..3c4994e 100644 --- a/build2/cc/common.cxx +++ b/build2/cc/common.cxx @@ -224,7 +224,10 @@ namespace build2 { for (const prerequisite_target& pt: l.prerequisite_targets[a]) { - if (pt == nullptr) + // Note: adhoc prerequisites are not part of the library meta- + // information protocol. + // + if (pt == nullptr || pt.adhoc) continue; bool la; diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx index 079be88..61d5984 100644 --- a/build2/cc/compile-rule.cxx +++ b/build2/cc/compile-rule.cxx @@ -237,6 +237,11 @@ namespace build2 // for (prerequisite_member p: reverse_group_prerequisite_members (a, t)) { + // If excluded or ad hoc, then don't factor it into our tests. + // + if (include (a, t, p) != include_type::normal) + continue; + if (p.is_a (mod ? *x_mod : x_src)) { // Save in the target's auxiliary storage. Translation type will @@ -292,6 +297,9 @@ namespace build2 for (prerequisite_member p: group_prerequisite_members (a, t)) { + if (include (a, t, p) != include_type::normal) // Excluded/ad hoc. + continue; + // Should be already searched and matched for libraries. // if (const target* pt = p.load ()) @@ -342,6 +350,9 @@ namespace build2 for (prerequisite_member p: group_prerequisite_members (a, t)) { + if (include (a, t, p) != include_type::normal) // Excluded/ad hoc. + continue; + if (const target* pt = p.load ()) { if (const libx* l = pt->is_a ()) @@ -393,6 +404,9 @@ namespace build2 for (prerequisite_member p: group_prerequisite_members (a, t)) { + if (include (a, t, p) != include_type::normal) // Excluded/ad hoc. + continue; + if (const target* pt = p.load ()) { if (const libx* l = pt->is_a ()) @@ -599,15 +613,20 @@ namespace build2 for (prerequisite_member p: group_prerequisite_members (a, t)) { const target* pt (nullptr); + include_type pi (include (a, t, p)); + + if (!pi) + continue; // A dependency on a library is there so that we can get its - // *.export.poptions, modules, etc. This is the "library - // meta-information protocol". See also append_lib_options(). + // *.export.poptions, modules, etc. This is the library + // meta-information protocol. See also append_lib_options(). // - if (p.is_a () || - p.is_a () || - p.is_a () || - p.is_a ()) + if (pi == include_type::normal && + (p.is_a () || + p.is_a () || + p.is_a () || + p.is_a ())) { if (a.operation () == update_id) { @@ -638,7 +657,8 @@ namespace build2 // else (normally library/executable) also depends on it and will // clean it up. // - else if (p.is_a () || p.is_a (tt.bmi)) + else if (pi == include_type::normal && + (p.is_a () || p.is_a (tt.bmi))) continue; else { @@ -649,7 +669,7 @@ namespace build2 } match_async (a, *pt, target::count_busy (), t[a].task_count); - pts.push_back (pt); + pts.push_back (prerequisite_target (pt, pi)); } wg.wait (); @@ -3529,6 +3549,9 @@ namespace build2 for (prerequisite_member p: group_prerequisite_members (a, t)) { + if (include (a, t, p) != include_type::normal) // Excluded/ad hoc. + continue; + const target* pt (p.load ()); // Should be cached for libraries. if (pt != nullptr) @@ -3625,6 +3648,9 @@ namespace build2 for (prerequisite_member p: prerequisite_members (a, t, group_prerequisites (*pt, pg))) { + if (include (a, t, p) != include_type::normal) // Excluded/ad hoc. + continue; + if (p.is_a (*x_mod)) { // Check for an explicit module name. Only look for an existing @@ -3739,6 +3765,9 @@ namespace build2 // for (prerequisite_member p: group_prerequisite_members (a, *bt)) { + if (include (a, t, p) != include_type::normal) // Excluded/ad hoc. + continue; + if (p.is_a (*x_mod)) // Got to be there. { fail (relative (src)) @@ -3961,6 +3990,9 @@ namespace build2 ps.push_back (prerequisite (lt)); for (prerequisite_member p: group_prerequisite_members (a, lt)) { + if (include (a, lt, p) != include_type::normal) // Excluded/ad hoc. + continue; + // @@ TODO: will probably need revision if using sidebuild for // non-installed libraries (e.g., direct BMI dependencies // will probably have to be translated to mxx{} or some such). diff --git a/build2/cc/install-rule.cxx b/build2/cc/install-rule.cxx index a7e05b0..ee290e3 100644 --- a/build2/cc/install-rule.cxx +++ b/build2/cc/install-rule.cxx @@ -41,6 +41,8 @@ namespace build2 // Note: for now we assume these prerequisites never come from see- // through groups. // + // Note: we install ad hoc prerequisites by default. + // otype ot (link_type (t).type); bool st (t.is_a () || t.is_a ()); // Target needs shared. diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx index e4f176a..154cadb 100644 --- a/build2/cc/link-rule.cxx +++ b/build2/cc/link-rule.cxx @@ -77,6 +77,11 @@ namespace build2 for (prerequisite_member p: group_prerequisite_members (a, t)) { + // If excluded or ad hoc, then don't factor it into our tests. + // + if (include (a, t, p) != include_type::normal) + continue; + if (p.is_a (x_src) || (x_mod != nullptr && p.is_a (*x_mod))) { seen_x = seen_x || true; @@ -562,12 +567,17 @@ namespace build2 for (prerequisite_member p: group_prerequisite_members (a, t)) { + include_type pi (include (a, t, p)); + // We pre-allocate a NULL slot for each (potential; see clean) // prerequisite target. // - pts.push_back (nullptr); + pts.push_back (prerequisite_target (nullptr, pi)); const target*& pt (pts.back ()); + if (pi != include_type::normal) // Skip excluded and ad hoc. + continue; + // Mark: // 0 - lib // 1 - src @@ -699,8 +709,8 @@ namespace build2 // for update. This allows operations like test and install to // skip such tacked on stuff. // - // @@ This is broken since, for example, update for install will - // ignore ad hoc inputs. + // Note that ad hoc inputs have to be explicitly marked with the + // include=adhoc prerequisite-specific variable. // if (current_outer_oif != nullptr) continue; @@ -730,9 +740,9 @@ namespace build2 // bmi{} targets we haven't completed yet. Hairy, I know. // - // Parallel prerequisite_targets loop. + // Parallel prerequisites/prerequisite_targets loop. // - size_t i (start), n (pts.size ()); + size_t i (start); for (prerequisite_member p: group_prerequisite_members (a, t)) { const target*& pt (pts[i].target); @@ -807,7 +817,7 @@ namespace build2 { const target* pt (pts[j++]); - if (pt == nullptr) + if (pt == nullptr) // Note: ad hoc is taken care of. continue; // NOTE: pt may be marked (even for a library -- see clean @@ -945,14 +955,25 @@ namespace build2 // wait_guard wg (target::count_busy (), t[a].task_count, true); - for (i = start; i != n; ++i) + i = start; + for (prerequisite_member p: group_prerequisite_members (a, t)) { - const target*& pt (pts[i]); + bool adhoc (pts[i].adhoc); + const target*& pt (pts[i++]); + + uint8_t m; if (pt == nullptr) - continue; + { + // Handle ad hoc prerequisities. + // + if (!adhoc) + continue; - if (uint8_t m = unmark (pt)) + pt = &p.search (t); + m = 1; // Mark for completion. + } + else if ((m = unmark (pt)) != 0) { // If this is a library not to be cleaned, we can finally blank it // out. @@ -962,10 +983,10 @@ namespace build2 pt = nullptr; continue; } - - match_async (a, *pt, target::count_busy (), t[a].task_count); - mark (pt, m); } + + match_async (a, *pt, target::count_busy (), t[a].task_count); + mark (pt, m); } wg.wait (); @@ -1342,6 +1363,9 @@ namespace build2 // Update prerequisites. We determine if any relevant ones render us // out-of-date manually below. // + // Note that straight_execute_prerequisites() will blank out all the ad + // hoc prerequisites so we don't need to worry about them from now on. + // bool update (false); timestamp mt (t.load_mtime ()); target_state ts (straight_execute_prerequisites (a, t)); diff --git a/build2/cc/windows-rpath.cxx b/build2/cc/windows-rpath.cxx index ee75b12..c710e66 100644 --- a/build2/cc/windows-rpath.cxx +++ b/build2/cc/windows-rpath.cxx @@ -105,7 +105,7 @@ namespace build2 for (const prerequisite_target& pt: t.prerequisite_targets[a]) { - if (pt == nullptr) + if (pt == nullptr || pt.adhoc) continue; bool la; @@ -195,7 +195,7 @@ namespace build2 for (const prerequisite_target& pt: t.prerequisite_targets[a]) { - if (pt == nullptr) + if (pt == nullptr || pt.adhoc) continue; bool la; -- cgit v1.1