diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-04-24 12:29:20 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-04-24 12:29:20 +0200 |
commit | 2a0f9e035f673f1ee387924501a31990de37f18d (patch) | |
tree | b8e55ab74bc88b788e99d8649219b931b80432d5 /build/bin | |
parent | 4c44c914d898af53152addad5530504548175e85 (diff) |
Implement lib/liba/libso{} target group, shared/static library build
Diffstat (limited to 'build/bin')
-rw-r--r-- | build/bin/rule | 39 | ||||
-rw-r--r-- | build/bin/rule.cxx | 126 | ||||
-rw-r--r-- | build/bin/target | 96 | ||||
-rw-r--r-- | build/bin/target.cxx | 156 |
4 files changed, 417 insertions, 0 deletions
diff --git a/build/bin/rule b/build/bin/rule new file mode 100644 index 0000000..007f6f7 --- /dev/null +++ b/build/bin/rule @@ -0,0 +1,39 @@ +// file : build/bin/rule -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD_BIN_RULE +#define BUILD_BIN_RULE + +#include <build/rule> + +namespace build +{ + namespace bin + { + class obj_rule: public rule + { + public: + virtual void* + match (action, target&, const std::string& hint) const; + + virtual recipe + apply (action, target&, void*) const; + }; + + class lib_rule: public rule + { + public: + virtual void* + match (action, target&, const std::string& hint) const; + + virtual recipe + apply (action, target&, void*) const; + + static target_state + perform (action, target&); + }; + } +} + +#endif // BUILD_BIN_RULE diff --git a/build/bin/rule.cxx b/build/bin/rule.cxx new file mode 100644 index 0000000..1b887bf --- /dev/null +++ b/build/bin/rule.cxx @@ -0,0 +1,126 @@ +// file : build/bin/rule.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include <build/bin/rule> + +#include <build/scope> +#include <build/target> +#include <build/algorithm> +#include <build/diagnostics> + +#include <build/config/utility> + +#include <build/bin/target> + +using namespace std; + +namespace build +{ + namespace bin + { + // obj + // + void* obj_rule:: + match (action a, target& t, const std::string&) const + { + fail << diag_doing (a, t) << " target group" << + info << "explicitly select either obja{} or objso{} member"; + } + + recipe obj_rule:: + apply (action, target&, void*) const {return empty_recipe;} + + // lib + // + // The whole logic is pretty much as if we had our two group + // members as prerequisites. + // + void* lib_rule:: + match (action, target& t, const std::string&) const + { + return &t; + } + + recipe lib_rule:: + apply (action a, target& xt, void*) const + { + lib& t (static_cast<lib&> (xt)); + + // Configure. + // + // The logic is as follows: if this library somehow knowns what + // it wants to be (i.e., the bin.lib is defined), then don't + // bother configuring the project-wide value. + // + const string* type (nullptr); + + if (auto v = t["bin.lib"]) + type = &v.as<const string&> (); + else + { + scope& root (*t.root_scope ()); + type = &config::required (root, "config.bin.lib", "shared").first; + root.assign ("bin.lib") = *type; + } + + bool ar (*type == "static" || *type == "both"); + bool so (*type == "shared" || *type == "both"); + + if (!ar && !so) + fail << "unknown library type: " << *type << + info << "'static', 'shared', or 'both' expected"; + + if (ar) + { + if (t.a == nullptr) + t.a = &static_cast<liba&> (search (prerequisite_key { + &liba::static_type, &t.dir, &t.name, &t.ext, nullptr})); + + build::match (a, *t.a); + } + + if (so) + { + if (t.so == nullptr) + t.so = &static_cast<libso&> (search (prerequisite_key { + &libso::static_type, &t.dir, &t.name, &t.ext, nullptr})); + + build::match (a, *t.so); + } + + return &perform; + } + + target_state lib_rule:: + perform (action a, target& xt) + { + lib& t (static_cast<lib&> (xt)); + + //@@ Not cool we have to do this again. Looks like we need + // some kind of a cache vs resolved pointer, like in + // prerequisite vs prerequisite_target. + // + // + const string& type (t["bin.lib"].as<const string&> ()); + bool ar (type == "static" || type == "both"); + bool so (type == "shared" || type == "both"); + + target* m1 (ar ? t.a : nullptr); + target* m2 (so ? t.so : nullptr); + + if (current_mode == execution_mode::last) + swap (m1, m2); + + target_state ts (target_state::unchanged); + + if (m1 != nullptr && execute (a, *m1) == target_state::changed) + ts = target_state::changed; + + if (m2 != nullptr && execute (a, *m2) == target_state::changed) + ts = target_state::changed; + + return ts; + } + } +} diff --git a/build/bin/target b/build/bin/target new file mode 100644 index 0000000..b26a890 --- /dev/null +++ b/build/bin/target @@ -0,0 +1,96 @@ +// file : build/bin/target -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD_BIN_TARGET +#define BUILD_BIN_TARGET + +#include <build/target> + +namespace build +{ + namespace bin + { + // The obj{} target group. + // + class obja: public file + { + public: + using file::file; + + public: + virtual const target_type& type () const {return static_type;} + static const target_type static_type; + }; + + class objso: public file + { + public: + using file::file; + + public: + virtual const target_type& type () const {return static_type;} + static const target_type static_type; + }; + + class obj: public target + { + public: + using target::target; + + obja* a {nullptr}; + objso* so {nullptr}; + + public: + virtual const target_type& type () const {return static_type;} + static const target_type static_type; + }; + + class exe: public file + { + public: + using file::file; + + public: + virtual const target_type& type () const {return static_type;} + static const target_type static_type; + }; + + // The lib{} target group. + // + class liba: public file + { + public: + using file::file; + + public: + virtual const target_type& type () const {return static_type;} + static const target_type static_type; + }; + + class libso: public file + { + public: + using file::file; + + public: + virtual const target_type& type () const {return static_type;} + static const target_type static_type; + }; + + class lib: public target + { + public: + using target::target; + + liba* a {nullptr}; + libso* so {nullptr}; + + public: + virtual const target_type& type () const {return static_type;} + static const target_type static_type; + }; + } +} + +#endif // BUILD_BIN_TARGET diff --git a/build/bin/target.cxx b/build/bin/target.cxx new file mode 100644 index 0000000..1849533 --- /dev/null +++ b/build/bin/target.cxx @@ -0,0 +1,156 @@ +// file : build/bin/target.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include <build/bin/target> + +using namespace std; + +namespace build +{ + namespace bin + { + static target* + obja_factory (dir_path d, std::string n, const std::string* e) + { + obj* o (targets.find<obj> (d, n)); + obja* a (new obja (std::move (d), std::move (n), e)); + + if ((a->group = o)) + o->a = a; + + return a; + } + + const target_type obja::static_type + { + typeid (obja), + "obja", + &file::static_type, + &obja_factory, + file::static_type.search + }; + + static target* + objso_factory (dir_path d, std::string n, const std::string* e) + { + obj* o (targets.find<obj> (d, n)); + objso* so (new objso (std::move (d), std::move (n), e)); + + if ((so->group = o)) + o->so = so; + + return so; + } + + const target_type objso::static_type + { + typeid (objso), + "objso", + &file::static_type, + &objso_factory, + file::static_type.search + }; + + static target* + obj_factory (dir_path d, string n, const string* e) + { + obja* a (targets.find<obja> (d, n)); + objso* so (targets.find<objso> (d, n)); + obj* o (new obj (move (d), move (n), e)); + + if ((o->a = a)) + a->group = o; + + if ((o->so = so)) + so->group = o; + + return o; + } + + const target_type obj::static_type + { + typeid (obj), + "obj", + &target::static_type, + &obj_factory, + target::static_type.search + }; + + const target_type exe::static_type + { + typeid (exe), + "exe", + &file::static_type, + &target_factory<exe>, + file::static_type.search + }; + + static target* + liba_factory (dir_path d, std::string n, const std::string* e) + { + lib* l (targets.find<lib> (d, n)); + liba* a (new liba (std::move (d), std::move (n), e)); + + if ((a->group = l)) + l->a = a; + + return a; + } + + const target_type liba::static_type + { + typeid (liba), + "liba", + &file::static_type, + &liba_factory, + file::static_type.search + }; + + static target* + libso_factory (dir_path d, std::string n, const std::string* e) + { + lib* l (targets.find<lib> (d, n)); + libso* so (new libso (std::move (d), std::move (n), e)); + + if ((so->group = l)) + l->so = so; + + return so; + } + + const target_type libso::static_type + { + typeid (libso), + "libso", + &file::static_type, + &libso_factory, + file::static_type.search + }; + + static target* + lib_factory (dir_path d, string n, const string* e) + { + liba* a (targets.find<liba> (d, n)); + libso* so (targets.find<libso> (d, n)); + lib* l (new lib (move (d), move (n), e)); + + if ((l->a = a)) + a->group = l; + + if ((l->so = so)) + so->group = l; + + return l; + } + + const target_type lib::static_type + { + typeid (lib), + "lib", + &target::static_type, + &lib_factory, + target::static_type.search + }; + } +} |