aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-01-21 09:03:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-01-21 09:03:28 +0200
commitd2b8ba3e586a17e78b480c129bfcf24d6e05bade (patch)
tree5e823668df3d8138a0285146ad6de1c863b57c8a /libbuild2
parent214f1f05dfb3f2ae2090e491f3dd78836076c2e0 (diff)
Add search_new() and search_new_locked() variants of search()
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/algorithm.cxx22
-rw-r--r--libbuild2/algorithm.hxx52
-rw-r--r--libbuild2/algorithm.ixx64
-rw-r--r--libbuild2/cc/link-rule.cxx4
4 files changed, 132 insertions, 10 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 0370626..0c8ac6f 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -88,6 +88,28 @@ namespace build2
}
const target&
+ search_new (context& ctx, const prerequisite_key& pk)
+ {
+ assert (ctx.phase == run_phase::load || ctx.phase == run_phase::match);
+
+ if (const target* pt = search_existing_target (ctx, pk))
+ return *pt;
+
+ return create_new_target (ctx, pk);
+ }
+
+ pair<target&, ulock>
+ search_new_locked (context& ctx, const prerequisite_key& pk)
+ {
+ assert (ctx.phase == run_phase::load || ctx.phase == run_phase::match);
+
+ if (const target* pt = search_existing_target (ctx, pk))
+ return {const_cast<target&> (*pt), ulock ()};
+
+ return create_new_target_locked (ctx, pk);
+ }
+
+ const target&
search (const target& t, name n, const scope& s, const target_type* tt)
{
assert (t.ctx.phase == run_phase::match);
diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx
index 01b69f2..da64b1a 100644
--- a/libbuild2/algorithm.hxx
+++ b/libbuild2/algorithm.hxx
@@ -17,7 +17,7 @@
namespace build2
{
// The default prerequisite search implementation. It first calls the
- // prerequisite-type-specific search function. If that doesn't yeld
+ // prerequisite-type-specific search function. If that doesn't yield
// anything, it creates a new target.
//
LIBBUILD2_SYMEXPORT const target&
@@ -45,20 +45,32 @@ namespace build2
LIBBUILD2_SYMEXPORT pair<target&, ulock>
search_locked (const target&, const prerequisite_key&);
- // Note that unlike the above version, this one can be called during the
- // load and execute phases.
+ // As above but this one can be called during the load and execute phases.
//
LIBBUILD2_SYMEXPORT const target*
search_existing (context&, const prerequisite_key&);
+ // First search for an existing target and if that doesn't yield anything,
+ // creates a new target, bypassing any prerequisite-type-specific search.
+ // Can be called during the load and match phases but only on project-
+ // unqualified prerequisites. This version is suitable for cases where you
+ // know the target is in out and cannot be possibly found in src.
+ //
+ LIBBUILD2_SYMEXPORT const target&
+ search_new (context&, const prerequisite_key&);
+
+ // As above but return the lock if the target was newly created.
+ //
+ LIBBUILD2_SYMEXPORT pair<target&, ulock>
+ search_new_locked (context&, const prerequisite_key&);
+
// Uniform search interface for prerequisite/prerequisite_member.
//
inline const target&
search (const target& t, const prerequisite_member& p) {return p.search (t);}
- // As above but override the target type. Useful for searching for
- // target group members where we need to search for a different
- // target type.
+ // As above but override the target type. Useful for searching for target
+ // group members where we need to search for a different target type.
//
const target&
search (const target&, const target_type&, const prerequisite_key&);
@@ -66,6 +78,12 @@ namespace build2
pair<target&, ulock>
search_locked (const target&, const target_type&, const prerequisite_key&);
+ const target&
+ search_new (context&, const target_type&, const prerequisite_key&);
+
+ pair<target&, ulock>
+ search_new_locked (context&, const target_type&, const prerequisite_key&);
+
// As above but specify the prerequisite to search as individual key
// components. Scope can be NULL if the directory is absolute.
//
@@ -85,8 +103,8 @@ namespace build2
const dir_path& dir,
const dir_path& out,
const string& name,
- const string* ext = nullptr, // NULL means unspecified.
- const scope* = nullptr); // NULL means dir is absolute.
+ const string* ext = nullptr,
+ const scope* = nullptr);
const target*
search_existing (context&,
@@ -98,6 +116,24 @@ namespace build2
const scope* = nullptr,
const optional<project_name>& proj = nullopt);
+ const target&
+ search_new (context&,
+ const target_type&,
+ const dir_path& dir,
+ const dir_path& out,
+ const string& name,
+ const string* ext = nullptr,
+ const scope* = nullptr);
+
+ pair<target&, ulock>
+ search_new_locked (context&,
+ const target_type&,
+ const dir_path& dir,
+ const dir_path& out,
+ const string& name,
+ const string* ext = nullptr,
+ const scope* = nullptr);
+
// As above but specify the target type as template argument.
//
template <typename T>
diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx
index d64747d..264a162 100644
--- a/libbuild2/algorithm.ixx
+++ b/libbuild2/algorithm.ixx
@@ -46,6 +46,28 @@ namespace build2
}
inline const target&
+ search_new (context& ctx,
+ const target_type& tt,
+ const prerequisite_key& k)
+ {
+ return search_new (
+ ctx,
+ prerequisite_key {
+ k.proj, {&tt, k.tk.dir, k.tk.out, k.tk.name, k.tk.ext}, k.scope});
+ }
+
+ inline pair<target&, ulock>
+ search_new_locked (context& ctx,
+ const target_type& tt,
+ const prerequisite_key& k)
+ {
+ return search_new_locked (
+ ctx,
+ prerequisite_key {
+ k.proj, {&tt, k.tk.dir, k.tk.out, k.tk.name, k.tk.ext}, k.scope});
+ }
+
+ inline const target&
search (const target& t,
const target_type& type,
const dir_path& dir,
@@ -110,6 +132,48 @@ namespace build2
scope});
}
+ inline const target&
+ search_new (context& ctx,
+ const target_type& type,
+ const dir_path& dir,
+ const dir_path& out,
+ const string& name,
+ const string* ext,
+ const scope* scope)
+ {
+ return search_new (
+ ctx,
+ prerequisite_key {
+ nullopt,
+ {
+ &type,
+ &dir, &out, &name,
+ ext != nullptr ? optional<string> (*ext) : nullopt
+ },
+ scope});
+ }
+
+ inline pair<target&, ulock>
+ search_new_locked (context& ctx,
+ const target_type& type,
+ const dir_path& dir,
+ const dir_path& out,
+ const string& name,
+ const string* ext,
+ const scope* scope)
+ {
+ return search_new_locked (
+ ctx,
+ prerequisite_key {
+ nullopt,
+ {
+ &type,
+ &dir, &out, &name,
+ ext != nullptr ? optional<string> (*ext) : nullopt
+ },
+ scope});
+ }
+
template <typename T>
inline const T&
search (const target& t,
diff --git a/libbuild2/cc/link-rule.cxx b/libbuild2/cc/link-rule.cxx
index 79de01c..551b243 100644
--- a/libbuild2/cc/link-rule.cxx
+++ b/libbuild2/cc/link-rule.cxx
@@ -976,8 +976,8 @@ namespace build2
// be the group -- we will pick a member in part 2 below.
//
pair<target&, ulock> r (
- search_locked (
- t, rtt, d, dir_path (), *cp.tk.name, nullptr, cp.scope));
+ search_new_locked (
+ ctx, rtt, d, dir_path (), *cp.tk.name, nullptr, cp.scope));
// If we shouldn't clean obj{}, then it is fair to assume we
// shouldn't clean the source either (generated source will be in