From 9fb791e9fad6c63fc1dac49f4d05ae63b8a3db9b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 5 Jan 2016 11:55:15 +0200 Subject: Rename build directory/namespace to build2 --- build2/bin/rule.cxx | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 build2/bin/rule.cxx (limited to 'build2/bin/rule.cxx') diff --git a/build2/bin/rule.cxx b/build2/bin/rule.cxx new file mode 100644 index 0000000..9d93b0a --- /dev/null +++ b/build2/bin/rule.cxx @@ -0,0 +1,145 @@ +// file : build2/bin/rule.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#include +#include +#include +#include + +#include + +using namespace std; + +namespace build2 +{ + namespace bin + { + // obj + // + match_result 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"; + + return nullptr; + } + + recipe obj_rule:: + apply (action, target&, const match_result&) const {return empty_recipe;} + + // lib + // + // The whole logic is pretty much as if we had our two group + // members as our prerequisites. + // + match_result lib_rule:: + match (action a, target& xt, const std::string&) const + { + lib& t (static_cast (xt)); + + // @@ We have to re-query it on each match_only()! + + // Get the library type to build. If not set for a target, this + // should be configured at the project scope by init_lib(). + // + const string& type (as (*t["bin.lib"])); + + 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"; + + // Search and pre-match the members. The pre-match here is part + // of the "library meta-information protocol" that could be used + // by the module that actually builds the members. The idea is + // that pre-matching members may populate our prerequisite_targets + // with prerequisite libraries from which others can extract the + // meta-information about the library, such as the options to use + // when linking it, etc. + // + if (ar) + { + if (t.a == nullptr) + t.a = &search (t.dir, t.name, t.ext, nullptr); + + match_only (a, *t.a); + } + + if (so) + { + if (t.so == nullptr) + t.so = &search (t.dir, t.name, t.ext, nullptr); + + match_only (a, *t.so); + } + + match_result mr (t, &type); + + // If there is an outer operation, indicate that we match + // unconditionally so that we don't override ourselves. + // + if (a.outer_operation () != 0) + mr.recipe_action = action (a.meta_operation (), a.operation ()); + + return mr; + } + + recipe lib_rule:: + apply (action a, target& xt, const match_result& mr) const + { + lib& t (static_cast (xt)); + + const string& type (*static_cast (mr.cpvalue)); + + bool ar (type == "static" || type == "both"); + bool so (type == "shared" || type == "both"); + + // Now we do full match. + // + if (ar) + build2::match (a, *t.a); + + if (so) + build2::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 (as (*t["bin.lib"])); + 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 r (target_state::unchanged); + + if (m1 != nullptr) + r |= execute (a, *m1); + + if (m2 != nullptr) + r |= execute (a, *m2); + + return r; + } + } +} -- cgit v1.1