aboutsummaryrefslogtreecommitdiff
path: root/build
diff options
context:
space:
mode:
Diffstat (limited to 'build')
-rw-r--r--build/config/module.cxx12
-rw-r--r--build/cxx/module.cxx10
-rw-r--r--build/cxx/rule.cxx17
-rw-r--r--build/parser.cxx15
-rw-r--r--build/scope20
-rw-r--r--build/variable16
-rw-r--r--build/variable.ixx48
7 files changed, 97 insertions, 41 deletions
diff --git a/build/config/module.cxx b/build/config/module.cxx
index 9ed0cec..426b1f6 100644
--- a/build/config/module.cxx
+++ b/build/config/module.cxx
@@ -18,11 +18,17 @@ namespace build
namespace config
{
static bool
- trigger (scope&, const path& p)
+ trigger (bool pre, scope& base, path& p)
{
tracer trace ("config::trigger");
- level4 ([&]{trace << "intercepted sourcing of " << p;});
- return file_exists (p);
+
+ if (pre)
+ {
+ level4 ([&]{trace << "intercepted sourcing of " << p;});
+ return file_exists (p);
+ }
+ else
+ return true;
}
void
diff --git a/build/cxx/module.cxx b/build/cxx/module.cxx
index 846e324..3e0101f 100644
--- a/build/cxx/module.cxx
+++ b/build/cxx/module.cxx
@@ -108,6 +108,8 @@ namespace build
// is important to distinguish between the "configured as
// unspecified" and "not configured" cases).
//
+ // We also merge them into the corresponding cxx.* variables.
+ //
{
auto v (root["config.cxx.poptions"]);
@@ -115,6 +117,8 @@ namespace build
{
if (v.belongs (*global_scope))
root.assign ("config.cxx.poptions") = v;
+
+ root.append ("cxx.poptions") += v;
}
else
root.assign ("config.cxx.poptions") = nullptr;
@@ -127,6 +131,8 @@ namespace build
{
if (v.belongs (*global_scope))
root.assign ("config.cxx.coptions") = v;
+
+ root.append ("cxx.coptions") += v;
}
else
root.assign ("config.cxx.coptions") = nullptr;
@@ -139,6 +145,8 @@ namespace build
{
if (v.belongs (*global_scope))
root.assign ("config.cxx.loptions") = v;
+
+ root.append ("cxx.loptions") += v;
}
else
root.assign ("config.cxx.loptions") = nullptr;
@@ -151,6 +159,8 @@ namespace build
{
if (v.belongs (*global_scope))
root.assign ("config.cxx.libs") = v;
+
+ root.append ("cxx.libs") += v;
}
else
root.assign ("config.cxx.libs") = nullptr;
diff --git a/build/cxx/rule.cxx b/build/cxx/rule.cxx
index 963ecb1..65616f8 100644
--- a/build/cxx/rule.cxx
+++ b/build/cxx/rule.cxx
@@ -203,19 +203,16 @@ namespace build
vector<const char*> args {cxx.c_str ()};
- append_options (args, rs, "config.cxx.poptions");
append_options (args, t, "cxx.poptions");
// @@ Some C++ options (e.g., -std, -m) affect the preprocessor.
// Or maybe they are not C++ options? Common options?
//
- append_options (args, rs, "config.cxx.coptions");
+ append_options (args, t, "cxx.coptions");
string std; // Storage.
append_std (args, t, std);
- append_options (args, t, "cxx.coptions");
-
if (t.is_a<objso> ())
args.push_back ("-fPIC");
@@ -362,16 +359,12 @@ namespace build
vector<const char*> args {cxx.c_str ()};
- append_options (args, rs, "config.cxx.poptions");
append_options (args, t, "cxx.poptions");
-
- append_options (args, rs, "config.cxx.coptions");
+ append_options (args, t, "cxx.coptions");
string std; // Storage.
append_std (args, t, std);
- append_options (args, t, "cxx.coptions");
-
if (t.is_a<objso> ())
args.push_back ("-fPIC");
@@ -717,20 +710,17 @@ namespace build
vector<const char*> args {cxx.c_str ()};
- append_options (args, rs, "config.cxx.coptions");
+ append_options (args, t, "cxx.coptions");
string std; // Storage.
append_std (args, t, std);
- append_options (args, t, "cxx.coptions");
-
if (so)
args.push_back ("-shared");
args.push_back ("-o");
args.push_back (relt.string ().c_str ());
- append_options (args, rs, "config.cxx.loptions");
append_options (args, t, "cxx.loptions");
for (target* pt: t.prerequisites)
@@ -753,7 +743,6 @@ namespace build
args.push_back (relo.back ().string ().c_str ());
}
- append_options (args, rs, "config.cxx.libs");
append_options (args, t, "cxx.libs");
args.push_back (nullptr);
diff --git a/build/parser.cxx b/build/parser.cxx
index 6c3989d..4275411 100644
--- a/build/parser.cxx
+++ b/build/parser.cxx
@@ -389,13 +389,19 @@ namespace build
// See if there is a trigger for this path.
//
+ const scope::trigger_type* trig (nullptr);
{
auto i (root_->triggers.find (p));
- if (i != root_->triggers.end () && !i->second (*root_, p))
+ if (i != root_->triggers.end ())
{
- level4 ([&]{trace (l) << "trigger instructed to skip " << p;});
- continue;
+ if (!i->second (true, *scope_, p))
+ {
+ level4 ([&]{trace (l) << "trigger instructed to skip " << p;});
+ continue;
+ }
+
+ trig = &i->second;
}
}
@@ -443,6 +449,9 @@ namespace build
auto v (root_->vars["src_root"]);
src_root_ = v ? &v.as<const dir_path&> () : nullptr;
}
+
+ if (trig != nullptr)
+ (*trig) (false, *scope_, p);
}
if (tt == type::newline)
diff --git a/build/scope b/build/scope
index e3c8776..2824aeb 100644
--- a/build/scope
+++ b/build/scope
@@ -108,15 +108,21 @@ namespace build
//
std::unordered_set<path_type> buildfiles;
- // A map of buildfiles to trigger functions that are executed when
- // such files are sourced. The path must be absolute and normalized.
+ // A map of absolute and normalized buildfile paths to trigger
+ // functions that are executed when such files are sourced. The
+ // trigger is called twice: the first time before sourcing the
+ // file (pre is true) and the second time -- after (pre is false).
//
- // The passed path is the buildfile. If the returned value is true,
- // then the file is sourced. If false -- the file is ignored. Note
- // that currently triggers can only be registered on the project's
- // root scope.
+ // The passed path is the buildfile, which can be altered by the
+ // trigger in the pre call, if desired. If the returned value is
+ // true, then the file is sourced. If false -- the file is ignored
+ // (and no post call is made). The return value is ignored in the
+ // post call.
//
- using trigger_type = std::function<bool (scope&, const path_type&)>;
+ // Note that currently triggers can only be registered on the
+ // project's root scope.
+ //
+ using trigger_type = std::function<bool (bool pre, scope&, path_type&)>;
std::unordered_map<path_type, trigger_type> triggers;
private:
diff --git a/build/variable b/build/variable
index 48fc519..05ca671 100644
--- a/build/variable
+++ b/build/variable
@@ -106,7 +106,7 @@ namespace build
T
as () const = delete;
- // Set interface.
+ // Assign.
//
const value_proxy&
operator= (value_ptr) const;
@@ -117,16 +117,22 @@ namespace build
const value_proxy&
operator= (std::string) const;
- // Append enother simple name to list_value.
+ const value_proxy&
+ operator= (dir_path) const;
+
+ const value_proxy&
+ operator= (nullptr_t) const;
+
+ // Append.
//
const value_proxy&
- operator+= (std::string) const;
+ operator+= (const value_proxy&) const;
const value_proxy&
- operator= (dir_path) const;
+ operator+= (const list_value&) const;
const value_proxy&
- operator= (nullptr_t) const;
+ operator+= (std::string) const; // Append simple name to list_value.
// Return true if this value belongs to the specified scope or target.
//
diff --git a/build/variable.ixx b/build/variable.ixx
index 2cbe519..52272cc 100644
--- a/build/variable.ixx
+++ b/build/variable.ixx
@@ -37,27 +37,57 @@ namespace build
}
inline const value_proxy& value_proxy::
- operator+= (std::string v) const
+ operator= (dir_path v) const
{
- if (*p == nullptr)
- *this = v;
- else
- as<list_value&> ().emplace_back (std::move (v));
+ p->reset (new list_value (std::move (v)));
+ return *this;
+ }
+ inline const value_proxy& value_proxy::
+ operator= (nullptr_t) const
+ {
+ p->reset ();
return *this;
}
inline const value_proxy& value_proxy::
- operator= (dir_path v) const
+ operator+= (const value_proxy& v) const
{
- p->reset (new list_value (std::move (v)));
+ if (v && this != &v)
+ {
+ if (*p == nullptr)
+ *this = v;
+ else
+ //@@ Assuming it is a list_value.
+ //
+ *this += v.as<const list_value&> ();
+ }
+
return *this;
}
inline const value_proxy& value_proxy::
- operator= (nullptr_t) const
+ operator+= (const list_value& v) const
{
- p->reset ();
+ if (*p == nullptr)
+ *this = value_ptr (new list_value (v));
+ else
+ {
+ list_value& lv (as<list_value&> ());
+ lv.insert (lv.end (), v.begin (), v.end ());
+ }
+
+ return *this;
+ }
+
+ inline const value_proxy& value_proxy::
+ operator+= (std::string v) const
+ {
+ if (*p == nullptr)
+ *this = v;
+ else
+ as<list_value&> ().emplace_back (std::move (v));
+
return *this;
}
}