diff options
Diffstat (limited to 'libbuild2/install/rule.hxx')
-rw-r--r-- | libbuild2/install/rule.hxx | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/libbuild2/install/rule.hxx b/libbuild2/install/rule.hxx new file mode 100644 index 0000000..ff99c6e --- /dev/null +++ b/libbuild2/install/rule.hxx @@ -0,0 +1,197 @@ +// file : libbuild2/install/rule.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef LIBBUILD2_INSTALL_RULE_HXX +#define LIBBUILD2_INSTALL_RULE_HXX + +#include <libbuild2/types.hxx> +#include <libbuild2/utility.hxx> + +#include <libbuild2/rule.hxx> +#include <libbuild2/action.hxx> +#include <libbuild2/target.hxx> +#include <libbuild2/filesystem.hxx> + +#include <libbuild2/export.hxx> + +namespace build2 +{ + namespace install + { + class LIBBUILD2_SYMEXPORT alias_rule: public rule + { + public: + virtual bool + match (action, target&, const string&) const override; + + // Return NULL if this prerequisite should be ignored and pointer to its + // target otherwise. The default implementation accepts all prerequsites + // from the target's (weak) amalgamation. + // + // The prerequisite is passed as an iterator allowing the filter to + // "see" inside groups. + // + using prerequisite_iterator = + prerequisite_members_range<group_prerequisites>::iterator; + + virtual const target* + filter (action, const target&, prerequisite_iterator&) const; + + virtual const target* + filter (action, const target&, const prerequisite&) const; + + virtual recipe + apply (action, target&) const override; + + alias_rule () {} + static const alias_rule instance; + }; + + class fsdir_rule: public rule + { + public: + virtual bool + match (action, target&, const string&) const override; + + virtual recipe + apply (action, target&) const override; + + fsdir_rule () {} + static const fsdir_rule instance; + }; + + // In addition to the alias rule's semantics, this rule sees through to + // the group's members. + // + // The default group_rule::instance matches any target for which it was + // registered. It is to be used for non-see-through groups that should + // exhibit the see-through behavior for install (see lib{} in the bin + // module for an example). + // + // We also register (for all targets) another instance of this rule that + // only matches see-through groups. + // + class LIBBUILD2_SYMEXPORT group_rule: public alias_rule + { + public: + virtual bool + match (action, target&, const string&) const override; + + // Return NULL if this group member should be ignored and pointer to its + // target otherwise. The default implementation accepts all members. + // + virtual const target* + filter (action, const target&, const target& group_member) const; + + using alias_rule::filter; // "Unhide" to make Clang happy. + + virtual recipe + apply (action, target&) const override; + + group_rule (bool see_through_only): see_through (see_through_only) {} + static const group_rule instance; + + bool see_through; + }; + + struct install_dir; + + class LIBBUILD2_SYMEXPORT file_rule: public rule + { + public: + virtual bool + match (action, target&, const string&) const override; + + // 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. + // + // @@ 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... + // + // The prerequisite is passed as an iterator allowing the filter to + // "see" inside groups. + // + using prerequisite_iterator = + prerequisite_members_range<group_prerequisites>::iterator; + + virtual const target* + filter (action, const target&, prerequisite_iterator&) const; + + virtual const target* + filter (action, const target&, const prerequisite&) const; + + virtual recipe + apply (action, target&) const override; + + static target_state + perform_update (action, const target&); + + // Extra un/installation hooks. Return true if anything was actually + // un/installed. + // + using install_dir = install::install_dir; // For derived rules. + + virtual bool + install_extra (const file&, const install_dir&) const; + + 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 + // or higher. Note that these functions respect the dry_run flag. + + // Install a symlink: base/link -> target. + // + static void + install_l (const scope& rs, + const install_dir& base, + const path& target, + const path& link, + bool verbose); + + // Uninstall a file or symlink: + // + // uninstall <target> <base>/ rm <base>/<target>.leaf (); name empty + // uninstall <target> <name> rm <base>/<name>; target can be NULL + // + // Return false if nothing has been removed (i.e., the file does not + // exist). + // + static bool + uninstall_f (const scope& rs, + const install_dir& base, + const file* target, + const path& name, + bool verbose); + + target_state + perform_install (action, const target&) const; + + target_state + perform_uninstall (action, const target&) const; + + static const file_rule instance; + file_rule () {} + }; + } +} + +#endif // LIBBUILD2_INSTALL_RULE_HXX |