aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/build
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-05-23 09:23:16 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-05-29 10:21:12 +0200
commite05f7c7383cc48823bd408c0bc5187191a9a1c48 (patch)
tree024bb9c3be9c876b8822388baf1622cad03d7563 /libbuild2/build
parent349b34108752e2fcf1ead648ffec8e5acfe4a91c (diff)
Explicit group: static members
Diffstat (limited to 'libbuild2/build')
-rw-r--r--libbuild2/build/script/parser.cxx20
-rw-r--r--libbuild2/build/script/parser.hxx18
-rw-r--r--libbuild2/build/script/runner.cxx27
-rw-r--r--libbuild2/build/script/script.cxx24
4 files changed, 65 insertions, 24 deletions
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx
index e7268f9..c71f218 100644
--- a/libbuild2/build/script/parser.cxx
+++ b/libbuild2/build/script/parser.cxx
@@ -61,7 +61,7 @@ namespace build2
pbase_ = scope_->src_path_;
- file_based_ = tt.is_a<file> ();
+ file_based_ = tt.is_a<file> () || tt.is_a<group> ();
perform_update_ = find (as.begin (), as.end (), perform_update_id) !=
as.end ();
@@ -748,8 +748,8 @@ namespace build2
}
if (!file_based_)
- fail (l) << "'depdb' builtin can only be used for file-based "
- << "targets";
+ fail (l) << "'depdb' builtin can only be used for file- or "
+ << "file group-based targets";
if (!diag_preamble_.empty ())
fail (diag_loc ()) << "'diag' builtin call before 'depdb' call" <<
@@ -1287,7 +1287,7 @@ namespace build2
}
void parser::
- exec_depdb_preamble (action a, const scope& bs, const file& t,
+ exec_depdb_preamble (action a, const scope& bs, const target& t,
environment& e, const script& s, runner& r,
lines_iterator begin, lines_iterator end,
depdb& dd,
@@ -1314,7 +1314,7 @@ namespace build2
action a;
const scope& bs;
- const file& t;
+ const target& t;
environment& env;
const script& scr;
@@ -1360,7 +1360,7 @@ namespace build2
//
exec_depdb_dyndep (t, tt,
li, ll,
- data.a, data.bs, const_cast<file&> (data.t),
+ data.a, data.bs, const_cast<target&> (data.t),
data.dd,
*data.dyn_targets,
*data.update,
@@ -1645,7 +1645,7 @@ namespace build2
void parser::
exec_depdb_dyndep (token& lt, build2::script::token_type& ltt,
size_t li, const location& ll,
- action a, const scope& bs, file& t,
+ action a, const scope& bs, target& t,
depdb& dd,
paths& dyn_targets,
bool& update,
@@ -2455,6 +2455,8 @@ namespace build2
//
if (ops.drop_cycles ())
{
+ // @@ TODO: expl
+
for (const target* m (&t); m != nullptr; m = m->adhoc_member)
{
if (ft == m)
@@ -2874,7 +2876,7 @@ namespace build2
// that there are only real targets to start with.
//
optional<vector<const target*>> dts;
- for (const target* m (&t); m != nullptr; m = m->adhoc_member)
+ for (const target* m (&t); m != nullptr; m = m->adhoc_member) // @@ TODO: expl
{
if (m->decl != target_decl::real)
dts = vector<const target*> ();
@@ -2914,7 +2916,7 @@ namespace build2
//
if (dts)
{
- for (target* p (&t); p->adhoc_member != nullptr; )
+ for (target* p (&t); p->adhoc_member != nullptr; ) // @@ TODO: expl
{
target* m (p->adhoc_member);
diff --git a/libbuild2/build/script/parser.hxx b/libbuild2/build/script/parser.hxx
index b615a90..856ad64 100644
--- a/libbuild2/build/script/parser.hxx
+++ b/libbuild2/build/script/parser.hxx
@@ -103,8 +103,10 @@ namespace build2
// runner's enter() function is called before the first preamble/body
// command execution and leave() -- after the last command.
//
+ // Note: target must be file or group.
+ //
void
- execute_depdb_preamble (action a, const scope& base, const file& t,
+ execute_depdb_preamble (action a, const scope& base, const target& t,
environment& e, const script& s, runner& r,
depdb& dd)
{
@@ -219,8 +221,10 @@ namespace build2
names
exec_special (token&, build2::script::token_type&, bool skip_first);
+ // Note: target must be file or group.
+ //
void
- exec_depdb_preamble (action, const scope& base, const file&,
+ exec_depdb_preamble (action, const scope& base, const target&,
environment&, const script&, runner&,
lines_iterator begin, lines_iterator end,
depdb&,
@@ -230,10 +234,12 @@ namespace build2
bool* deferred_failure = nullptr,
dyndep_byproduct* = nullptr);
+ // Note: target must be file or group.
+ //
void
exec_depdb_dyndep (token&, build2::script::token_type&,
size_t line_index, const location&,
- action, const scope& base, file&,
+ action, const scope& base, target&,
depdb&,
paths& dyn_targets,
bool& update,
@@ -276,9 +282,9 @@ namespace build2
script* script_;
const small_vector<action, 1>* actions_; // Non-NULL during pre-parse.
- // True if this script is for file-based targets and performing update
- // is one of the actions, respectively. Only set for the pre-parse
- // mode.
+ // True if this script is for file- or file group-based targets and
+ // performing update is one of the actions, respectively. Only set for
+ // the pre-parse mode.
//
bool file_based_;
bool perform_update_;
diff --git a/libbuild2/build/script/runner.cxx b/libbuild2/build/script/runner.cxx
index c52ef66..e08ebbf 100644
--- a/libbuild2/build/script/runner.cxx
+++ b/libbuild2/build/script/runner.cxx
@@ -28,12 +28,29 @@ namespace build2
//
for (auto i (env.cleanups.begin ()); i != env.cleanups.end (); )
{
- const target* m (&env.target);
- for (; m != nullptr; m = m->adhoc_member)
+ const target* m (nullptr);
+ if (const group* g = env.target.is_a<group> ())
{
- if (const path_target* pm = m->is_a<path_target> ())
- if (i->path == pm->path ())
- break;
+ for (const target* gm: g->members)
+ {
+ if (const path_target* pm = gm->is_a<path_target> ())
+ {
+ if (i->path == pm->path ())
+ {
+ m = gm;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (m = &env.target; m != nullptr; m = m->adhoc_member)
+ {
+ if (const path_target* pm = m->is_a<path_target> ())
+ if (i->path == pm->path ())
+ break;
+ }
}
if (m != nullptr)
diff --git a/libbuild2/build/script/script.cxx b/libbuild2/build/script/script.cxx
index 9d9b5a8..0f31e7f 100644
--- a/libbuild2/build/script/script.cxx
+++ b/libbuild2/build/script/script.cxx
@@ -58,11 +58,27 @@ namespace build2
{
// $>
//
+ // What should it contain for an explicit group? While it may seem
+ // that just the members should be enough (and analogous to the ad
+ // hoc case), this won't let us get the group name for diagnostics.
+ // So the group name followed by all the members seems like the
+ // logical choice.
+ //
names ns;
- for (const target_type* m (&target);
- m != nullptr;
- m = m->adhoc_member)
- m->as_name (ns);
+
+ if (const group* g = target.is_a<group> ())
+ {
+ g->as_name (ns);
+ for (const target_type* m: g->members)
+ m->as_name (ns);
+ }
+ else
+ {
+ for (const target_type* m (&target);
+ m != nullptr;
+ m = m->adhoc_member)
+ m->as_name (ns);
+ }
assign (var_ts) = move (ns);
}