From b5d143f529e4ebbeb7a1746312e38da815e2e321 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 8 May 2023 13:21:55 +0200 Subject: 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. --- libbuild2/b-cmdline.cxx | 3 +++ libbuild2/b-options.cxx | 24 ++++++++++++++++++++++-- libbuild2/b-options.hxx | 4 ++++ libbuild2/b-options.ixx | 6 ++++++ libbuild2/b.cli | 17 ++++++++++++++--- libbuild2/context.cxx | 4 ++-- libbuild2/context.hxx | 16 +++++++++++++--- libbuild2/dist/operation.cxx | 4 ++-- libbuild2/module.cxx | 2 +- libbuild2/rule.cxx | 18 +++++++++++++++++- 10 files changed, 84 insertions(+), 14 deletions(-) (limited to 'libbuild2') 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 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; // 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 = 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 () ? &search (t, p) : nullptr, + i); + }; + } + + match_prerequisites (a, t, ms); return default_recipe; } -- cgit v1.1