aboutsummaryrefslogtreecommitdiff
path: root/build2/cc
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
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')
-rw-r--r--build2/cc/common.cxx5
-rw-r--r--build2/cc/compile-rule.cxx48
-rw-r--r--build2/cc/install-rule.cxx2
-rw-r--r--build2/cc/link-rule.cxx50
-rw-r--r--build2/cc/windows-rpath.cxx4
5 files changed, 85 insertions, 24 deletions
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<libx> ())
@@ -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<libx> ())
@@ -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<libx> () ||
- p.is_a<liba> () ||
- p.is_a<libs> () ||
- p.is_a<libux> ())
+ if (pi == include_type::normal &&
+ (p.is_a<libx> () ||
+ p.is_a<liba> () ||
+ p.is_a<libs> () ||
+ p.is_a<libux> ()))
{
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<bmi> () || p.is_a (tt.bmi))
+ else if (pi == include_type::normal &&
+ (p.is_a<bmi> () || 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<exe> () || t.is_a<libs> ()); // 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;