aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/install/rule.cxx36
-rw-r--r--build2/install/rule.hxx16
2 files changed, 47 insertions, 5 deletions
diff --git a/build2/install/rule.cxx b/build2/install/rule.cxx
index 18cbeae..7c13188 100644
--- a/build2/install/rule.cxx
+++ b/build2/install/rule.cxx
@@ -341,6 +341,18 @@ namespace build2
return false;
}
+ auto_rmfile file_rule::
+ install_pre (const file& t, const install_dir&) const
+ {
+ return auto_rmfile (t.path (), false /* active */);
+ }
+
+ bool file_rule::
+ install_post (const file& t, const install_dir& id, auto_rmfile&&) const
+ {
+ return install_extra (t, id);
+ }
+
struct install_dir
{
dir_path dir;
@@ -654,9 +666,10 @@ namespace build2
const install_dir& base,
const path& name,
const file& t,
+ const path& f,
bool verbose)
{
- path relf (relative (t.path ()));
+ path relf (relative (f));
dir_path chd (chroot_path (rs, base.dir));
@@ -775,10 +788,25 @@ namespace build2
if (auto l = t["install.mode"])
id.mode = &cast<string> (l);
- // Install the target and extras.
+ // Install the target.
+ //
+ auto_rmfile f (install_pre (t, id));
+
+ // If install_pre() returned a different file name, make sure we
+ // install it as the original.
//
- install_f (rs, id, n ? p.leaf () : path (), t, verbose);
- install_extra (t, id);
+ const path& tp (t.path ());
+ const path& fp (f.path);
+
+ install_f (
+ rs,
+ id,
+ n ? p.leaf () : fp.leaf () != tp.leaf () ? tp.leaf () : path (),
+ t,
+ f.path,
+ verbose);
+
+ install_post (t, id, move (f));
};
// First handle installable prerequisites.
diff --git a/build2/install/rule.hxx b/build2/install/rule.hxx
index 2ad3d4b..c84249e 100644
--- a/build2/install/rule.hxx
+++ b/build2/install/rule.hxx
@@ -11,6 +11,7 @@
#include <build2/rule.hxx>
#include <build2/target.hxx>
#include <build2/operation.hxx>
+#include <build2/filesystem.hxx>
namespace build2
{
@@ -108,7 +109,7 @@ namespace build2
static target_state
perform_update (action, const target&);
- // Extra un/installation hooks. Return true if anything was
+ // Extra un/installation hooks. Return true if anything was actually
// un/installed.
//
using install_dir = install::install_dir; // For derived rules.
@@ -119,6 +120,19 @@ namespace build2
virtual bool
uninstall_extra (const file&, const install_dir&) const;
+ // Lower-level pre/post installation hooks that can be used to override
+ // the source file path being installed (for example, to implement
+ // post-processing, etc).
+ //
+ // Note that one cannot generally perform post-processing in-place
+ // because of permissions.
+ //
+ virtual auto_rmfile
+ install_pre (const file&, const install_dir&) const;
+
+ virtual bool
+ install_post (const file&, const install_dir&, auto_rmfile&&) const;
+
// Installation/uninstallation "commands".
//
// If verbose is false, then only print the command at verbosity level 2