aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/bin/target.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/bin/target.cxx')
-rw-r--r--libbuild2/bin/target.cxx474
1 files changed, 474 insertions, 0 deletions
diff --git a/libbuild2/bin/target.cxx b/libbuild2/bin/target.cxx
new file mode 100644
index 0000000..dd8a947
--- /dev/null
+++ b/libbuild2/bin/target.cxx
@@ -0,0 +1,474 @@
+// file : libbuild2/bin/target.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <libbuild2/bin/target.hxx>
+
+#include <libbuild2/context.hxx>
+
+using namespace std;
+
+namespace build2
+{
+ namespace bin
+ {
+ const target_type objx::static_type
+ {
+ "objx",
+ &file::static_type,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ const target_type bmix::static_type
+ {
+ "bmix",
+ &file::static_type,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ const target_type hbmix::static_type
+ {
+ "hbmix",
+ &bmix::static_type,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ const target_type libx::static_type
+ {
+ "libx",
+ &mtime_target::static_type,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ const target_type libux::static_type
+ {
+ "libux",
+ &file::static_type,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ // 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.
+
+ // obj*{} and [h]bmi*{} member factory.
+ //
+ template <typename M, typename G>
+ static target*
+ m_factory (context& ctx,
+ const target_type&, dir_path dir, dir_path out, string n)
+ {
+ const G* g (ctx.targets.find<G> (dir, out, n));
+
+ M* m (new M (ctx, move (dir), move (out), move (n)));
+ m->group = g;
+
+ return m;
+ }
+
+ const target_type obje::static_type
+ {
+ "obje",
+ &objx::static_type,
+ &m_factory<obje, obj>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type bmie::static_type
+ {
+ "bmie",
+ &bmix::static_type,
+ &m_factory<bmie, bmi>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type hbmie::static_type
+ {
+ "hbmie",
+ &hbmix::static_type,
+ &m_factory<hbmie, hbmi>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type obja::static_type
+ {
+ "obja",
+ &objx::static_type,
+ &m_factory<obja, obj>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type bmia::static_type
+ {
+ "bmia",
+ &bmix::static_type,
+ &m_factory<bmia, bmi>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type hbmia::static_type
+ {
+ "hbmia",
+ &hbmix::static_type,
+ &m_factory<hbmia, hbmi>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type objs::static_type
+ {
+ "objs",
+ &objx::static_type,
+ &m_factory<objs, obj>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type bmis::static_type
+ {
+ "bmis",
+ &bmix::static_type,
+ &m_factory<bmis, bmi>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type hbmis::static_type
+ {
+ "hbmis",
+ &hbmix::static_type,
+ &m_factory<hbmis, hbmi>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type libue::static_type
+ {
+ "libue",
+ &libux::static_type,
+ &target_factory<libue>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type libua::static_type
+ {
+ "libua",
+ &libux::static_type,
+ &m_factory<libua, libul>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ const target_type libus::static_type
+ {
+ "libus",
+ &libux::static_type,
+ &m_factory<libus, libul>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &target_search, // Note: not _file(); don't look for an existing file.
+ false
+ };
+
+ // obj{}, [h]bmi{}, and libu{} group factory.
+ //
+ template <typename G, typename E, typename A, typename S>
+ static target*
+ g_factory (context& ctx,
+ const target_type&, dir_path dir, dir_path out, string n)
+ {
+ // Casts are MT-aware (during serial load).
+ //
+ E* e (ctx.phase == run_phase::load
+ ? const_cast<E*> (ctx.targets.find<E> (dir, out, n))
+ : nullptr);
+ A* a (ctx.phase == run_phase::load
+ ? const_cast<A*> (ctx.targets.find<A> (dir, out, n))
+ : nullptr);
+ S* s (ctx.phase == run_phase::load
+ ? const_cast<S*> (ctx.targets.find<S> (dir, out, n))
+ : nullptr);
+
+ G* g (new G (ctx, move (dir), move (out), move (n)));
+
+ if (e != nullptr) e->group = g;
+ if (a != nullptr) a->group = g;
+ if (s != nullptr) s->group = g;
+
+ return g;
+ }
+
+ const target_type obj::static_type
+ {
+ "obj",
+ &target::static_type,
+ &g_factory<obj, obje, obja, objs>,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ const target_type bmi::static_type
+ {
+ "bmi",
+ &target::static_type,
+ &g_factory<bmi, bmie, bmia, bmis>,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ const target_type hbmi::static_type
+ {
+ "hbmi",
+ &target::static_type,
+ &g_factory<hbmi, hbmie, hbmia, hbmis>,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ // The same as g_factory() but without E.
+ //
+ static target*
+ libul_factory (context& ctx,
+ const target_type&, dir_path dir, dir_path out, string n)
+ {
+ libua* a (ctx.phase == run_phase::load
+ ? const_cast<libua*> (ctx.targets.find<libua> (dir, out, n))
+ : nullptr);
+ libus* s (ctx.phase == run_phase::load
+ ? const_cast<libus*> (ctx.targets.find<libus> (dir, out, n))
+ : nullptr);
+
+ libul* g (new libul (ctx, move (dir), move (out), move (n)));
+
+ if (a != nullptr) a->group = g;
+ if (s != nullptr) s->group = g;
+
+ return g;
+ }
+
+ const target_type libul::static_type
+ {
+ "libul",
+ &libx::static_type,
+ &libul_factory,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false
+ };
+
+ // 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
+ // we can copy things between cross and native environments. So
+ // these will have to be determined based on what we are building.
+ // As if this is not complicated enough, the bin module doesn't
+ // know anything about building. So perhaps the extension should
+ // come from a variable that is set not by bin but by the module
+ // whose rule matched the target (e.g., cxx::link).
+ //
+ const target_type liba::static_type
+ {
+ "liba",
+ &file::static_type,
+ &m_factory<liba, lib>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &file_search,
+ false
+ };
+
+ const target_type libs::static_type
+ {
+ "libs",
+ &file::static_type,
+ &m_factory<libs, lib>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &file_search,
+ false
+ };
+
+ // lib
+ //
+ group_view lib::
+ group_members (action) 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 target*
+ lib_factory (context& ctx,
+ const target_type&, dir_path dir, dir_path out, string n)
+ {
+ // Casts are MT-aware (during serial load).
+ //
+ liba* a (ctx.phase == run_phase::load
+ ? const_cast<liba*> (ctx.targets.find<liba> (dir, out, n))
+ : nullptr);
+ libs* s (ctx.phase == run_phase::load
+ ? const_cast<libs*> (ctx.targets.find<libs> (dir, out, n))
+ : nullptr);
+
+ lib* l (new lib (ctx, move (dir), move (out), move (n)));
+
+ if (a != nullptr) a->group = l;
+ if (s != nullptr) s->group = l;
+
+ return l;
+ }
+
+ const target_type lib::static_type
+ {
+ "lib",
+ &libx::static_type,
+ &lib_factory,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ &target_search,
+ false // Note: not see-through ("alternatives" group).
+ };
+
+ // libi
+ //
+ const target_type libi::static_type
+ {
+ "libi",
+ &file::static_type,
+ &target_factory<libi>,
+ nullptr, /* fixed_extension */
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
+ nullptr,
+ &file_search,
+ false
+ };
+
+ // def
+ //
+ extern const char def_ext[] = "def"; // VC14 rejects constexpr.
+
+ const target_type def::static_type
+ {
+ "def",
+ &file::static_type,
+ &target_factory<def>,
+ &target_extension_fix<def_ext>,
+ nullptr, /* default_extension */
+ &target_pattern_fix<def_ext>,
+ nullptr,
+ &file_search,
+ false
+ };
+ }
+}