aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/install/init.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-04-04 08:05:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-04-04 08:05:21 +0200
commit7b06ee81ab0e8a2199c4dce07ec67282c4f52f62 (patch)
tree70d2d0d47a8c572cfe3e56b5f892694fca11ae5a /libbuild2/install/init.cxx
parent31b32815407db4263c2aad3c4ca721fd8a9f3c8a (diff)
Add support for installation filtering (GH issue #147)
Diffstat (limited to 'libbuild2/install/init.cxx')
-rw-r--r--libbuild2/install/init.cxx76
1 files changed, 74 insertions, 2 deletions
diff --git a/libbuild2/install/init.cxx b/libbuild2/install/init.cxx
index f0402ca..69f578b 100644
--- a/libbuild2/install/init.cxx
+++ b/libbuild2/install/init.cxx
@@ -421,9 +421,10 @@ namespace build2
using config::lookup_config;
using config::specified_config;
- // Note: ignore config.install.{scope,manifest} (see below).
+ // Note: ignore config.install.{scope,filter,manifest} (see below).
//
- bool s (specified_config (rs, "install", {"scope", "manifest"}));
+ bool s (specified_config (
+ rs, "install", {"scope", "filter", "manifest"}));
// Adjust module priority so that the (numerous) config.install.*
// values are saved at the end of config.build.
@@ -460,6 +461,77 @@ namespace build2
config::unsave_variable (rs, v);
}
+ // config.install.filter
+ //
+ // Installation filterting. The value of this variable is a list of
+ // key-value pairs that specify the filesystem entries to include or
+ // exclude from the installation. For example, the following filters
+ // will omit installing headers and static libraries (notice the
+ // quoting of the wildcard).
+ //
+ // !config.install.filter='include/@false "*.a"@false'
+ //
+ // The key in each pair is a file or directory path or a path wildcard
+ // pattern. If a key is relative and contains a directory component or
+ // is a directory, then it is treated relative to the corresponding
+ // config.install.* location. Otherwise (simple path, normally a
+ // pattern), it is matched against the leaf of any path. Note that if
+ // an absolute path is specified, it should be without the
+ // config.install.chroot prefix.
+ //
+ // The value in each pair is either true (include) or false (exclude).
+ // The filters are evaluated in the order specified and the first
+ // match that is found determines the outcome. If no match is found,
+ // the default is to include. For a directory, while false means
+ // exclude all the sub-paths inside this directory, true does not mean
+ // that all the sub-paths will be included wholesale. Rather, the
+ // matched component of the sub-path is treated as included with the
+ // rest of the components matched against the following
+ // sub-filters. For example:
+ //
+ // !config.install.filter='
+ // include/x86_64-linux-gnu/@true
+ // include/x86_64-linux-gnu/details/@false
+ // include/@false'
+ //
+ // The true or false value may be followed by comma and the `symlink`
+ // modifier to only apply to symlink filesystem entries. For example:
+ //
+ // !config.install.filter='"*.so"@false,symlink'
+ //
+ // Note that this mechanism only affects what gets physically copied
+ // to the installation directory without affecting what gets built for
+ // install or the view of what gets installed at the buildfile level.
+ // For example, given the `include/@false *.a@false` filters, static
+ // libraries will still be built (unless arranged not to with
+ // config.bin.lib) and the pkg-config files will still end up with -I
+ // options pointing to the header installation directory. Note also
+ // that this mechanism applies to both install and uninstall
+ // operations.
+ //
+ // If you are familiar with the Debian or Fedora packaging, this
+ // mechanism is somewhat similar to (and can be used for a similar
+ // purpose as) the Debian's .install files and Fedora's %files spec
+ // file sections that are used to split the installation into multiple
+ // binary packages.
+ //
+ // Note: can only be specified as a global override.
+ //
+ {
+ auto& v (vp.insert<filters> ("config.install.filter"));
+
+ // If specified, verify it is a global override.
+ //
+ if (lookup l = rs[v])
+ {
+ if (!l.belongs (rs.global_scope ()))
+ fail << "config.install.filter must be a global override" <<
+ info << "specify !config.install.filter=...";
+ }
+
+ config::unsave_variable (rs, v);
+ }
+
// config.install.manifest
//
// Installation manifest. Valid values are a file path or `-` to dump