aboutsummaryrefslogtreecommitdiff
path: root/build2/cc/link-rule.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-06-28 09:44:15 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-06-28 09:44:15 +0200
commit3cc5e3bd441fc9d18fece3d9e99fae75c78438e7 (patch)
treea9a08c453370847e0d352d47e19fbfcb7cc757ef /build2/cc/link-rule.cxx
parentc0f72d47fc25981dcc1f55e12dfa0fdba7b70242 (diff)
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
Diffstat (limited to 'build2/cc/link-rule.cxx')
-rw-r--r--build2/cc/link-rule.cxx50
1 files changed, 37 insertions, 13 deletions
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));