aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/install/rule.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/install/rule.hxx')
-rw-r--r--libbuild2/install/rule.hxx209
1 files changed, 168 insertions, 41 deletions
diff --git a/libbuild2/install/rule.hxx b/libbuild2/install/rule.hxx
index 73f2486..b023af5 100644
--- a/libbuild2/install/rule.hxx
+++ b/libbuild2/install/rule.hxx
@@ -22,10 +22,18 @@ namespace build2
{
public:
virtual bool
- match (action, target&, const string&) const override;
+ match (action, target&) const override;
// Return NULL if this prerequisite should be ignored and pointer to its
- // target otherwise. The default implementation allows all prerequsites.
+ // target otherwise. In the latter case, return the match options that
+ // should be used for this prerequisite (use match_extra::all_options
+ // and not 0 if no match options are needed).
+ //
+ // The default implementation ignores prerequsites that are outside of
+ // the installation scope (see install_scope() for details).
+ //
+ // The default implementation always returns match_extra::all_options.
+ // The match_extra argument is not used by the default implementation.
//
// The prerequisite is passed as an iterator allowing the filter to
// "see" inside groups.
@@ -33,30 +41,44 @@ namespace build2
using prerequisite_iterator =
prerequisite_members_range<group_prerequisites>::iterator;
- virtual const target*
- filter (action, const target&, prerequisite_iterator&) const;
+ virtual pair<const target*, uint64_t>
+ filter (const scope*,
+ action, const target&, prerequisite_iterator&,
+ match_extra&) const;
- virtual const target*
- filter (action, const target&, const prerequisite&) const;
+ virtual pair<const target*, uint64_t>
+ filter (const scope*,
+ action, const target&, const prerequisite&,
+ match_extra&) const;
+ // Note: rule::apply() override (with match_extra).
+ //
virtual recipe
- apply (action, target&) const override;
+ apply (action, target&, match_extra&) const override;
+
+ // Implementation of apply().
+ //
+ // If the implementation may call reapply_impl(), then the reapply
+ // argument to apply_impl() must be true. Note that in this case, the
+ // *_impl() functions use the prerequisite_target::data member for own
+ // housekeeping.
+ //
+ recipe
+ apply_impl (action, target&, match_extra&, bool reapply = false) const;
+
+ // Implementation of reapply() that re-tries prerequisites that have
+ // been filtered out during the reapply() call. Note that currently not
+ // supported for update, only for install/uninstall.
+ //
+ void
+ reapply_impl (action, target&, match_extra&) const;
alias_rule () {}
static const alias_rule instance;
- };
-
- class fsdir_rule: public simple_rule
- {
- public:
- virtual bool
- match (action, target&, const string&) const override;
+ private:
virtual recipe
- apply (action, target&) const override;
-
- fsdir_rule () {}
- static const fsdir_rule instance;
+ apply (action, target&) const override; // Dummy simple_rule override.
};
// In addition to the alias rule's semantics, this rule sees through to
@@ -74,23 +96,33 @@ namespace build2
{
public:
virtual bool
- match (action, target&, const string&) const override;
+ match (action, target&) const override;
- // Return NULL if this group member should be ignored and pointer to its
- // target otherwise. The default implementation accepts all members.
+ // Return false if this group member should be ignored and true
+ // otherwise. Note that this filter is called during apply().
+ //
+ // The default implementation accepts all members.
//
- virtual const target*
+ virtual bool
filter (action, const target&, const target& group_member) const;
+ // Return NULL if this prerequisite should be ignored and pointer to its
+ // target otherwise. The same semantics as in file_rule below.
+ //
+ virtual pair<const target*, uint64_t>
+ filter (const scope*,
+ action, const target&, const prerequisite&,
+ match_extra&) const override;
+
using alias_rule::filter; // "Unhide" to make Clang happy.
virtual recipe
- apply (action, target&) const override;
+ apply (action, target&, match_extra&) const override;
- group_rule (bool see_through_only): see_through (see_through_only) {}
+ group_rule (bool sto): see_through_only (sto) {}
static const group_rule instance;
- bool see_through;
+ bool see_through_only;
};
struct install_dir;
@@ -99,15 +131,36 @@ namespace build2
{
public:
virtual bool
- match (action, target&, const string&) const override;
+ match (action, target&) const override;
+
+ // Return false if this ad hoc group member should be ignored and true
+ // otherwise. Note that this filter is called during execute and only
+ // for install/uninstall (and not update). For generality, it is also
+ // (first) called on the target itself (can be detected by comparing
+ // the second and third arguments).
+ //
+ // The default implementation accepts all members.
+ //
+ virtual bool
+ filter (action, const target&, const target& adhoc_group_member) const;
// Return NULL if this prerequisite should be ignored and pointer to its
- // target otherwise. The default implementation ignores prerequsites
- // that are outside of this target's project.
+ // target otherwise. In the latter case, return the match options that
+ // should be used for this prerequisite (use match_extra::all_options
+ // and not 0 if no match options are needed).
+ //
+ // The default implementation ignores prerequsites that are outside of
+ // the installation scope (see install_scope() for details). It also
+ // ignores exe{} prerequisites assuming an exe{} listed for a file
+ // target is there to execute (e.g., to generate that target) and
+ // normally should not be installed (an exe{} would typically be
+ // installed via the dir{./} alias). But this can be overridden with a
+ // prerequisite-specific install=true, for example:
//
- // @@ I wonder why we do weak amalgamation for alias but project for
- // file? And then override this for prerequisite libraries/modules
- // in cc::install_rule and bash::install_rule...
+ // exe{foo}: exe{bar}: install = true # foo runs bar
+ //
+ // The default implementation always returns match_extra::all_options.
+ // The match_extra argument is not used by the default implementation.
//
// The prerequisite is passed as an iterator allowing the filter to
// "see" inside groups.
@@ -115,14 +168,38 @@ namespace build2
using prerequisite_iterator =
prerequisite_members_range<group_prerequisites>::iterator;
- virtual const target*
- filter (action, const target&, prerequisite_iterator&) const;
+ virtual pair<const target*, uint64_t>
+ filter (const scope*,
+ action, const target&, prerequisite_iterator&,
+ match_extra&) const;
- virtual const target*
- filter (action, const target&, const prerequisite&) const;
+ virtual pair<const target*, uint64_t>
+ filter (const scope*,
+ action, const target&, const prerequisite&,
+ match_extra&) const;
+ // Note: rule::apply() override (with match_extra).
+ //
virtual recipe
- apply (action, target&) const override;
+ apply (action, target&, match_extra&) const override;
+
+ // Implementation of apply() that returns empty_recipe (i.e., NULL) if
+ // the target is not installable.
+ //
+ // If the implementation may call reapply_impl(), then the reapply
+ // argument to apply_impl() must be true. Note that in this case, the
+ // *_impl() functions use the prerequisite_target::data member for own
+ // housekeeping.
+ //
+ recipe
+ apply_impl (action, target&, match_extra&, bool reapply = false) const;
+
+ // Implementation of reapply() that re-tries prerequisites that have
+ // been filtered out during the reapply() call. Note that currently not
+ // supported for update, only for install/uninstall.
+ //
+ void
+ reapply_impl (action, target&, match_extra&) const;
static target_state
perform_update (action, const target&);
@@ -160,10 +237,16 @@ namespace build2
//
// install -d <dir>
//
+ // Note: <dir> is expected to be absolute.
+ //
+ // Note that the target argument only specifies which target caused
+ // this directory to be created.
+ //
static void
install_d (const scope& rs,
const install_dir& base,
const dir_path& dir,
+ const file& target,
uint16_t verbosity = 1);
// Install a file:
@@ -171,6 +254,8 @@ namespace build2
// install <file> <base>/ # if <name> is empty
// install <file> <base>/<name> # if <name> is not empty
//
+ // Note that <name> should be a simple path.
+ //
static void
install_f (const scope& rs,
const install_dir& base,
@@ -181,13 +266,25 @@ namespace build2
// Install (make) a symlink:
//
- // ln -s <target> <base>/<link>
+ // install -l <link_target> <base>/<link>
+ //
+ // Which is essentially:
+ //
+ // ln -s <link_target> <base>/<link>
+ //
+ // Note that <link> should be a simple path. Note that <link_target>
+ // must not be absolute if relocatable installation is requested
+ // (config.install.relocatable).
+ //
+ // Note that the target argument only specifies which target this
+ // symlink "belongs" to.
//
static void
install_l (const scope& rs,
const install_dir& base,
- const path& target,
const path& link,
+ const file& target,
+ const path& link_target,
uint16_t verbosity = 1);
// Uninstall (remove) a file or symlink:
@@ -205,13 +302,26 @@ namespace build2
const path& name,
uint16_t verbosity = 1);
+ // Uninstall (remove) a symlink.
+ //
+ // This is essentially unistall_f() but with better low-verbosity
+ // diagnostics.
+ //
+ static bool
+ uninstall_l (const scope& rs,
+ const install_dir& base,
+ const path& link,
+ const path& link_target,
+ uint16_t verbosity = 1);
+
+
// Uninstall (remove) an empty directory.
//
// uninstall -d <dir>
//
- // We try to remove all the directories between base and dir but not base
- // itself unless base == dir. Return false if nothing has been removed
- // (i.e., the directories do not exist or are not empty).
+ // We try to remove all the directories between base and dir but not
+ // base itself unless base == dir. Return false if nothing has been
+ // removed (i.e., the directories do not exist or are not empty).
//
static bool
uninstall_d (const scope& rs,
@@ -227,6 +337,23 @@ namespace build2
static const file_rule instance;
file_rule () {}
+
+ private:
+ virtual recipe
+ apply (action, target&) const override; // Dummy simple_rule override.
+ };
+
+ class fsdir_rule: public simple_rule
+ {
+ public:
+ virtual bool
+ match (action, target&) const override;
+
+ virtual recipe
+ apply (action, target&) const override;
+
+ fsdir_rule () {}
+ static const fsdir_rule instance;
};
}
}