// file : build2/bin/target.cxx -*- C++ -*- // copyright : Copyright (c) 2014-2017 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #include using namespace std; 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 static pair> objx_factory (const target_type&, dir_path dir, dir_path out, string n, optional ext) { const obj* g (targets.find (dir, out, n)); T* x (new T (move (dir), move (out), move (n))); x->group = g; return make_pair (x, move (ext)); } const target_type obje::static_type { "obje", &file::static_type, &objx_factory, &target_extension_var, &target_pattern_var, nullptr, &target_search, // Note: not _file(); don't look for an existing file. false }; const target_type obja::static_type { "obja", &file::static_type, &objx_factory, &target_extension_var, &target_pattern_var, nullptr, &target_search, // Note: not _file(); don't look for an existing file. false }; const target_type objs::static_type { "objs", &file::static_type, &objx_factory, &target_extension_var, &target_pattern_var, nullptr, &target_search, // Note: not _file(); don't look for an existing file. false }; static pair> obj_factory (const target_type&, dir_path dir, dir_path out, string n, optional ext) { // Casts are MT-aware (during serial load). // obje* e (phase == run_phase::load ? const_cast (targets.find (dir, out, n)) : nullptr); obja* a (phase == run_phase::load ? const_cast (targets.find (dir, out, n)) : nullptr); objs* s (phase == run_phase::load ? const_cast (targets.find (dir, out, n)) : nullptr); obj* o (new obj (move (dir), move (out), move (n))); if (e != nullptr) e->group = o; if (a != nullptr) a->group = o; if (s != nullptr) s->group = o; return make_pair (o, move (ext)); } const target_type obj::static_type { "obj", &target::static_type, &obj_factory, nullptr, nullptr, nullptr, &target_search, false }; template static pair> libx_factory (const target_type&, dir_path dir, dir_path out, string n, optional ext) { const lib* g (targets.find (dir, out, n)); T* x (new T (move (dir), move (out), move (n))); x->group = g; 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 // 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, &libx_factory, &target_extension_var, &target_pattern_var, nullptr, &file_search, false }; const target_type libs::static_type { "libs", &file::static_type, &libx_factory, &target_extension_var, &target_pattern_var, nullptr, &file_search, false }; // 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 (&a), 2} : group_view {nullptr, 0}; } static pair> lib_factory (const target_type&, dir_path dir, dir_path out, string n, optional ext) { // Casts are MT-aware (during serial load). // liba* a (phase == run_phase::load ? const_cast (targets.find (dir, out, n)) : nullptr); libs* s (phase == run_phase::load ? const_cast (targets.find (dir, out, n)) : nullptr); lib* l (new lib (move (dir), move (out), move (n))); if (a != nullptr) a->group = l; if (s != nullptr) s->group = l; return make_pair (l, move (ext)); } const target_type lib::static_type { "lib", &target::static_type, &lib_factory, nullptr, nullptr, nullptr, &target_search, false }; // libi // const target_type libi::static_type { "libi", &file::static_type, &target_factory, &target_extension_var, &target_pattern_var, nullptr, &file_search, false }; } }