aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/dist/init.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/dist/init.cxx')
-rw-r--r--libbuild2/dist/init.cxx74
1 files changed, 58 insertions, 16 deletions
diff --git a/libbuild2/dist/init.cxx b/libbuild2/dist/init.cxx
index 2be4c3f..48a3e15 100644
--- a/libbuild2/dist/init.cxx
+++ b/libbuild2/dist/init.cxx
@@ -3,8 +3,9 @@
#include <libbuild2/dist/init.hxx>
-#include <libbuild2/scope.hxx>
#include <libbuild2/file.hxx>
+#include <libbuild2/rule.hxx>
+#include <libbuild2/scope.hxx>
#include <libbuild2/diagnostics.hxx>
#include <libbuild2/config/utility.hxx>
@@ -21,6 +22,7 @@ namespace build2
namespace dist
{
static const rule rule_;
+ static const file_rule file_rule_ (true /* check_type */);
void
boot (scope& rs, const location&, module_boot_extra& extra)
@@ -32,7 +34,34 @@ namespace build2
// Enter module variables. Do it during boot in case they get assigned
// in bootstrap.build (which is customary for, e.g., dist.package).
//
- auto& vp (rs.var_pool ());
+
+ // The dist flag or path. Normally it is a flag (true or false) but can
+ // also be used to remap the distribution location.
+ //
+ // In the latter case it specifies the "imaginary" source location which
+ // is used to derive the corresponding distribution local. This location
+ // can be specified as either a directory path (to remap with the same
+ // file name) or a file path (to remap with a different name). And the
+ // way we distinguish between the two is via the presence/absence of the
+ // trailing directory separator. If the path is relative, then it's
+ // treated relative to the target directory. Note that to make things
+ // less error prone, simple paths without any directory separators are
+ // not allowed (use ./<name> instead).
+ //
+ // Note that if multiple targets end up with the same source location,
+ // the behavior is undefined and no diagnostics is issued.
+ //
+ // Note also that such remapping has no effect in the bootstrap
+ // distribution mode.
+ //
+ // Note: project-private.
+ //
+ rs.var_pool ().insert<path> ("dist", variable_visibility::target);
+
+ // The rest of the variables we enter are qualified so go straight for
+ // the public variable pool.
+ //
+ auto& vp (rs.var_pool (true /* public */));
// config.dist.archives is a list of archive extensions (e.g., zip,
// tar.gz) that can be optionally prefixed with a directory. If it is
@@ -57,7 +86,7 @@ namespace build2
// The bootstrap distribution mode. Note that it can only be specified
// as a global override and is thus marked as unsaved in init(). Unlike
- // the normal load distribution mode, we can do in-source and multiple
+ // the normal load distribution mode, we can do in source and multiple
// projects at once.
//
// Note also that other config.dist.* variables can only be specified as
@@ -71,8 +100,6 @@ namespace build2
vp.insert<paths> ("dist.archives");
vp.insert<paths> ("dist.checksums");
- vp.insert<bool> ("dist", variable_visibility::target); // Flag.
-
// Project's package name. Note: if set, must be in bootstrap.build.
//
auto& v_d_p (vp.insert<string> ("dist.package"));
@@ -107,7 +134,7 @@ namespace build2
//
bool s (specified_config (rs, "dist", {"bootstrap"}));
- // dist.root
+ // config.dist.root
//
{
value& v (rs.assign ("dist.root"));
@@ -119,22 +146,24 @@ namespace build2
}
}
- // dist.cmd
+ // config.dist.cmd
+ //
+ // By default we use in-process code for creating directories and
+ // copying files (for performance, especially on Windows). But an
+ // external program (normally install) can be used if configured.
//
{
- value& v (rs.assign<process_path> ("dist.cmd"));
+ value& v (rs.assign<process_path> ("dist.cmd")); // NULL
if (s)
{
- if (lookup l = lookup_config (rs,
- "config.dist.cmd",
- path ("install")))
+ if (lookup l = lookup_config (rs, "config.dist.cmd", nullptr))
v = run_search (cast<path> (l), true);
}
}
- // dist.archives
- // dist.checksums
+ // config.dist.archives
+ // config.dist.checksums
//
{
value& a (rs.assign ("dist.archives"));
@@ -157,7 +186,7 @@ namespace build2
}
}
- // dist.uncommitted
+ // config.dist.uncommitted
//
// Omit it from the configuration unless specified.
//
@@ -182,13 +211,26 @@ namespace build2
l5 ([&]{trace << "for " << rs;});
- auto& vp (rs.var_pool ());
+ auto& vp (rs.var_pool (true /* public */)); // All qualified.
// Register our wildcard rule. Do it explicitly for the alias to prevent
// something like insert<target>(dist_id, test_id) taking precedence.
//
rs.insert_rule<target> (dist_id, 0, "dist", rule_);
- rs.insert_rule<alias> (dist_id, 0, "dist.alias", rule_); //@@ outer?
+ rs.insert_rule<alias> (dist_id, 0, "dist.alias", rule_);
+
+ // We need this rule for out-of-any-project dependencies (for example,
+ // executables imported from /usr/bin, etc). We are registering it on
+ // the global scope similar to builtin rules.
+ //
+ // Note: use target instead of anything more specific (such as
+ // mtime_target) in order not to take precedence over the "dist" rule
+ // above.
+ //
+ // See a similar rule in the config module.
+ //
+ rs.global_scope ().insert_rule<target> (
+ dist_id, 0, "dist.file", file_rule_);
// Configuration.
//