aboutsummaryrefslogtreecommitdiff
path: root/build2/dist
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-26 15:52:15 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-26 15:53:23 +0200
commit8276cb927bafd338be237adbecf437e70042da99 (patch)
tree49218b58e1f50a65b58674177e6047f1ac9f6831 /build2/dist
parent2fd9d3f177429b20797897360931badedbb0f0ef (diff)
Implement version module
Diffstat (limited to 'build2/dist')
-rw-r--r--build2/dist/init.cxx54
-rw-r--r--build2/dist/module65
-rw-r--r--build2/dist/module.cxx15
-rw-r--r--build2/dist/operation.cxx44
4 files changed, 148 insertions, 30 deletions
diff --git a/build2/dist/init.cxx b/build2/dist/init.cxx
index be7b381..41927cd 100644
--- a/build2/dist/init.cxx
+++ b/build2/dist/init.cxx
@@ -11,6 +11,7 @@
#include <build2/config/utility>
#include <build2/dist/rule>
+#include <build2/dist/module>
#include <build2/dist/operation>
using namespace std;
@@ -23,7 +24,7 @@ namespace build2
static const rule rule_;
void
- boot (scope& rs, const location&, unique_ptr<module_base>&)
+ boot (scope& rs, const location&, unique_ptr<module_base>& mod)
{
tracer trace ("dist::boot");
@@ -36,30 +37,33 @@ 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& v (var_pool.rw (rs));
-
- // Note: some overridable, some not.
- //
- // config.dist.archives is a list of archive extensions that can be
- // optionally prefixed with a directory. If it is relative, then it is
- // prefixed with config.dist.root. Otherwise, the archive is written
- // to the absolute location.
- //
- v.insert<abs_dir_path> ("config.dist.root", true);
- v.insert<paths> ("config.dist.archives", true);
- v.insert<path> ("config.dist.cmd", true);
-
- v.insert<dir_path> ("dist.root");
- v.insert<process_path> ("dist.cmd");
- v.insert<paths> ("dist.archives");
-
- v.insert<bool> ("dist", variable_visibility::target); // Flag.
-
- // Project's package name.
- //
- v.insert<string> ("dist.package", variable_visibility::project);
- }
+ auto& vp (var_pool.rw (rs));
+
+ // Note: some overridable, some not.
+ //
+ // config.dist.archives is a list of archive extensions that can be
+ // optionally prefixed with a directory. If it is relative, then it is
+ // prefixed with config.dist.root. Otherwise, the archive is written
+ // to the absolute location.
+ //
+ vp.insert<abs_dir_path> ("config.dist.root", true);
+ vp.insert<paths> ("config.dist.archives", true);
+ vp.insert<path> ("config.dist.cmd", true);
+
+ vp.insert<dir_path> ("dist.root");
+ vp.insert<process_path> ("dist.cmd");
+ vp.insert<paths> ("dist.archives");
+
+ vp.insert<bool> ("dist", variable_visibility::target); // Flag.
+
+ // Project's package name.
+ //
+ auto& v_d_p (
+ vp.insert<string> ("dist.package", variable_visibility::project));
+
+ // Create the module.
+ //
+ mod.reset (new module (v_d_p));
}
bool
diff --git a/build2/dist/module b/build2/dist/module
new file mode 100644
index 0000000..5510423
--- /dev/null
+++ b/build2/dist/module
@@ -0,0 +1,65 @@
+// file : build2/dist/module -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BUILD2_DIST_MODULE
+#define BUILD2_DIST_MODULE
+
+#include <build2/types>
+#include <build2/utility>
+
+#include <build2/module>
+#include <build2/variable>
+
+namespace build2
+{
+ namespace dist
+ {
+ struct module: module_base
+ {
+ static const string name;
+
+ const variable& var_dist_package;
+
+ // Distribution post-processing callbacks.
+ //
+ // The last component in the pattern may contain shell wildcards. If the
+ // path contains a directory, then it is matched from the distribution
+ // root only. Otherwise, it is matched against all the files being
+ // distributed. For example:
+ //
+ // buildfile - every buildfile
+ // ./buildfile - root buildfile only
+ // tests/buildfile - tests/buildfile only
+ //
+ // The callback is called with the absolute path of the matching file
+ // after it has been copied to the distribution directory. The project's
+ // root scope and callback-specific data are passed along.
+ //
+ using callback_func = void (const path&, const scope&, void*);
+
+ void
+ register_callback (path pattern, callback_func* f, void* data)
+ {
+ callbacks_.push_back (callback {move (pattern), f, data});
+ }
+
+ // Implementation details.
+ //
+ module (const variable& v_d_p)
+ : var_dist_package (v_d_p) {}
+
+ public:
+ struct callback
+ {
+ const path pattern;
+ callback_func* function;
+ void* data;
+ };
+
+ vector<callback> callbacks_;
+ };
+ }
+}
+
+#endif // BUILD2_DIST_MODULE
diff --git a/build2/dist/module.cxx b/build2/dist/module.cxx
new file mode 100644
index 0000000..05ca1cb
--- /dev/null
+++ b/build2/dist/module.cxx
@@ -0,0 +1,15 @@
+// file : build2/dist/module.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <build2/dist/module>
+
+using namespace std;
+
+namespace build2
+{
+ namespace dist
+ {
+ const string module::name ("dist");
+ }
+}
diff --git a/build2/dist/operation.cxx b/build2/dist/operation.cxx
index 033748e..859225d 100644
--- a/build2/dist/operation.cxx
+++ b/build2/dist/operation.cxx
@@ -4,6 +4,8 @@
#include <build2/dist/operation>
+#include <butl/filesystem> // path_match()
+
#include <build2/file>
#include <build2/dump>
#include <build2/scope>
@@ -13,6 +15,8 @@
#include <build2/filesystem>
#include <build2/diagnostics>
+#include <build2/dist/module>
+
using namespace std;
using namespace butl;
@@ -27,7 +31,9 @@ namespace build2
// install <file> <dir>
//
- static void
+ // Return the destination file path.
+ //
+ static path
install (const process_path& cmd, const file&, const dir_path&);
// cd <root> && tar|zip ... <dir>/<pkg>.<ext> <pkg>
@@ -286,23 +292,49 @@ namespace build2
install (dist_cmd, td);
- // Copy over all the files.
+ // Copy over all the files. Apply post-processing callbacks.
//
+ module& mod (*rs->modules.lookup<module> (module::name));
+
for (const void* v: files)
{
const file& t (*static_cast<const file*> (v));
// Figure out where this file is inside the target directory.
//
+ bool src (t.dir.sub (src_root));
+
dir_path d (td);
- d /= t.dir.sub (src_root)
+ d /= src
? t.dir.leaf (src_root)
: t.dir.leaf (out_root);
if (!exists (d))
install (dist_cmd, d);
- install (dist_cmd, t, d);
+ path r (install (dist_cmd, t, d));
+
+ for (module::callback cb: mod.callbacks_)
+ {
+ const path& pat (cb.pattern);
+
+ // If we have a directory, then it should be relative to the project
+ // root.
+ //
+ if (!pat.simple ())
+ {
+ assert (pat.relative ());
+
+ dir_path d ((src ? src_root : out_root) / pat.directory ());
+ d.normalize ();
+
+ if (d != t.dir)
+ continue;
+ }
+
+ if (path_match (pat.leaf ().string (), t.path ().leaf ().string ()))
+ cb.function (r, *rs, cb.data);
+ }
}
// Archive if requested.
@@ -367,7 +399,7 @@ namespace build2
// install <file> <dir>
//
- static void
+ static path
install (const process_path& cmd, const file& t, const dir_path& d)
{
dir_path reld (relative (d));
@@ -417,6 +449,8 @@ namespace build2
throw failed ();
}
+
+ return d / relf.leaf ();
}
static void