aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/build
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-05-30 07:12:30 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-05-30 11:23:09 +0200
commitb4c8dc71b6f2c9d8bd63591b3e9a1c6bc329c240 (patch)
treed41e8c43c0391cbed7377a99609d6182ab3d5676 /libbuild2/build
parentde2daaa41ec6064181e6b9e73a34c32cd0008242 (diff)
Add depdb-dyndep --target-extension-type option
This allows specifying custom extension to target type mapping.
Diffstat (limited to 'libbuild2/build')
-rw-r--r--libbuild2/build/script/builtin-options.cxx5
-rw-r--r--libbuild2/build/script/builtin-options.hxx17
-rw-r--r--libbuild2/build/script/builtin-options.ixx30
-rw-r--r--libbuild2/build/script/builtin.cli18
-rw-r--r--libbuild2/build/script/parser.cxx61
5 files changed, 122 insertions, 9 deletions
diff --git a/libbuild2/build/script/builtin-options.cxx b/libbuild2/build/script/builtin-options.cxx
index 3b64de1..dba3c59 100644
--- a/libbuild2/build/script/builtin-options.cxx
+++ b/libbuild2/build/script/builtin-options.cxx
@@ -294,6 +294,8 @@ namespace build2
target_what_specified_ (false),
target_default_type_ (),
target_default_type_specified_ (false),
+ target_extension_type_ (),
+ target_extension_type_specified_ (false),
target_cwd_ (),
target_cwd_specified_ (false)
{
@@ -403,6 +405,9 @@ namespace build2
_cli_depdb_dyndep_options_map_["--target-default-type"] =
&::build2::build::cli::thunk< depdb_dyndep_options, string, &depdb_dyndep_options::target_default_type_,
&depdb_dyndep_options::target_default_type_specified_ >;
+ _cli_depdb_dyndep_options_map_["--target-extension-type"] =
+ &::build2::build::cli::thunk< depdb_dyndep_options, map<string, string>, &depdb_dyndep_options::target_extension_type_,
+ &depdb_dyndep_options::target_extension_type_specified_ >;
_cli_depdb_dyndep_options_map_["--target-cwd"] =
&::build2::build::cli::thunk< depdb_dyndep_options, dir_path, &depdb_dyndep_options::target_cwd_,
&depdb_dyndep_options::target_cwd_specified_ >;
diff --git a/libbuild2/build/script/builtin-options.hxx b/libbuild2/build/script/builtin-options.hxx
index 2a00072..a8c3440 100644
--- a/libbuild2/build/script/builtin-options.hxx
+++ b/libbuild2/build/script/builtin-options.hxx
@@ -204,6 +204,21 @@ namespace build2
void
target_default_type_specified (bool);
+ const map<string, string>&
+ target_extension_type () const;
+
+ map<string, string>&
+ target_extension_type ();
+
+ void
+ target_extension_type (const map<string, string>&);
+
+ bool
+ target_extension_type_specified () const;
+
+ void
+ target_extension_type_specified (bool);
+
const dir_path&
target_cwd () const;
@@ -250,6 +265,8 @@ namespace build2
bool target_what_specified_;
string target_default_type_;
bool target_default_type_specified_;
+ map<string, string> target_extension_type_;
+ bool target_extension_type_specified_;
dir_path target_cwd_;
bool target_cwd_specified_;
};
diff --git a/libbuild2/build/script/builtin-options.ixx b/libbuild2/build/script/builtin-options.ixx
index 3e3787f..20847c2 100644
--- a/libbuild2/build/script/builtin-options.ixx
+++ b/libbuild2/build/script/builtin-options.ixx
@@ -294,6 +294,36 @@ namespace build2
this->target_default_type_specified_ = x;
}
+ inline const map<string, string>& depdb_dyndep_options::
+ target_extension_type () const
+ {
+ return this->target_extension_type_;
+ }
+
+ inline map<string, string>& depdb_dyndep_options::
+ target_extension_type ()
+ {
+ return this->target_extension_type_;
+ }
+
+ inline void depdb_dyndep_options::
+ target_extension_type (const map<string, string>& x)
+ {
+ this->target_extension_type_ = x;
+ }
+
+ inline bool depdb_dyndep_options::
+ target_extension_type_specified () const
+ {
+ return this->target_extension_type_specified_;
+ }
+
+ inline void depdb_dyndep_options::
+ target_extension_type_specified (bool x)
+ {
+ this->target_extension_type_specified_ = x;
+ }
+
inline const dir_path& depdb_dyndep_options::
target_cwd () const
{
diff --git a/libbuild2/build/script/builtin.cli b/libbuild2/build/script/builtin.cli
index cf1540d..6d6369b 100644
--- a/libbuild2/build/script/builtin.cli
+++ b/libbuild2/build/script/builtin.cli
@@ -76,8 +76,8 @@ namespace build2
dir_paths --include-path|-I; // Search paths for generated
// prerequisites.
- string --default-type; // Default prerequisite type to use
- // if none could be derived from ext.
+ string --default-type; // Default prerequisite type to use if
+ // none could be derived from extension.
bool --adhoc; // Treat dynamically discovered
// prerequisites as ad hoc (so they
@@ -103,15 +103,17 @@ namespace build2
// ad hoc group members (unless already specified as static members).
// This functionality is not available in the byproduct mode.
//
- // @@ BTW, here what would likely be more useful than default target
- // is the ability to specify custom extension-to-type mapping in
- // order to resolve ambiguities. See also the issue with getting
- // these options during clean.
- //
string --target-what; // Target kind, e.g., "source".
string --target-default-type; // Default target type to use if none
- // could be derived from ext.
+ // could be derived from extension.
+
+ map<string, string> // Extension to target type mapping in
+ --target-extension-type; // the <ext>=<type> form, for example,
+ // h=hxx. This mapping is considered
+ // before attempting to automatically
+ // map the extension and so can be used
+ // to resolve ambiguities.
dir_path --target-cwd; // Builtin's working directory used to
// complete relative paths of targets.
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx
index 3814305..9965799 100644
--- a/libbuild2/build/script/parser.cxx
+++ b/libbuild2/build/script/parser.cxx
@@ -2087,6 +2087,23 @@ namespace build2
<< "' specified with --target-default-type";
}
+ map<string, const target_type*> map_tt;
+ if (ops.target_extension_type_specified ())
+ {
+ if (!dyn_tgt)
+ fail (ll) << "depdb dyndep: --target-extension-type specified "
+ << "without --dyn-target";
+
+ for (pair<const string, string>& p: ops.target_extension_type ())
+ {
+ const target_type* tt (bs.find_target_type (p.second));
+ if (tt == nullptr)
+ fail (ll) << "depdb dyndep: unknown target type '" << p.second
+ << "' specified with --target-extension-type";
+
+ map_tt[p.first] = tt;
+ }
+ }
// --file (last since need --*cwd)
//
@@ -2256,7 +2273,6 @@ namespace build2
[] (const scope& bs, const string& n, const string& e)
{
// NOTE: another version in adhoc_buildscript_rule::apply().
- // NOTE: now also used for dynamic targets below!
// @@ TODO: allow specifying base target types.
//
@@ -3106,6 +3122,47 @@ namespace build2
}
}
+ struct map_ext_data
+ {
+ const char* what_tgt;
+ const map<string, const target_type*>& map_tt;
+ const path* f; // Updated on each iteration.
+ } d {what_tgt, map_tt, nullptr};
+
+ function<dyndep::map_extension_func> map_ext (
+ [this, &d] (const scope& bs, const string& n, const string& e)
+ {
+ small_vector<const target_type*, 2> tts;
+
+ // Check the custom mapping first.
+ //
+ auto i (d.map_tt.find (e));
+ if (i != d.map_tt.end ())
+ tts.push_back (i->second);
+ else
+ {
+ tts = dyndep::map_extension (bs, n, e, nullptr);
+
+ // Issue custom diagnostics suggesting --target-extension-type.
+ //
+ if (tts.size () > 1)
+ {
+ diag_record dr (fail);
+
+ dr << "mapping of " << d.what_tgt << " target path " << *d.f
+ << " to target type is ambiguous";
+
+ for (const target_type* tt: tts)
+ dr << info << "can be " << tt->name << "{}";
+
+ dr << info << "use --target-extension-type to provide custom "
+ << "mapping";
+ }
+ }
+
+ return tts;
+ });
+
function<dyndep::group_filter_func> filter;
if (g != nullptr)
{
@@ -3131,6 +3188,8 @@ namespace build2
{
const path& f (dt.path);
+ d.f = &f; // Current file being mapped.
+
// Note that this logic should be consistent with what we have in
// adhoc_buildscript_rule::apply() for perform_clean.
//