aboutsummaryrefslogtreecommitdiff
path: root/build
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-07-07 13:00:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-07-07 13:49:16 +0200
commit402bb6e6b297614226c4f848ebdb13fd49a95d76 (patch)
tree0a8a59e2bf1b7c0d6d7efb1dcf7e9bee1bea76cc /build
parent49d5628e35593a5300d39596286c768d7aa435b6 (diff)
Relax requirement on amalgamation src_root to track sub-project
Diffstat (limited to 'build')
-rw-r--r--build/config/operation.cxx2
-rw-r--r--build/file.cxx59
-rw-r--r--build/parser.cxx64
3 files changed, 69 insertions, 56 deletions
diff --git a/build/config/operation.cxx b/build/config/operation.cxx
index 78ad9e8..e6c258c 100644
--- a/build/config/operation.cxx
+++ b/build/config/operation.cxx
@@ -89,7 +89,7 @@ namespace build
{
const dir_path& d (v.as<const dir_path&> ());
- ofs << "# Base configuration inherited from " << d << "/ ." << endl
+ ofs << "# Base configuration inherited from " << d << endl
<< "#" << endl;
}
diff --git a/build/file.cxx b/build/file.cxx
index 5f899de..948b6ce 100644
--- a/build/file.cxx
+++ b/build/file.cxx
@@ -171,23 +171,37 @@ namespace build
const dir_path& d (v.as<const dir_path&> ());
dir_path out_root (root.path () / d);
- dir_path src_root (root.src_path () / d);
out_root.normalize ();
- src_root.normalize ();
- scope& rs (create_root (out_root, src_root));
-
- bootstrap_out (rs);
-
- // Check if the bootstrap process changed src_root.
+ // src_root is a bit more complicated. Here we have three cases:
+ //
+ // 1. Amalgamation's src_root is "parallel" to the sub-project's.
+ // 2. Amalgamation's src_root is the same as its out_root.
+ // 3. Some other pre-configured (via src-root.build) src_root.
//
- const dir_path& p (rs.vars["src_root"].as<const dir_path&> ());
+ // So we need to try all these cases in some sensible order.
+ // #3 should probably be tried first since that src_root was
+ // explicitly configured by the user. After that, #2 followed
+ // by #1 seems reasonable.
+ //
+ scope& rs (create_root (out_root, dir_path ()));
+ bootstrap_out (rs); // #3 happens here, if at all.
+
+ auto val (rs.assign ("src_root"));
- if (src_root != p)
- fail << "bootstrapped src_root " << p << " does not match "
- << "amalgamated " << src_root;
+ if (!val)
+ {
+ if (is_src_root (out_root)) // #2
+ val = out_root;
+ else // #1
+ {
+ dir_path src_root (root.src_path () / d);
+ src_root.normalize ();
+ val = move (src_root);
+ }
+ }
- rs.src_path_ = &p;
+ rs.src_path_ = &val.as<const dir_path&> ();
bootstrap_src (rs);
create_bootstrap_outer (rs);
@@ -202,7 +216,7 @@ namespace build
{
// Should be a list of directories.
//
- if (!n.type.empty () || !n.value.empty () || n.dir.empty ())
+ if (!n.directory ())
fail << "expected directory in subprojects variable "
<< "instead of " << n;
@@ -211,20 +225,19 @@ namespace build
if (!out_base.sub (out_root))
continue;
- dir_path src_root (root.src_path () / n.dir);
- scope& rs (create_root (out_root, src_root));
-
+ // The same logic to src_root as in create_bootstrap_outer().
+ //
+ scope& rs (create_root (out_root, dir_path ()));
bootstrap_out (rs);
- // Check if the bootstrap process changed src_root.
- //
- const dir_path& p (rs.vars["src_root"].as<const dir_path&> ());
+ auto val (rs.assign ("src_root"));
- if (src_root != p)
- fail << "bootstrapped src_root " << p << " does not match "
- << "subproject " << src_root;
+ if (!val)
+ val = is_src_root (out_root)
+ ? out_root
+ : (root.src_path () / n.dir);
- rs.src_path_ = &p;
+ rs.src_path_ = &val.as<const dir_path&> ();
bootstrap_src (rs);
diff --git a/build/parser.cxx b/build/parser.cxx
index 59e3783..e051124 100644
--- a/build/parser.cxx
+++ b/build/parser.cxx
@@ -521,56 +521,56 @@ namespace build
p /= path ("buildfile");
}
- bool in_out (false);
- if (p.absolute ())
+ // Determine new out_base.
+ //
+ dir_path out_base;
+
+ if (p.relative ())
+ {
+ out_base = scope_->path () / p.directory ();
+ out_base.normalize ();
+ }
+ else
{
p.normalize ();
// Make sure the path is in this project. Include is only meant
- // to be used for intra-project inclusion.
+ // to be used for intra-project inclusion (plus amalgamation).
//
+ bool in_out (false);
if (!p.sub (*src_root_) && !(in_out = p.sub (*out_root_)))
fail (l) << "out of project include " << p;
- }
- else
- {
- // Use the src directory corresponding to the current directory scope.
- //
- p = src_out (scope_->path (), *out_root_, *src_root_) / p;
- p.normalize ();
- }
- if (!root_->buildfiles.insert (p).second)
- {
- level4 ([&]{trace (l) << "skipping already included " << p;});
- continue;
- }
-
- // Determine new bases.
- //
- dir_path out_base;
- dir_path src_base;
-
- if (in_out)
- {
- out_base = p.directory ();
- src_base = src_out (out_base, *out_root_, *src_root_);
- }
- else
- {
- src_base = p.directory ();
- out_base = out_src (src_base, *out_root_, *src_root_);
+ out_base = in_out
+ ? p.directory ()
+ : out_src (p.directory (), *out_root_, *src_root_);
}
// Create and bootstrap root scope(s) of subproject(s) that
// this out_base belongs to. If any were created, load them
- // and update parser state.
+ // and update parser state. Note that we need to do this
+ // before figuring out absolute buildfile path since we may
+ // switch the project root (i.e., include into a sub-project).
//
scope* ors (switch_root (&create_bootstrap_inner (*root_, out_base)));
if (root_ != ors)
load_root_pre (*root_); // Loads outer roots recursively.
+ // Determine src_base and buildfile, if relative.
+ //
+ dir_path src_base (src_out (out_base, *out_root_, *src_root_));
+
+ if (p.relative ())
+ p = src_base / p.leaf ();
+
+ if (!root_->buildfiles.insert (p).second) // Note: may be "new" root.
+ {
+ level4 ([&]{trace (l) << "skipping already included " << p;});
+ switch_root (ors); // Restore old root.
+ continue;
+ }
+
ifstream ifs (p.string ());
if (!ifs.is_open ())