From 402bb6e6b297614226c4f848ebdb13fd49a95d76 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 7 Jul 2015 13:00:45 +0200 Subject: Relax requirement on amalgamation src_root to track sub-project --- build/config/operation.cxx | 2 +- build/file.cxx | 59 ++++++++++++++++----------- build/parser.cxx | 64 +++++++++++++++--------------- tests/amalgam/config/build/bootstrap.build | 3 ++ tests/amalgam/config/build/root.build | 1 + tests/amalgam/config/buildfile | 3 ++ tests/amalgam/simple/build/bootstrap.build | 3 ++ tests/amalgam/simple/buildfile | 9 +++++ tests/amalgam/simple/driver.cxx | 4 ++ tests/cli/lib/libtest/build/root.build | 1 - tests/cli/lib/test/buildfile | 2 +- tests/cli/simple/build/root.build | 2 - tests/cli/simple/buildfile | 6 ++- 13 files changed, 98 insertions(+), 61 deletions(-) create mode 100644 tests/amalgam/config/build/bootstrap.build create mode 100644 tests/amalgam/config/build/root.build create mode 100644 tests/amalgam/config/buildfile create mode 100644 tests/amalgam/simple/build/bootstrap.build create mode 100644 tests/amalgam/simple/buildfile create mode 100644 tests/amalgam/simple/driver.cxx 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 ()); - 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 ()); 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 ()); + // 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 (); 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 ()); + 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 (); 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 ()) diff --git a/tests/amalgam/config/build/bootstrap.build b/tests/amalgam/config/build/bootstrap.build new file mode 100644 index 0000000..5951f06 --- /dev/null +++ b/tests/amalgam/config/build/bootstrap.build @@ -0,0 +1,3 @@ +project = amalgam-config +subprojects = 1/ 2/ +using config diff --git a/tests/amalgam/config/build/root.build b/tests/amalgam/config/build/root.build new file mode 100644 index 0000000..7d1767b --- /dev/null +++ b/tests/amalgam/config/build/root.build @@ -0,0 +1 @@ +using cxx diff --git a/tests/amalgam/config/buildfile b/tests/amalgam/config/buildfile new file mode 100644 index 0000000..e9fc7f4 --- /dev/null +++ b/tests/amalgam/config/buildfile @@ -0,0 +1,3 @@ +d = 1/ 2/ +.: $d +include $d diff --git a/tests/amalgam/simple/build/bootstrap.build b/tests/amalgam/simple/build/bootstrap.build new file mode 100644 index 0000000..8da7272 --- /dev/null +++ b/tests/amalgam/simple/build/bootstrap.build @@ -0,0 +1,3 @@ +project = amalgam-simple +amalgamation = ../ +using config diff --git a/tests/amalgam/simple/buildfile b/tests/amalgam/simple/buildfile new file mode 100644 index 0000000..ec6a4e1 --- /dev/null +++ b/tests/amalgam/simple/buildfile @@ -0,0 +1,9 @@ +using cxx + +hxx.ext = hxx +cxx.ext = cxx +ixx.ext = ixx + +cxx.poptions += -I$out_root + +exe{driver}: cxx{driver} diff --git a/tests/amalgam/simple/driver.cxx b/tests/amalgam/simple/driver.cxx new file mode 100644 index 0000000..70b4146 --- /dev/null +++ b/tests/amalgam/simple/driver.cxx @@ -0,0 +1,4 @@ +int +main () +{ +} diff --git a/tests/cli/lib/libtest/build/root.build b/tests/cli/lib/libtest/build/root.build index 4dce48b..f8d3d9e 100644 --- a/tests/cli/lib/libtest/build/root.build +++ b/tests/cli/lib/libtest/build/root.build @@ -3,4 +3,3 @@ using cxx hxx.ext = ixx.ext = ipp cxx.ext = cpp - diff --git a/tests/cli/lib/test/buildfile b/tests/cli/lib/test/buildfile index 70a4dc1..0bbeb95 100644 --- a/tests/cli/lib/test/buildfile +++ b/tests/cli/lib/test/buildfile @@ -3,4 +3,4 @@ import libs += cli-lib-libtest exe{driver}: cxx{driver} cli.cxx{test} $libs cli.cxx{test}: cli{test} -cxx.poptions = -I$out_root +cxx.poptions += -I$out_root diff --git a/tests/cli/simple/build/root.build b/tests/cli/simple/build/root.build index 8e910cf..8b13789 100644 --- a/tests/cli/simple/build/root.build +++ b/tests/cli/simple/build/root.build @@ -1,3 +1 @@ -using cxx -using cli diff --git a/tests/cli/simple/buildfile b/tests/cli/simple/buildfile index 80882c6..998eb67 100644 --- a/tests/cli/simple/buildfile +++ b/tests/cli/simple/buildfile @@ -1,8 +1,12 @@ +using cxx + hxx.ext = cxx.ext = cpp ixx.ext = ipp -cxx.poptions = -I$out_root +cxx.poptions += -I$out_root + +using cli exe{driver}: cxx{driver} cxx{test} cxx{test} hxx{test}: cli{test} -- cgit v1.1