aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/algorithm.cxx11
-rw-r--r--libbuild2/algorithm.hxx18
-rw-r--r--libbuild2/algorithm.ixx32
-rw-r--r--libbuild2/search.cxx40
-rw-r--r--libbuild2/search.hxx5
-rw-r--r--libbuild2/target.hxx4
6 files changed, 108 insertions, 2 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index d1a796d..f859eef 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -68,6 +68,17 @@ namespace build2
return create_new_target (t.ctx, pk);
}
+ pair<target&, ulock>
+ search_locked (const target& t, const prerequisite_key& pk)
+ {
+ assert (t.ctx.phase == run_phase::match && !pk.proj);
+
+ if (const target* pt = pk.tk.type->search (t, pk))
+ return {const_cast<target&> (*pt), ulock ()};
+
+ return create_new_target_locked (t.ctx, pk);
+ }
+
const target*
search_existing (context& ctx, const prerequisite_key& pk)
{
diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx
index 34e844c..aa1336c 100644
--- a/libbuild2/algorithm.hxx
+++ b/libbuild2/algorithm.hxx
@@ -39,6 +39,12 @@ namespace build2
LIBBUILD2_SYMEXPORT const target&
search (const target&, const prerequisite_key&);
+ // As above but return the lock if the target was newly created. Note that
+ // this version can only be used on project-unqualified prerequisites.
+ //
+ 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.
//
@@ -57,6 +63,9 @@ namespace build2
const target&
search (const target&, const target_type&, const prerequisite_key&);
+ pair<target&, ulock>
+ search_locked (const target&, 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.
//
@@ -70,6 +79,15 @@ namespace build2
const scope* = nullptr, // NULL means dir is absolute.
const optional<project_name>& proj = nullopt);
+ pair<target&, ulock>
+ search_locked (const target&,
+ const target_type&,
+ 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 target*
search_existing (context&,
const target_type&,
diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx
index eb20ad0..396d518 100644
--- a/libbuild2/algorithm.ixx
+++ b/libbuild2/algorithm.ixx
@@ -34,6 +34,17 @@ namespace build2
k.proj, {&tt, k.tk.dir, k.tk.out, k.tk.name, k.tk.ext}, k.scope});
}
+ inline pair<target&, ulock>
+ search_locked (const target& t,
+ const target_type& tt,
+ const prerequisite_key& k)
+ {
+ return search_locked (
+ t,
+ 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,
@@ -56,6 +67,27 @@ namespace build2
scope});
}
+ inline pair<target&, ulock>
+ search_locked (const target& t,
+ const target_type& type,
+ const dir_path& dir,
+ const dir_path& out,
+ const string& name,
+ const string* ext,
+ const scope* scope)
+ {
+ return search_locked (
+ t,
+ prerequisite_key {
+ nullopt,
+ {
+ &type,
+ &dir, &out, &name,
+ ext != nullptr ? optional<string> (*ext) : nullopt
+ },
+ scope});
+ }
+
inline const target*
search_existing (context& ctx,
const target_type& type,
diff --git a/libbuild2/search.cxx b/libbuild2/search.cxx
index 2b10e0b..b341c85 100644
--- a/libbuild2/search.cxx
+++ b/libbuild2/search.cxx
@@ -243,4 +243,44 @@ namespace build2
<< " for prerequisite " << pk;});
return t;
}
+
+ pair<target&, ulock>
+ create_new_target_locked (context& ctx, const prerequisite_key& pk)
+ {
+ tracer trace ("create_new_target_locked");
+
+ const target_key& tk (pk.tk);
+
+ // We default to the target in this directory scope.
+ //
+ dir_path d;
+ if (tk.dir->absolute ())
+ d = *tk.dir; // Already normalized.
+ else
+ {
+ d = pk.scope->out_path ();
+
+ if (!tk.dir->empty ())
+ {
+ d /= *tk.dir;
+ d.normalize ();
+ }
+ }
+
+ // Find or insert.
+ //
+ // @@ OUT: same story as in search_existing_target() re out.
+ //
+ auto r (ctx.targets.insert_locked (*tk.type,
+ move (d),
+ *tk.out,
+ *tk.name,
+ tk.ext,
+ target_decl::prereq_new,
+ trace));
+
+ l5 ([&]{trace << (r.second ? "new" : "existing") << " target " << r.first
+ << " for prerequisite " << pk;});
+ return r;
+ }
}
diff --git a/libbuild2/search.hxx b/libbuild2/search.hxx
index e63d582..aa30648 100644
--- a/libbuild2/search.hxx
+++ b/libbuild2/search.hxx
@@ -34,6 +34,11 @@ namespace build2
//
LIBBUILD2_SYMEXPORT const target&
create_new_target (context&, const prerequisite_key&);
+
+ // As above but return the lock if the target was newly created.
+ //
+ LIBBUILD2_SYMEXPORT pair<target&, ulock>
+ create_new_target_locked (context&, const prerequisite_key&);
}
#endif // LIBBUILD2_SEARCH_HXX
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index d6e128e..e1d91e4 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -1558,8 +1558,8 @@ namespace build2
// (for example, a binless library or an installed import library -- we
// know the DLL is there, just not exactly where). In this case you could
// also set its mtime to timestamp_unreal (but don't have to, if a real
- // timestamp can be derived, for example, the from the import library in
- // the DLL case above).
+ // timestamp can be derived, for example, from the import library in the
+ // DLL case above).
//
// Note, however, that a target with timestamp_unreal does not have to
// have an empty path. One consequence of this arrangement (assigned path