aboutsummaryrefslogtreecommitdiff
path: root/build/bin
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-04-24 12:29:20 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-04-24 12:29:20 +0200
commit2a0f9e035f673f1ee387924501a31990de37f18d (patch)
treeb8e55ab74bc88b788e99d8649219b931b80432d5 /build/bin
parent4c44c914d898af53152addad5530504548175e85 (diff)
Implement lib/liba/libso{} target group, shared/static library build
Diffstat (limited to 'build/bin')
-rw-r--r--build/bin/rule39
-rw-r--r--build/bin/rule.cxx126
-rw-r--r--build/bin/target96
-rw-r--r--build/bin/target.cxx156
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
+ };
+ }
+}