diff options
-rw-r--r-- | build/cxx/install | 2 | ||||
-rw-r--r-- | build/cxx/install.cxx | 2 | ||||
-rw-r--r-- | build/install/module.cxx | 8 | ||||
-rw-r--r-- | build/install/rule | 12 | ||||
-rw-r--r-- | build/install/rule.cxx | 51 |
5 files changed, 66 insertions, 9 deletions
diff --git a/build/cxx/install b/build/cxx/install index 3a6f463..7117fb8 100644 --- a/build/cxx/install +++ b/build/cxx/install @@ -12,7 +12,7 @@ namespace build { namespace cxx { - class install: public build::install::rule + class install: public build::install::file_rule { public: virtual bool diff --git a/build/cxx/install.cxx b/build/cxx/install.cxx index b623349..e6417a6 100644 --- a/build/cxx/install.cxx +++ b/build/cxx/install.cxx @@ -40,7 +40,7 @@ namespace build // match_result r (link::instance.match (a, t, hint)); - return r ? install::rule::match (a, t, "") : r; + return r ? install::file_rule::match (a, t, "") : r; } install install::instance; diff --git a/build/install/module.cxx b/build/install/module.cxx index b117e98..042bee9 100644 --- a/build/install/module.cxx +++ b/build/install/module.cxx @@ -89,7 +89,8 @@ namespace build set_var<strings> (s, r, name, ".options", nullptr); } - static rule rule_; + static alias_rule alias_rule_; + static file_rule file_rule_; extern "C" void install_init (scope& r, @@ -116,9 +117,10 @@ namespace build // r.operations.insert (install_id, install); - // Register our file installer rule. + // Register our alias and file installer rule. // - b.rules.insert<file> (perform_id, install_id, "install", rule_); + b.rules.insert<alias> (perform_id, install_id, "install", alias_rule_); + b.rules.insert<file> (perform_id, install_id, "install", file_rule_); // Enter module variables. // diff --git a/build/install/rule b/build/install/rule index bed0836..af38587 100644 --- a/build/install/rule +++ b/build/install/rule @@ -14,7 +14,17 @@ namespace build { namespace install { - class rule: public build::rule + class alias_rule: public rule + { + public: + virtual match_result + match (action, target&, const std::string&) const; + + virtual recipe + apply (action, target&, const match_result&) const; + }; + + class file_rule: public rule { public: virtual bool diff --git a/build/install/rule.cxx b/build/install/rule.cxx index 64df3eb..6f0f95f 100644 --- a/build/install/rule.cxx +++ b/build/install/rule.cxx @@ -38,7 +38,52 @@ namespace build return r.simple () && r.string () == "false" ? nullptr : &r; } - match_result rule:: + // alias_rule + // + match_result alias_rule:: + match (action, target& t, const std::string&) const + { + return t; + } + + recipe alias_rule:: + apply (action a, target& t, const match_result&) const + { + tracer trace ("install::alias_rule::apply"); + + for (prerequisite p: group_prerequisites (t)) + { + target& pt (search (p)); + + // Check if this prerequisite is explicitly "not installable", + // that is, there is the 'install' variable and its value is + // false. + // + // At first, this might seem redundand since we could have let + // the file_rule below take care of it. The nuance is this: this + // prerequsite can be in a different subproject that hasn't loaded + // the install module (and therefore has no file_rule registered). + // The typical example would be the 'tests' subproject. + // + auto l (pt["install"]); + + if (l && as<dir_path> (*l).string () == "false") + { + level5 ([&]{trace << "ignoring " << pt;}); + continue; + } + + build::match (a, pt); + t.prerequisite_targets.push_back (&pt); + } + + return default_recipe; + } + + // file_rule + // + + match_result file_rule:: match (action a, target& t, const std::string&) const { // First determine if this target should be installed (called @@ -55,7 +100,7 @@ namespace build return mr; } - recipe rule:: + recipe file_rule:: apply (action a, target& t, const match_result& mr) const { if (!mr.bvalue) // Not installable. @@ -304,7 +349,7 @@ namespace build return r; } - target_state rule:: + target_state file_rule:: perform_install (action a, target& t) { file& ft (static_cast<file&> (t)); |