aboutsummaryrefslogtreecommitdiff
path: root/build/b.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-04-07 14:51:53 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-04-07 14:51:53 +0200
commit9e6303e86dae25096ee62d74abfca4456be6a96f (patch)
tree58be935e7a1cc2843d251456478d8cc6ec1ad01a /build/b.cxx
parent088a60c512aff26eeb026c516d0afe724880cb2b (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.cxx102
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;