aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/b.cxx2
-rw-r--r--build/buildfile3
-rw-r--r--build/config/utility7
-rw-r--r--build/install/module21
-rw-r--r--build/install/module.cxx105
-rw-r--r--build/install/operation18
-rw-r--r--build/install/operation.cxx34
-rw-r--r--build/variable12
-rw-r--r--tests/install/simple/build/bootstrap.build4
-rw-r--r--tests/install/simple/buildfile6
-rw-r--r--tests/install/simple/driver.cxx2
11 files changed, 207 insertions, 7 deletions
diff --git a/build/b.cxx b/build/b.cxx
index 21e72cf..fea5690 100644
--- a/build/b.cxx
+++ b/build/b.cxx
@@ -45,6 +45,7 @@ using namespace std;
#include <build/cxx/module>
#include <build/cli/module>
#include <build/test/module>
+#include <build/install/module>
using namespace build;
@@ -96,6 +97,7 @@ main (int argc, char* argv[])
builtin_modules["cxx"] = &cxx::cxx_init;
builtin_modules["cli"] = &cli::cli_init;
builtin_modules["test"] = &test::test_init;
+ builtin_modules["install"] = &install::install_init;
// Figure out work and home directories.
//
diff --git a/build/buildfile b/build/buildfile
index a6715de..ceda4eb 100644
--- a/build/buildfile
+++ b/build/buildfile
@@ -9,11 +9,12 @@ bin = bin/{target rule module}
cxx = cxx/{target compile link module utility}
cli = cli/{target rule module}
test = test/{operation rule module}
+install = install/{operation module}
exe{b}: cxx{b algorithm name operation spec scope variable target \
prerequisite rule file module context search diagnostics token \
lexer parser path-io utility dump options $config $bin $cxx $cli \
- $test} $libs
+ $test $install} $libs
#@@ TODO
#
diff --git a/build/config/utility b/build/config/utility
index e1d81a7..713ab01 100644
--- a/build/config/utility
+++ b/build/config/utility
@@ -41,6 +41,13 @@ namespace build
const T*
optional (scope& root, const char* name);
+ template <typename T>
+ inline const T*
+ optional (scope& root, const std::string& name)
+ {
+ return optional<T> (root, name.c_str ());
+ }
+
// Add all the values from a variable to the C-string list. T is
// either target or scope.
//
diff --git a/build/install/module b/build/install/module
new file mode 100644
index 0000000..240d034
--- /dev/null
+++ b/build/install/module
@@ -0,0 +1,21 @@
+// file : build/install/module -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BUILD_INSTALL_MODULE
+#define BUILD_INSTALL_MODULE
+
+#include <build/types>
+#include <build/module>
+
+namespace build
+{
+ namespace install
+ {
+ extern "C" void
+ install_init (
+ scope&, scope&, const location&, std::unique_ptr<module>&, bool);
+ }
+}
+
+#endif // BUILD_INSTALL_MODULE
diff --git a/build/install/module.cxx b/build/install/module.cxx
new file mode 100644
index 0000000..dc88ec2
--- /dev/null
+++ b/build/install/module.cxx
@@ -0,0 +1,105 @@
+// file : build/install/module.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <build/install/module>
+
+#include <build/scope>
+#include <build/target>
+#include <build/rule>
+#include <build/diagnostics>
+
+#include <build/config/utility>
+
+#include <build/install/operation>
+
+using namespace std;
+using namespace butl;
+
+namespace build
+{
+ namespace install
+ {
+ // Set install.<name> values based on config.install.<name> values
+ // or the defaults.
+ //
+ static void
+ set_dir (scope& r, const char* name, const char* path, const char* mode)
+ {
+ string vn ("config.install.");
+ vn += name;
+
+ const list_value* pv (config::optional<list_value> (r, vn));
+
+ vn += ".mode";
+ const list_value* mv (config::optional<list_value> (r, vn));
+
+ vn = "install.";
+ vn += name;
+ auto p (r.assign (vn));
+
+ if (pv != nullptr && !pv->empty ())
+ p = *pv;
+ else if (path != nullptr)
+ p = path;
+
+ vn += ".mode";
+ auto m (r.assign (vn));
+
+ if (mv != nullptr && !mv->empty ())
+ p = *mv;
+ else if (mode != nullptr)
+ p = mode;
+ }
+
+ extern "C" void
+ install_init (scope& root,
+ scope& base,
+ const location& l,
+ unique_ptr<build::module>&,
+ bool first)
+ {
+ tracer trace ("install::init");
+
+ if (&root != &base)
+ fail (l) << "install module must be initialized in bootstrap.build";
+
+ if (!first)
+ {
+ warn (l) << "multiple install module initializations";
+ return;
+ }
+
+ const dir_path& out_root (root.path ());
+ level4 ([&]{trace << "for " << out_root;});
+
+ // Register the install operation.
+ //
+ operation_id install_id (root.operations.insert (install));
+
+ {
+ auto& rs (base.rules);
+
+ // Register the standard alias rule for the install operation.
+ //
+ rs.insert<alias> (install_id, "alias", alias_rule::instance);
+ }
+
+ // Configuration.
+ //
+ // Note that we don't use any defaults -- the location must
+ // be explicitly specified or the installer will complain if
+ // and when we try to install.
+ //
+ if (first)
+ {
+ set_dir (root, "root", nullptr, nullptr);
+ set_dir (root, "data_root", "root", "644");
+ set_dir (root, "exec_root", "root", "755");
+
+ set_dir (root, "bin", "exec_root/bin", nullptr);
+ set_dir (root, "sbin", "exec_root/sbin", nullptr);
+ }
+ }
+ }
+}
diff --git a/build/install/operation b/build/install/operation
new file mode 100644
index 0000000..2763d10
--- /dev/null
+++ b/build/install/operation
@@ -0,0 +1,18 @@
+// file : build/install/operation -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BUILD_INSTALL_OPERATION
+#define BUILD_INSTALL_OPERATION
+
+#include <build/operation>
+
+namespace build
+{
+ namespace install
+ {
+ extern operation_info install;
+ }
+}
+
+#endif // BUILD_INSTALL_OPERATION
diff --git a/build/install/operation.cxx b/build/install/operation.cxx
new file mode 100644
index 0000000..1ba001f
--- /dev/null
+++ b/build/install/operation.cxx
@@ -0,0 +1,34 @@
+// file : build/install/operation.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <build/install/operation>
+
+#include <build/config/operation>
+
+using namespace std;
+using namespace butl;
+
+namespace build
+{
+ namespace install
+ {
+ static operation_id
+ install_pre (meta_operation_id mo)
+ {
+ // Run update as a pre-operation, unless we are disfiguring.
+ //
+ return mo != config::disfigure_id ? update_id : 0;
+ }
+
+ operation_info install {
+ "install",
+ "install",
+ "installing",
+ "has nothing to install", // We cannot "be installed".
+ execution_mode::first,
+ &install_pre,
+ nullptr
+ };
+ }
+}
diff --git a/build/variable b/build/variable
index 368b2f8..809e7d2 100644
--- a/build/variable
+++ b/build/variable
@@ -166,20 +166,20 @@ namespace build
//
template <typename T>
bool
- belongs (const T& x) const {return map == &x.vars;}
+ belongs (const T& x) const {return vars == &x.vars;}
// Implementation details.
//
- const variable_map* map; // Variable map to which this value belongs.
+ const variable_map* vars; // Variable map to which this value belongs.
- value_proxy (): map (nullptr), p (nullptr) {}
- value_proxy (value_ptr* p, const variable_map* m): map (m), p (p) {}
+ value_proxy (): vars (nullptr), p (nullptr) {}
+ value_proxy (value_ptr* p, const variable_map* v): vars (v), p (p) {}
template <typename T>
- value_proxy (value_ptr& p, const T& x): map (&x.vars), p (&p) {}
+ value_proxy (value_ptr& p, const T& x): vars (&x.vars), p (&p) {}
void
- rebind (const value_proxy& x) {map = x.map; p = x.p;}
+ rebind (const value_proxy& x) {vars = x.vars; p = x.p;}
private:
value_ptr* p;
diff --git a/tests/install/simple/build/bootstrap.build b/tests/install/simple/build/bootstrap.build
new file mode 100644
index 0000000..40e665b
--- /dev/null
+++ b/tests/install/simple/build/bootstrap.build
@@ -0,0 +1,4 @@
+project = install-simple
+amalgamation = # Disabled.
+using config
+using install
diff --git a/tests/install/simple/buildfile b/tests/install/simple/buildfile
new file mode 100644
index 0000000..986f391
--- /dev/null
+++ b/tests/install/simple/buildfile
@@ -0,0 +1,6 @@
+using cxx
+
+hxx.ext = hxx
+cxx.ext = cxx
+
+exe{driver}: cxx{driver}
diff --git a/tests/install/simple/driver.cxx b/tests/install/simple/driver.cxx
new file mode 100644
index 0000000..a444f13
--- /dev/null
+++ b/tests/install/simple/driver.cxx
@@ -0,0 +1,2 @@
+int main () {}
+