From 2a0f9e035f673f1ee387924501a31990de37f18d Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 24 Apr 2015 12:29:20 +0200 Subject: Implement lib/liba/libso{} target group, shared/static library build --- build/bin/rule.cxx | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 build/bin/rule.cxx (limited to 'build/bin/rule.cxx') 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 + +#include +#include +#include +#include + +#include + +#include + +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 (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 (); + 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 (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 (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 (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 ()); + 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; + } + } +} -- cgit v1.1