diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-02-15 03:55:15 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-03-02 14:03:34 +0200 |
commit | b37f1aa6398065be806e6605a023189685669885 (patch) | |
tree | b9b32091e3d70a31852302b24c99ecb62465464a /build2/bin/target.cxx | |
parent | a64b2ae2099346471ead988d5f2d383d55a9bf89 (diff) |
Implement parallel match
Diffstat (limited to 'build2/bin/target.cxx')
-rw-r--r-- | build2/bin/target.cxx | 158 |
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)); } |