aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}