aboutsummaryrefslogtreecommitdiff
path: root/build/file.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/file.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/file.cxx')
-rw-r--r--build/file.cxx103
1 files changed, 99 insertions, 4 deletions
diff --git a/build/file.cxx b/build/file.cxx
index 7bb8bb6..0b0220d 100644
--- a/build/file.cxx
+++ b/build/file.cxx
@@ -53,16 +53,111 @@ namespace build
source (bf, root, base);
}
- void
- root_pre (scope& root)
+ scope&
+ create_root (const path& out_root, const path& src_root)
{
- tracer trace ("root_pre");
+ 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
+ // bootstrap; see below) can result in additional names being
+ // added.
+ //
+ if (rs.meta_operations.empty ())
+ {
+ assert (rs.meta_operations.insert (perform) == perform_id);
- path bf (root.src_path () / path ("build/root.build"));
+ assert (rs.operations.insert (default_) == default_id);
+ assert (rs.operations.insert (update) == update_id);
+ assert (rs.operations.insert (clean) == clean_id);
+ }
+
+ // If this is already a root scope, verify that things are
+ // consistent.
+ //
+ {
+ auto v (rs.variables["out_root"]);
+
+ if (!v)
+ v = out_root;
+ else
+ {
+ const path& p (v.as<const path&> ());
+
+ if (p != out_root)
+ fail << "new out_root " << out_root << " does not match "
+ << "existing " << p;
+ }
+ }
+
+ if (!src_root.empty ())
+ {
+ auto v (rs.variables["src_root"]);
+
+ if (!v)
+ v = src_root;
+ else
+ {
+ const path& p (v.as<const path&> ());
+
+ if (p != src_root)
+ fail << "new src_root " << src_root << " does not match "
+ << "existing " << p;
+ }
+ }
+
+ return rs;
+ }
+
+ void
+ bootstrap_out (scope& root)
+ {
+ path bf (root.path () / path ("build/bootstrap/src-root.build"));
if (!file_exists (bf))
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);
}
+
+ bool
+ bootstrap_src (scope& root)
+ {
+ tracer trace ("bootstrap_src");
+
+ path bf (root.src_path () / path ("build/bootstrap.build"));
+
+ if (!file_exists (bf))
+ return false;
+
+ // 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.
+ //
+ source_once (bf, root, root);
+ return true;
+ }
+
+ void
+ root_pre (scope& root)
+ {
+ tracer trace ("root_pre");
+
+ // First load outer roots, if any.
+ //
+ if (scope* rs = root.parent_scope ()->root_scope ())
+ root_pre (*rs);
+
+ path bf (root.src_path () / path ("build/root.build"));
+
+ if (file_exists (bf))
+ source_once (bf, root, root);
+ }
}