aboutsummaryrefslogtreecommitdiff
path: root/build/install
diff options
context:
space:
mode:
Diffstat (limited to 'build/install')
-rw-r--r--build/install/module.cxx139
-rw-r--r--build/install/rule.cxx86
-rw-r--r--build/install/utility20
3 files changed, 120 insertions, 125 deletions
diff --git a/build/install/module.cxx b/build/install/module.cxx
index 834b0e8..610154a 100644
--- a/build/install/module.cxx
+++ b/build/install/module.cxx
@@ -29,54 +29,64 @@ namespace build
// to set all the install.* values to defaults, as if we had the
// default configuration.
//
+ template <typename T>
static void
- set_dir (bool spec,
+ set_var (bool spec,
scope& r,
const char* name,
- const char* path,
- const char* mode = nullptr,
- const char* dir_mode = nullptr,
- const char* cmd = nullptr,
- const char* options = nullptr)
+ const char* var,
+ const T* dv)
{
- auto set = [spec, &r, name] (const char* var, const char* dv)
- {
- string vn;
- const list_value* lv (nullptr);
-
- if (spec)
- {
- vn = "config.install.";
- vn += name;
- vn += var;
-
- lv = dv != nullptr
- ? &config::required (r, vn, list_value (dv)).first
- : config::optional<list_value> (r, vn);
- }
-
- vn = "install.";
- vn += name;
- vn += var;
- auto v (r.assign (vn));
-
- if (spec)
- {
- if (lv != nullptr && !lv->empty ())
- v = *lv;
- }
- else
- {
- if (dv != nullptr)
- v = dv;
- }
- };
-
- set ("", path);
- set (".mode", mode);
- set (".dir_mode", dir_mode);
- set (".cmd", cmd);
- set (".options", options);
+ string vn;
+ const value* cv (nullptr);
+
+ if (spec)
+ {
+ vn = "config.install.";
+ vn += name;
+ vn += var;
+ const variable& vr (
+ variable_pool.find (move (vn), &value_traits<T>::value_type));
+
+ cv = dv != nullptr
+ ? &config::required (r, vr, *dv).first.get ()
+ : &config::optional (r, vr);
+ }
+
+ vn = "install.";
+ vn += name;
+ vn += var;
+ const variable& vr (
+ variable_pool.find (move (vn), &value_traits<T>::value_type));
+
+ value& v (r.assign (vr));
+
+ if (spec)
+ {
+ if (cv != nullptr && *cv && !cv->empty ())
+ v = *cv;
+ }
+ else
+ {
+ if (dv != nullptr)
+ v = *dv;
+ }
+ }
+
+ static void
+ set_dir (bool s,
+ scope& r,
+ const char* name,
+ const dir_path& path,
+ const string& fmode = string (),
+ const string& dmode = string (),
+ const string& cmd = string ())
+ {
+ set_var (s, r, name, "", path.empty () ? nullptr : &path);
+ set_var (s, r, name, ".mode", fmode.empty () ? nullptr : &fmode);
+ set_var (s, r, name, ".dir_mode", dmode.empty () ? nullptr : &dmode);
+ set_var (s, r, name, ".cmd", cmd.empty () ? nullptr : &cmd);
+ set_var<strings> (s, r, name, ".options", nullptr);
}
static rule rule_;
@@ -120,6 +130,15 @@ namespace build
rs.insert<file> (install_id, "install", rule_);
}
+ // Enter module variables.
+ //
+ // Note that the set_dir() calls below enter some more.
+ //
+ if (first)
+ {
+ variable_pool.find ("install", dir_path_type);
+ }
+
// Configuration.
//
// Note that we don't use any defaults for root -- the location
@@ -129,31 +148,31 @@ namespace build
if (first)
{
bool s (config::specified (r, "config.install"));
- const string& n (r["project"].as<const string&> ());
+ const string& n (as<string> (*r["project"]));
- set_dir (s, r, "root", nullptr, nullptr, "755", "install");
- set_dir (s, r, "data_root", "root", "644");
- set_dir (s, r, "exec_root", "root", "755");
+ set_dir (s, r, "root", dir_path (), "", "755", "install");
+ set_dir (s, r, "data_root", dir_path ("root"), "644");
+ set_dir (s, r, "exec_root", dir_path ("root"), "755");
- set_dir (s, r, "sbin", "exec_root/sbin");
- set_dir (s, r, "bin", "exec_root/bin");
- set_dir (s, r, "lib", "exec_root/lib");
- set_dir (s, r, "libexec", ("exec_root/libexec/" + n).c_str ());
+ set_dir (s, r, "sbin", dir_path ("exec_root/sbin"));
+ set_dir (s, r, "bin", dir_path ("exec_root/bin"));
+ set_dir (s, r, "lib", dir_path ("exec_root/lib"));
+ set_dir (s, r, "libexec", dir_path ("exec_root/libexec/" + n));
- set_dir (s, r, "data", ("data_root/share/" + n).c_str ());
- set_dir (s, r, "include", "data_root/include");
+ set_dir (s, r, "data", dir_path ("data_root/share/" + n));
+ set_dir (s, r, "include", dir_path ("data_root/include"));
- set_dir (s, r, "doc", ("data_root/share/doc/" + n).c_str ());
- set_dir (s, r, "man", "data_root/share/man");
+ set_dir (s, r, "doc", dir_path ("data_root/share/doc/" + n));
+ set_dir (s, r, "man", dir_path ("data_root/share/man"));
- set_dir (s, r, "man1", "man/man1");
+ set_dir (s, r, "man1", dir_path ("man/man1"));
}
// Configure "installability" for built-in target types.
//
- path<doc> (b, "doc"); // Install into install.doc.
- path<man> (b, "man"); // Install into install.man.
- path<man> (b, "man1"); // Install into install.man1.
+ path<doc> (b, dir_path ("doc")); // Install into install.doc.
+ path<man> (b, dir_path ("man")); // Install into install.man.
+ path<man1> (b, dir_path ("man1")); // Install into install.man1.
}
}
}
diff --git a/build/install/rule.cxx b/build/install/rule.cxx
index f14547c..8f67001 100644
--- a/build/install/rule.cxx
+++ b/build/install/rule.cxx
@@ -21,48 +21,23 @@ namespace build
{
namespace install
{
- // Lookup the install or install.* variable and check that
- // the value makes sense. Return NULL if not found or if
- // the value is the special 'false' name (which means do
- // not install). T is either scope or target.
+ // Lookup the install or install.* variable. Return NULL if
+ // not found or if the value is the special 'false' name (which
+ // means do not install). T is either scope or target.
//
template <typename T>
- static const name*
- lookup (T& t, const char* var)
+ static const dir_path*
+ lookup (T& t, const string& var)
{
- auto v (t[var]);
+ auto l (t[var]);
- const name* r (nullptr);
+ if (!l)
+ return nullptr;
- if (!v)
- return r;
-
- const list_value& lv (v.template as<const list_value&> ());
-
- if (lv.empty ())
- return r;
-
- if (lv.size () == 1)
- {
- const name& n (lv.front ());
-
- if (n.simple () && n.value == "false")
- return r;
-
- if (!n.empty () && (n.simple () || n.directory ()))
- return &n;
- }
-
- fail << "expected directory instead of '" << lv << "' in "
- << "the " << var << " variable";
-
- return r;
+ const dir_path& r (as<dir_path> (*l));
+ return r.simple () && r.string () == "false" ? nullptr : &r;
}
- template <typename T>
- static inline const name*
- lookup (T& t, const string& var) {return lookup (t, var.c_str ());}
-
match_result rule::
match (action a, target& t, const std::string&) const
{
@@ -185,8 +160,8 @@ namespace build
struct install_dir
{
dir_path dir;
- string cmd;
- const list_value* options {nullptr};
+ string cmd; //@@ VAR type
+ const_strings_value options {nullptr};
string mode;
string dir_mode;
};
@@ -200,8 +175,8 @@ namespace build
cstrings args {base.cmd.c_str (), "-d"};
- if (base.options != nullptr)
- config::append_options (args, *base.options, "install.*.options");
+ if (base.options.d != nullptr) //@@ VAR
+ config::append_options (args, base.options);
args.push_back ("-m");
args.push_back (base.dir_mode.c_str ());
@@ -241,8 +216,8 @@ namespace build
cstrings args {base.cmd.c_str ()};
- if (base.options != nullptr)
- config::append_options (args, *base.options, "install.*.options");
+ if (base.options.d != nullptr) //@@ VAR
+ config::append_options (args, base.options);
args.push_back ("-m");
args.push_back (base.mode.c_str ());
@@ -277,10 +252,9 @@ namespace build
// creating leading directories as necessary.
//
static install_dir
- resolve (scope& s, const name& n, const string* var = nullptr)
+ resolve (scope& s, dir_path d, const string* var = nullptr)
{
install_dir r;
- dir_path d (n.simple () ? dir_path (n.value) : n.dir);
if (d.absolute ())
{
@@ -298,11 +272,11 @@ namespace build
// as the installation directory name, e.g., bin, sbin, lib,
// etc. Look it up and recurse.
//
- const string& dn (*d.begin ());
- const string var ("install." + dn);
- if (const name* n = lookup (s, var))
+ const string& sn (*d.begin ());
+ const string var ("install." + sn);
+ if (const dir_path* dn = lookup (s, var))
{
- r = resolve (s, *n, &var);
+ r = resolve (s, *dn, &var);
d = r.dir / dir_path (++d.begin (), d.end ());
d.normalize ();
@@ -310,7 +284,7 @@ namespace build
install (r, d); // install -d
}
else
- fail << "unknown installation directory name " << dn <<
+ fail << "unknown installation directory name " << sn <<
info << "did you forget to specify config." << var << "?";
}
@@ -320,12 +294,10 @@ namespace build
//
if (var != nullptr)
{
- if (auto v = s[*var + ".cmd"]) r.cmd = v.as<const string&> ();
- if (auto v = s[*var + ".mode"]) r.mode = v.as<const string&> ();
- if (auto v = s[*var + ".dir_mode"])
- r.dir_mode = v.as<const string&> ();
- if (auto v = s[*var + ".options"])
- r.options = &v.as<const list_value&> ();
+ if (auto l = s[*var + ".cmd"]) r.cmd = as<string> (*l);
+ if (auto l = s[*var + ".mode"]) r.mode = as<string> (*l);
+ if (auto l = s[*var + ".dir_mode"]) r.dir_mode = as<string> (*l);
+ if (auto l = s[*var + ".options"]) r.options = as<strings> (*l);
}
// Set defaults for unspecified components.
@@ -351,12 +323,12 @@ namespace build
//
install_dir d (
resolve (t.base_scope (),
- t["install"].as<const name&> ())); // We know it's there.
+ as<dir_path> (*t["install"]))); // We know it's there.
// Override mode if one was specified.
//
- if (auto v = t["install.mode"])
- d.mode = v.as<const string&> ();
+ if (auto l = t["install.mode"])
+ d.mode = as<string> (*l);
install (d, ft);
return (r |= target_state::changed);
diff --git a/build/install/utility b/build/install/utility
index 5c703fc..9bc41f1 100644
--- a/build/install/utility
+++ b/build/install/utility
@@ -5,7 +5,11 @@
#ifndef BUILD_INSTALL_UTILITY
#define BUILD_INSTALL_UTILITY
+#include <string>
+#include <utility>
+
#include <build/scope>
+#include <build/types>
namespace build
{
@@ -15,20 +19,20 @@ namespace build
//
template <typename T>
inline void
- path (scope& s, const char* v)
+ path (scope& s, dir_path d)
{
- auto p (s.target_vars[T::static_type]["*"].assign ("install"));
- if (p.second) // Already set by the user?
- p.first = v;
+ auto r (s.target_vars[T::static_type]["*"].assign ("install"));
+ if (r.second) // Already set by the user?
+ r.first.get () = std::move (d);
}
template <typename T>
inline void
- mode (scope& s, const char* v)
+ mode (scope& s, std::string m)
{
- auto m (s.target_vars[T::static_type]["*"].assign ("install.mode"));
- if (m.second) // Already set by the user?
- m.first = v;
+ auto r (s.target_vars[T::static_type]["*"].assign ("install.mode"));
+ if (r.second) // Already set by the user?
+ r.first.get () = std::move (m);
}
}
}