aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-07-26 09:30:11 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-07-26 09:30:11 +0200
commitacdcc228c252e2a0a90a8586c5b5c6984332635b (patch)
treed5d683b623e6f97661a70bd9b915d728b04be189
parentbd9c21a84b62553000fb1e6d23fac4c58febf348 (diff)
Pass extension supplied by rule to target type default extension function
Also revert the precedence back to target type over rule. But now the target type is able to customize this logic (see exe{} for a use case).
-rw-r--r--build2/cc/compile-rule.cxx2
-rw-r--r--build2/search.cxx2
-rw-r--r--build2/target-type.hxx9
-rw-r--r--build2/target.cxx39
-rw-r--r--build2/target.hxx6
-rw-r--r--build2/target.txx5
6 files changed, 38 insertions, 25 deletions
diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx
index 12bf2fa..ebd12fd 100644
--- a/build2/cc/compile-rule.cxx
+++ b/build2/cc/compile-rule.cxx
@@ -1068,7 +1068,7 @@ namespace build2
// This is like prerequisite search.
//
- if (optional<string> de = tt.default_extension (tk, s, true))
+ if (optional<string> de = tt.default_extension (tk, s, nullptr, true))
if (*de == e)
return true;
diff --git a/build2/search.cxx b/build2/search.cxx
index 69e9986..960229b 100644
--- a/build2/search.cxx
+++ b/build2/search.cxx
@@ -117,7 +117,7 @@ namespace build2
if (auto f = ctk.type->fixed_extension)
ext = f (ctk);
else if (auto f = ctk.type->default_extension)
- ext = f (ctk, *s, true);
+ ext = f (ctk, *s, nullptr, true);
if (!ext)
{
diff --git a/build2/target-type.hxx b/build2/target-type.hxx
index ebe60db..408a520 100644
--- a/build2/target-type.hxx
+++ b/build2/target-type.hxx
@@ -34,12 +34,14 @@ namespace build2
// returns NULL, then it means the default extension for this target could
// not be derived.
//
- // The default extension is used in two (key; there are others) places:
+ // The default extension is used in two key (there are others) places:
// search_existing_file() (called for a prerequisite with the last argument
// true) and in target::derive_extension() (called for a target with the
// last argument false); see their respective implementations for details.
- // Note that the default extension supplied to derive_extension() (e.g., by
- // a rule) takes precedence over the one returned by default_extension.
+ // The third argument is the default extension that is supplied (e.g., by a
+ // rule) to derive_extension(), if any. The implementation can decide which
+ // takes precedence, etc (see the exe{} target type for some interesting
+ // logic).
//
// If the pattern function is not NULL, then it is used to amend a pattern
// or match (reverse is false) and then, if the amendment call returned
@@ -55,6 +57,7 @@ namespace build2
const char* (*fixed_extension) (const target_key&);
optional<string> (*default_extension) (const target_key&,
const scope&,
+ const char*,
bool search);
bool (*pattern) (const target_type&, const scope&, string&, bool reverse);
diff --git a/build2/target.cxx b/build2/target.cxx
index 200f562..e6188cd 100644
--- a/build2/target.cxx
+++ b/build2/target.cxx
@@ -488,19 +488,21 @@ namespace build2
{
optional<string> e;
- // Prefer the default extension specified (presumably) by the rule over
- // the one returned by the default extension function. Here we assume
- // the rule knows what it is doing (see the exe{} target type for a use
- // case).
+ // If the target type has the default extension function then try that
+ // first. The reason for preferring it over what's been provided by the
+ // caller is that this function will often use the 'extension' variable
+ // which the user can use to override extensions. But since we pass the
+ // provided default extension, the target type can override this logic
+ // (see the exe{} target type for a use case).
//
- if (de != nullptr)
- e = de;
- else
- {
- if (auto f = type ().default_extension)
- e = f (key (), base_scope (), search);
+ if (auto f = type ().default_extension)
+ e = f (key (), base_scope (), de, search);
- if (!e)
+ if (!e)
+ {
+ if (de != nullptr)
+ e = de;
+ else
{
if (search)
return nullptr;
@@ -577,13 +579,13 @@ namespace build2
}
optional<string>
- target_extension_null (const target_key&, const scope&, bool)
+ target_extension_null (const target_key&, const scope&, const char*, bool)
{
return nullopt;
}
optional<string>
- target_extension_assert (const target_key&, const scope&, bool)
+ target_extension_assert (const target_key&, const scope&, const char*, bool)
{
assert (false); // Attempt to obtain the default extension.
throw failed ();
@@ -847,14 +849,19 @@ namespace build2
};
static optional<string>
- exe_target_extension (const target_key&, const scope&, bool search)
+ exe_target_extension (const target_key&,
+ const scope&,
+ const char* e,
+ bool search)
{
// If we are searching for an executable that is not a target, then use
// the build machine executable extension. Otherwise, if this is a target,
// then we expect the rule to supply the target machine extension. But if
- // it doesn't, then assume no extension (e.g., a script).
+ // it doesn't, then fallback to no extension (e.g., a script).
//
- return string (!search ? "" :
+ return string (!search
+ ? (e != nullptr ? e : "")
+ :
#ifdef _WIN32
"exe"
#else
diff --git a/build2/target.hxx b/build2/target.hxx
index aad5331..0f8c8ea 100644
--- a/build2/target.hxx
+++ b/build2/target.hxx
@@ -1713,7 +1713,7 @@ namespace build2
//
template <const char* var, const char* def>
optional<string>
- target_extension_var (const target_key&, const scope&, bool);
+ target_extension_var (const target_key&, const scope&, const char*, bool);
template <const char* var, const char* def>
bool
@@ -1722,12 +1722,12 @@ namespace build2
// Always return NULL extension.
//
optional<string>
- target_extension_null (const target_key&, const scope&, bool);
+ target_extension_null (const target_key&, const scope&, const char*, bool);
// Assert if called.
//
optional<string>
- target_extension_assert (const target_key&, const scope&, bool);
+ target_extension_assert (const target_key&, const scope&, const char*, bool);
// Target print functions.
//
diff --git a/build2/target.txx b/build2/target.txx
index 4feea2f..d832d6b 100644
--- a/build2/target.txx
+++ b/build2/target.txx
@@ -105,7 +105,10 @@ namespace build2
template <const char* var, const char* def>
optional<string>
- target_extension_var (const target_key& tk, const scope& s, bool)
+ target_extension_var (const target_key& tk,
+ const scope& s,
+ const char*,
+ bool)
{
return target_extension_var_impl (*tk.type, *tk.name, s, var, def);
}