diff options
-rw-r--r-- | build/config/module.cxx | 12 | ||||
-rw-r--r-- | build/cxx/module.cxx | 10 | ||||
-rw-r--r-- | build/cxx/rule.cxx | 17 | ||||
-rw-r--r-- | build/parser.cxx | 15 | ||||
-rw-r--r-- | build/scope | 20 | ||||
-rw-r--r-- | build/variable | 16 | ||||
-rw-r--r-- | build/variable.ixx | 48 |
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; } } |