diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-04-07 14:51:53 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-04-07 14:51:53 +0200 |
commit | 9e6303e86dae25096ee62d74abfca4456be6a96f (patch) | |
tree | 58be935e7a1cc2843d251456478d8cc6ec1ad01a /build/b.cxx | |
parent | 088a60c512aff26eeb026c516d0afe724880cb2b (diff) |
Initial support for amalgamation/subprojects
For now both need to be manually specified in src bootstrap. At
this stage main() loads any outer root scopes while include loads
any inner.
Diffstat (limited to 'build/b.cxx')
-rw-r--r-- | build/b.cxx | 102 |
1 files changed, 54 insertions, 48 deletions
diff --git a/build/b.cxx b/build/b.cxx index d7a5638..49abe5c 100644 --- a/build/b.cxx +++ b/build/b.cxx @@ -89,41 +89,39 @@ namespace build return path (); } + // Create and bootstrap outer root scopes, if any. Loading is + // done by root_pre(). + // static void - bootstrap_out (scope& root) + create_outer_roots (scope& root) { - path bf (root.path () / path ("build/bootstrap/src-root.build")); + auto v (root.ro_variables ()["amalgamation"]); - if (!file_exists (bf)) + if (!v) return; - //@@ TODO: if bootstrap files can source other bootstrap files - // (the way to express dependecies), then we need a way to - // prevent multiple sourcing. We handle it here but we still - // need something like source_once (once [scope] source). - // - source_once (bf, root, root); - } + const path& d (v.as<const path&> ()); + path out_root (root.path () / d); + path src_root (root.src_path () / d); + out_root.normalize (); + src_root.normalize (); - // Return true if we loaded anything. - // - static bool - bootstrap_src (scope& root) - { - tracer trace ("bootstrap_src"); - - path bf (root.src_path () / path ("build/bootstrap.build")); + scope& rs (create_root (out_root, src_root)); - if (!file_exists (bf)) - return false; + bootstrap_out (rs); - // We assume that bootstrap out cannot load this file explicitly. It - // feels wrong to allow this since that makes the whole bootstrap - // process hard to reason about. But we may try to bootstrap the - // same root scope multiple time. + // Check if the bootstrap process changed src_root. // - source_once (bf, root, root); - return true; + const path& p (rs.variables["src_root"].as<const path&> ()); + + if (src_root != p) + fail << "bootstrapped src_root " << p << " does not match " + << "amalgamated " << src_root; + + rs.src_path_ = &p; + + bootstrap_src (rs); + create_outer_roots (rs); } } @@ -502,31 +500,11 @@ main (int argc, char* argv[]) // files, if any. Note that we might already have done this // as a result of one of the preceding target processing. // - scope& rs (scopes.insert (out_root, true).first); - - // Enter built-in meta-operation and operation names. Note that - // the order of registration should match the id constants; see - // <operation> for details. Loading of modules (via the src_root - // bootstrap; see below) can result in additional names being - // added. - // - if (rs.meta_operations.empty ()) - { - assert (rs.meta_operations.insert (perform) == perform_id); - - assert (rs.operations.insert (default_) == default_id); - assert (rs.operations.insert (update) == update_id); - assert (rs.operations.insert (clean) == clean_id); - } - - rs.variables["out_root"] = out_root; - - // If we know src_root, add that variable as well. This could + // If we know src_root, set that variable as well. This could // be of use to the bootstrap file (other than src-root.build, // which, BTW, doesn't need to exist if src_root == out_root). // - if (!src_root.empty ()) - rs.variables["src_root"] = src_root; + scope& rs (create_root (out_root, src_root)); bootstrap_out (rs); @@ -587,6 +565,34 @@ main (int argc, char* argv[]) // bool bootstrapped (bootstrap_src (rs)); + // Check that out_root that we have found is the innermost root + // for this project. If it is not, then it means we are trying + // to load a disfigured sub-project and that we do not support. + // Why don't we support it? Because things are already complex + // enough here. + // + if (auto v = rs.ro_variables ()["subprojects"]) + { + for (const name& n: v.as<const list_value&> ().data) + { + // Should be a list of directories. + // + if (!n.type.empty () || !n.value.empty () || n.dir.empty ()) + fail << "expected directory in subprojects variable " + << "instead of " << n; + + if (out_base.sub (out_root / n.dir)) + fail << tn << " is in a subproject of " << out_root << + info << "explicitly specify src_base for this target"; + } + } + + // Create and bootstrap outer roots if any. Loading is done + // by root_pre() (that would normally be called by the meta- + // operation's load() callback below). + // + create_outer_roots (rs); + // The src bootstrap should have loaded all the modules that // may add new meta/operations. So at this stage they should // all be known. We store the combined action id in uint8_t; |