From 8276cb927bafd338be237adbecf437e70042da99 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 26 Apr 2017 15:52:15 +0200 Subject: Implement version module --- build2/dist/init.cxx | 54 +++++++++++++++++++++------------------ build2/dist/module | 65 +++++++++++++++++++++++++++++++++++++++++++++++ build2/dist/module.cxx | 15 +++++++++++ build2/dist/operation.cxx | 44 ++++++++++++++++++++++++++++---- 4 files changed, 148 insertions(+), 30 deletions(-) create mode 100644 build2/dist/module create mode 100644 build2/dist/module.cxx (limited to 'build2/dist') 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 #include +#include #include using namespace std; @@ -23,7 +24,7 @@ namespace build2 static const rule rule_; void - boot (scope& rs, const location&, unique_ptr&) + boot (scope& rs, const location&, unique_ptr& 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 ("config.dist.root", true); - v.insert ("config.dist.archives", true); - v.insert ("config.dist.cmd", true); - - v.insert ("dist.root"); - v.insert ("dist.cmd"); - v.insert ("dist.archives"); - - v.insert ("dist", variable_visibility::target); // Flag. - - // Project's package name. - // - v.insert ("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 ("config.dist.root", true); + vp.insert ("config.dist.archives", true); + vp.insert ("config.dist.cmd", true); + + vp.insert ("dist.root"); + vp.insert ("dist.cmd"); + vp.insert ("dist.archives"); + + vp.insert ("dist", variable_visibility::target); // Flag. + + // Project's package name. + // + auto& v_d_p ( + vp.insert ("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 +#include + +#include +#include + +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 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 + +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 +#include // path_match() + #include #include #include @@ -13,6 +15,8 @@ #include #include +#include + using namespace std; using namespace butl; @@ -27,7 +31,9 @@ namespace build2 // install // - static void + // Return the destination file path. + // + static path install (const process_path& cmd, const file&, const dir_path&); // cd && tar|zip ... /. @@ -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::name)); + for (const void* v: files) { const file& t (*static_cast (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 // - 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 -- cgit v1.1