aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-05-08 13:21:55 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-05-09 15:37:47 +0200
commitb5d143f529e4ebbeb7a1746312e38da815e2e321 (patch)
tree2275a4619794874f7e8efea1735d46a1912313dc
parent00df206af5c80aba31bf7d180bdf03d617071e94 (diff)
Add --load-only option in addition to --match-only
This option has the effect of loading all the subdirectory buildfiles that are not explicitly included.
-rw-r--r--build2/b.cxx21
-rw-r--r--libbuild2/b-cmdline.cxx3
-rw-r--r--libbuild2/b-options.cxx24
-rw-r--r--libbuild2/b-options.hxx4
-rw-r--r--libbuild2/b-options.ixx6
-rw-r--r--libbuild2/b.cli17
-rw-r--r--libbuild2/context.cxx4
-rw-r--r--libbuild2/context.hxx16
-rw-r--r--libbuild2/dist/operation.cxx4
-rw-r--r--libbuild2/module.cxx2
-rw-r--r--libbuild2/rule.cxx18
11 files changed, 103 insertions, 16 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index 163a89e..72c49e9 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -416,10 +416,14 @@ main (int argc, char* argv[])
pctx = nullptr; // Free first to reuse memory.
}
+ optional<match_only_level> mo;
+ if (ops.load_only ()) mo = match_only_level::alias;
+ else if (ops.match_only ()) mo = match_only_level::all;
+
pctx.reset (new context (sched,
mutexes,
fcache,
- ops.match_only (),
+ mo,
ops.no_external_modules (),
ops.dry_run (),
ops.no_diag_buffer (),
@@ -479,6 +483,8 @@ main (int argc, char* argv[])
1100 /* variables */});
}
+ bool load_only (ops.load_only ());
+
const path& buildfile (ops.buildfile_specified ()
? ops.buildfile ()
: empty_path);
@@ -1409,6 +1415,9 @@ main (int argc, char* argv[])
break;
}
+ if (load_only && (mid != perform_id || oid != update_id))
+ fail << "--load-only requires perform(update) action";
+
// Now load the buildfiles and search the targets.
//
action_targets tgs;
@@ -1440,6 +1449,9 @@ main (int argc, char* argv[])
if (tt == nullptr)
fail (l) << "unknown target type " << tn.type;
+ if (load_only && !tt->is_a<alias> ())
+ fail << "--load-only requires alias target";
+
if (mif->search != nullptr)
{
// If the directory is relative, assume it is relative to work
@@ -1470,7 +1482,9 @@ main (int argc, char* argv[])
}
} // target
- if (dump_load)
+ // Delay until after match in the --load-only mode (see below).
+ //
+ if (dump_load && !load_only)
dump (ctx, nullopt /* action */);
// Finally, match the rules and perform the operation.
@@ -1610,6 +1624,9 @@ main (int argc, char* argv[])
<< ", id " << static_cast<uint16_t> (post_oid);});
}
+ if (dump_load && load_only)
+ dump (ctx, nullopt /* action */);
+
if (mif->operation_post != nullptr)
mif->operation_post (ctx, mparams, oid);
diff --git a/libbuild2/b-cmdline.cxx b/libbuild2/b-cmdline.cxx
index b7d0726..77ad087 100644
--- a/libbuild2/b-cmdline.cxx
+++ b/libbuild2/b-cmdline.cxx
@@ -418,6 +418,9 @@ namespace build2
if (ops.mtime_check () && ops.no_mtime_check ())
fail << "both --mtime-check and --no-mtime-check specified";
+
+ if (ops.match_only () && ops.load_only ())
+ fail << "both --match-only and --load-only specified";
}
catch (const cli::exception& e)
{
diff --git a/libbuild2/b-options.cxx b/libbuild2/b-options.cxx
index 0ff788e..251c709 100644
--- a/libbuild2/b-options.cxx
+++ b/libbuild2/b-options.cxx
@@ -354,6 +354,7 @@ namespace build2
dry_run_ (),
no_diag_buffer_ (),
match_only_ (),
+ load_only_ (),
no_external_modules_ (),
structured_result_ (),
structured_result_specified_ (false),
@@ -588,6 +589,12 @@ namespace build2
this->match_only_, a.match_only_);
}
+ if (a.load_only_)
+ {
+ ::build2::build::cli::parser< bool>::merge (
+ this->load_only_, a.load_only_);
+ }
+
if (a.no_external_modules_)
{
::build2::build::cli::parser< bool>::merge (
@@ -883,8 +890,18 @@ namespace build2
<< " lines and thus could be tolerable." << ::std::endl;
os << std::endl
- << "\033[1m--match-only\033[0m Match the rules but do not execute the operation. This" << ::std::endl
- << " mode is primarily useful for profiling." << ::std::endl;
+ << "\033[1m--match-only\033[0m Match the rules without executing the operation. This" << ::std::endl
+ << " mode is primarily useful for profiling and dumping the" << ::std::endl
+ << " build system state." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--load-only\033[0m Match the rules only to \033[1malias{}\033[0m targets ignoring other" << ::std::endl
+ << " targets and without executing the operation. In" << ::std::endl
+ << " particular, this has the effect of loading all the" << ::std::endl
+ << " subdirectory \033[1mbuildfiles\033[0m that are not explicitly" << ::std::endl
+ << " included. Note that this option can only be used with" << ::std::endl
+ << " the \033[1mperform(update)\033[0m action on an \033[1malias{}\033[0m target," << ::std::endl
+ << " usually \033[1mdir{}\033[0m." << ::std::endl;
os << std::endl
<< "\033[1m--no-external-modules\033[0m Don't load external modules during project bootstrap." << ::std::endl
@@ -991,6 +1008,7 @@ namespace build2
<< " the state after multiple phases/variants. By default" << ::std::endl
<< " the entire build state is dumped but this behavior can" << ::std::endl
<< " be altered with the \033[1m--dump-scope\033[0m and \033[1m--dump-target\033[0m" << ::std::endl
+ << " options. See also the \033[1m--match-only\033[0m and \033[1m--load-only\033[0m" << ::std::endl
<< " options." << ::std::endl;
os << std::endl
@@ -1191,6 +1209,8 @@ namespace build2
&::build2::build::cli::thunk< b_options, &b_options::no_diag_buffer_ >;
_cli_b_options_map_["--match-only"] =
&::build2::build::cli::thunk< b_options, &b_options::match_only_ >;
+ _cli_b_options_map_["--load-only"] =
+ &::build2::build::cli::thunk< b_options, &b_options::load_only_ >;
_cli_b_options_map_["--no-external-modules"] =
&::build2::build::cli::thunk< b_options, &b_options::no_external_modules_ >;
_cli_b_options_map_["--structured-result"] =
diff --git a/libbuild2/b-options.hxx b/libbuild2/b-options.hxx
index 37239ce..48dd35f 100644
--- a/libbuild2/b-options.hxx
+++ b/libbuild2/b-options.hxx
@@ -151,6 +151,9 @@ namespace build2
match_only () const;
const bool&
+ load_only () const;
+
+ const bool&
no_external_modules () const;
const structured_result_format&
@@ -304,6 +307,7 @@ namespace build2
bool dry_run_;
bool no_diag_buffer_;
bool match_only_;
+ bool load_only_;
bool no_external_modules_;
structured_result_format structured_result_;
bool structured_result_specified_;
diff --git a/libbuild2/b-options.ixx b/libbuild2/b-options.ixx
index 99e73d0..34b0d39 100644
--- a/libbuild2/b-options.ixx
+++ b/libbuild2/b-options.ixx
@@ -177,6 +177,12 @@ namespace build2
}
inline const bool& b_options::
+ load_only () const
+ {
+ return this->load_only_;
+ }
+
+ inline const bool& b_options::
no_external_modules () const
{
return this->no_external_modules_;
diff --git a/libbuild2/b.cli b/libbuild2/b.cli
index deb6a26..c9dfddd 100644
--- a/libbuild2/b.cli
+++ b/libbuild2/b.cli
@@ -663,8 +663,18 @@ namespace build2
bool --match-only
{
- "Match the rules but do not execute the operation. This mode is primarily
- useful for profiling."
+ "Match the rules without executing the operation. This mode is primarily
+ useful for profiling and dumping the build system state."
+ }
+
+ bool --load-only
+ {
+ "Match the rules only to \cb{alias{\}} targets ignoring other targets
+ and without executing the operation. In particular, this has the
+ effect of loading all the subdirectory \cb{buildfiles} that are not
+ explicitly included. Note that this option can only be used with the
+ \cb{perform(update)} action on an \cb{alias{\}} target, usually
+ \cb{dir{\}}."
}
bool --no-external-modules
@@ -782,7 +792,8 @@ namespace build2
pre/post-operations (\cb{match} dumps the main operation only). Repeat
this option to dump the state after multiple phases/variants. By
default the entire build state is dumped but this behavior can be
- altered with the \cb{--dump-scope} and \cb{--dump-target} options."
+ altered with the \cb{--dump-scope} and \cb{--dump-target} options.
+ See also the \cb{--match-only} and \cb{--load-only} options."
}
string --dump-format
diff --git a/libbuild2/context.cxx b/libbuild2/context.cxx
index afbb59a..3c101eb 100644
--- a/libbuild2/context.cxx
+++ b/libbuild2/context.cxx
@@ -290,7 +290,7 @@ namespace build2
context (scheduler& s,
global_mutexes& ms,
file_cache& fc,
- bool mo,
+ optional<match_only_level> mo,
bool nem,
bool dr,
bool ndb,
@@ -716,7 +716,7 @@ namespace build2
sched (nullptr),
mutexes (nullptr),
fcache (nullptr),
- match_only (false),
+ match_only (nullopt),
no_external_modules (true),
dry_run_option (false),
no_diag_buffer (false),
diff --git a/libbuild2/context.hxx b/libbuild2/context.hxx
index b0fac02..7574787 100644
--- a/libbuild2/context.hxx
+++ b/libbuild2/context.hxx
@@ -120,6 +120,16 @@ namespace build2
}
};
+ // Match-only level.
+ //
+ // See the --match-only and --load-only options for background.
+ //
+ enum class match_only_level
+ {
+ alias, // Match only alias{} targets.
+ all // Match all targets.
+ };
+
// A build context encapsulates the state of a build. It is possible to have
// multiple build contexts provided they are non-overlapping, that is, they
// don't try to build the same projects (note that this is currently not
@@ -217,9 +227,9 @@ namespace build2
global_mutexes* mutexes;
file_cache* fcache;
- // Match only flag (see --match-only but also dist).
+ // Match only flag/level (see --{load,match}-only but also dist).
//
- bool match_only;
+ optional<match_only_level> match_only;
// Skip booting external modules flag (see --no-external-modules).
//
@@ -689,7 +699,7 @@ namespace build2
context (scheduler&,
global_mutexes&,
file_cache&,
- bool match_only = false,
+ optional<match_only_level> match_only = nullopt,
bool no_external_modules = false,
bool dry_run = false,
bool no_diag_buffer = false,
diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx
index 45b1688..6dcc88a 100644
--- a/libbuild2/dist/operation.cxx
+++ b/libbuild2/dist/operation.cxx
@@ -302,8 +302,8 @@ namespace build2
}
};
- auto mog = make_guard ([&ctx] () {ctx.match_only = false;});
- ctx.match_only = true;
+ auto mog = make_guard ([&ctx] () {ctx.match_only = nullopt;});
+ ctx.match_only = match_only_level::all;
const operations& ops (rs.root_extra->operations);
for (operations::size_type id (default_id + 1); // Skip default_id.
diff --git a/libbuild2/module.cxx b/libbuild2/module.cxx
index dd83225..1aaa38d 100644
--- a/libbuild2/module.cxx
+++ b/libbuild2/module.cxx
@@ -83,7 +83,7 @@ namespace build2
new context (*ctx.sched,
*ctx.mutexes,
*ctx.fcache,
- false, /* match_only */
+ nullopt, /* match_only */
false, /* no_external_modules */
false, /* dry_run */
ctx.no_diag_buffer,
diff --git a/libbuild2/rule.cxx b/libbuild2/rule.cxx
index 5d456d5..0b401c2 100644
--- a/libbuild2/rule.cxx
+++ b/libbuild2/rule.cxx
@@ -219,7 +219,23 @@ namespace build2
//
inject_fsdir (a, t, true, false);
- match_prerequisites (a, t);
+ // Handle the alias match-only level.
+ //
+ match_search ms;
+ if (t.ctx.match_only && *t.ctx.match_only == match_only_level::alias)
+ {
+ ms = [] (action,
+ const target& t,
+ const prerequisite& p,
+ include_type i)
+ {
+ return prerequisite_target (
+ p.is_a<alias> () ? &search (t, p) : nullptr,
+ i);
+ };
+ }
+
+ match_prerequisites (a, t, ms);
return default_recipe;
}