aboutsummaryrefslogtreecommitdiff
path: root/build2/bin/target.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/bin/target.cxx')
-rw-r--r--build2/bin/target.cxx158
1 files changed, 64 insertions, 94 deletions
diff --git a/build2/bin/target.cxx b/build2/bin/target.cxx
index ea0a1ac..cf187fa 100644
--- a/build2/bin/target.cxx
+++ b/build2/bin/target.cxx
@@ -10,83 +10,58 @@ namespace build2
{
namespace bin
{
+ // Note that we link groups during the load phase since this is often
+ // relied upon when setting target-specific variables (e.g., we may set a
+ // common value for lib{} and then append liba/libs-specific values to
+ // it). While sure inelegant, this is MT-safe since during load we are
+ // running serial. For the members it is also safe to set the group during
+ // creation.
+
extern const char ext_var[] = "extension"; // VC14 rejects constexpr.
+ template <typename T>
static pair<target*, optional<string>>
- obje_factory (const target_type&,
+ objx_factory (const target_type&,
dir_path dir,
dir_path out,
string n,
optional<string> ext)
{
- obj* o (targets.find<obj> (dir, out, n));
- obje* e (new obje (move (dir), move (out), move (n)));
+ const obj* g (targets.find<obj> (dir, out, n));
- if ((e->group = o) != nullptr)
- o->e = e;
+ T* x (new T (move (dir), move (out), move (n)));
+ x->group = g;
- return make_pair (e, move (ext));
+ return make_pair (x, move (ext));
}
const target_type obje::static_type
{
"obje",
&file::static_type,
- &obje_factory,
+ &objx_factory<obje>,
&target_extension_var<ext_var, nullptr>,
nullptr,
&search_target, // Note: not _file(); don't look for an existing file.
false
};
- static pair<target*, optional<string>>
- obja_factory (const target_type&,
- dir_path dir,
- dir_path out,
- string n,
- optional<string> ext)
- {
- obj* o (targets.find<obj> (dir, out, n));
- obja* a (new obja (move (dir), move (out), move (n)));
-
- if ((a->group = o) != nullptr)
- o->a = a;
-
- return make_pair (a, move (ext));
- }
-
const target_type obja::static_type
{
"obja",
&file::static_type,
- &obja_factory,
+ &objx_factory<obja>,
&target_extension_var<ext_var, nullptr>,
nullptr,
&search_target, // Note: not _file(); don't look for an existing file.
false
};
- static pair<target*, optional<string>>
- objs_factory (const target_type&,
- dir_path dir,
- dir_path out,
- string n,
- optional<string> ext)
- {
- obj* o (targets.find<obj> (dir, out, n));
- objs* s (new objs (move (dir), move (out), move (n)));
-
- if ((s->group = o) != nullptr)
- o->s = s;
-
- return make_pair (s, move (ext));
- }
-
const target_type objs::static_type
{
"objs",
&file::static_type,
- &objs_factory,
+ &objx_factory<objs>,
&target_extension_var<ext_var, nullptr>,
nullptr,
&search_target, // Note: not _file(); don't look for an existing file.
@@ -100,20 +75,23 @@ namespace build2
string n,
optional<string> ext)
{
- obje* e (targets.find<obje> (dir, out, n));
- obja* a (targets.find<obja> (dir, out, n));
- objs* s (targets.find<objs> (dir, out, n));
+ // Casts are MT-aware (during serial load).
+ //
+ obje* e (phase == run_phase::load
+ ? const_cast<obje*> (targets.find<obje> (dir, out, n))
+ : nullptr);
+ obja* a (phase == run_phase::load
+ ? const_cast<obja*> (targets.find<obja> (dir, out, n))
+ : nullptr);
+ objs* s (phase == run_phase::load
+ ? const_cast<objs*> (targets.find<objs> (dir, out, n))
+ : nullptr);
obj* o (new obj (move (dir), move (out), move (n)));
- if ((o->e = e) != nullptr)
- e->group = o;
-
- if ((o->a = a)!= nullptr)
- a->group = o;
-
- if ((o->s = s)!= nullptr)
- s->group = o;
+ if (e != nullptr) e->group = o;
+ if (a != nullptr) a->group = o;
+ if (s != nullptr) s->group = o;
return make_pair (o, move (ext));
}
@@ -129,26 +107,22 @@ namespace build2
false
};
+ template <typename T>
static pair<target*, optional<string>>
- liba_factory (const target_type& t,
- dir_path d,
- dir_path o,
+ libx_factory (const target_type&,
+ dir_path dir,
+ dir_path out,
string n,
optional<string> ext)
{
- // Only link-up to the group if the types match exactly.
- //
- lib* l (t == liba::static_type ? targets.find<lib> (d, o, n) : nullptr);
- liba* a (new liba (move (d), move (o), move (n)));
+ const lib* g (targets.find<lib> (dir, out, n));
- if ((a->group = l) != nullptr)
- l->a = a;
+ T* x (new T (move (dir), move (out), move (n)));
+ x->group = g;
- return make_pair (a, move (ext));
+ return make_pair (x, move (ext));
}
- // @@
- //
// What extensions should we use? At the outset, this is platform-
// dependent. And if we consider cross-compilation, is it build or
// host-dependent? Feels like it should be host-dependent so that
@@ -163,36 +137,18 @@ namespace build2
{
"liba",
&file::static_type,
- &liba_factory,
+ &libx_factory<liba>,
&target_extension_var<ext_var, nullptr>,
nullptr,
&search_file,
false
};
- static pair<target*, optional<string>>
- libs_factory (const target_type& t,
- dir_path d,
- dir_path o,
- string n,
- optional<string> ext)
- {
- // Only link-up to the group if the types match exactly.
- //
- lib* l (t == libs::static_type ? targets.find<lib> (d, o, n) : nullptr);
- libs* s (new libs (move (d), move (o), move (n)));
-
- if ((s->group = l) != nullptr)
- l->s = s;
-
- return make_pair (s, move (ext));
- }
-
const target_type libs::static_type
{
"libs",
&file::static_type,
- &libs_factory,
+ &libx_factory<libs>,
&target_extension_var<ext_var, nullptr>,
nullptr,
&search_file,
@@ -201,23 +157,37 @@ namespace build2
// lib
//
+ group_view lib::
+ group_members (action_type) const
+ {
+ static_assert (sizeof (lib_members) == sizeof (const target*) * 2,
+ "member layout incompatible with array");
+
+ return a != nullptr || s != nullptr
+ ? group_view {reinterpret_cast<const target* const*> (&a), 2}
+ : group_view {nullptr, 0};
+ }
+
static pair<target*, optional<string>>
lib_factory (const target_type&,
- dir_path d,
- dir_path o,
+ dir_path dir,
+ dir_path out,
string n,
optional<string> ext)
{
- liba* a (targets.find<liba> (d, o, n));
- libs* s (targets.find<libs> (d, o, n));
-
- lib* l (new lib (move (d), move (o), move (n)));
+ // Casts are MT-aware (during serial load).
+ //
+ liba* a (phase == run_phase::load
+ ? const_cast<liba*> (targets.find<liba> (dir, out, n))
+ : nullptr);
+ libs* s (phase == run_phase::load
+ ? const_cast<libs*> (targets.find<libs> (dir, out, n))
+ : nullptr);
- if ((l->a = a) != nullptr)
- a->group = l;
+ lib* l (new lib (move (dir), move (out), move (n)));
- if ((l->s = s) != nullptr)
- s->group = l;
+ if (a != nullptr) a->group = l;
+ if (s != nullptr) s->group = l;
return make_pair (l, move (ext));
}