aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/cxx/install2
-rw-r--r--build/cxx/install.cxx2
-rw-r--r--build/install/module.cxx8
-rw-r--r--build/install/rule12
-rw-r--r--build/install/rule.cxx51
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));