From 70613e9be046c9cddd2486505a44d3a0324d6d95 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 13 Jul 2015 12:20:27 +0200 Subject: Implement subproject import --- build/config/operation.cxx | 6 +- build/file.cxx | 99 ++++++++++++++++++++--------- build/rule.cxx | 4 +- build/variable | 13 ++++ tests/amalgam/config/buildfile | 2 +- tests/amalgam/libtest/build/bootstrap.build | 2 + tests/amalgam/libtest/build/export.build | 6 ++ tests/amalgam/libtest/buildfile | 6 ++ tests/amalgam/libtest/test.cxx | 4 ++ tests/amalgam/simple1/build/bootstrap.build | 2 - tests/amalgam/simple1/buildfile | 9 --- tests/amalgam/simple1/driver.cxx | 4 -- tests/amalgam/simple2/build/bootstrap.build | 2 - tests/amalgam/simple2/buildfile | 9 --- tests/amalgam/simple2/driver.cxx | 4 -- tests/amalgam/test/build/bootstrap.build | 2 + tests/amalgam/test/buildfile | 8 +++ tests/amalgam/test/driver.cxx | 4 ++ 18 files changed, 120 insertions(+), 66 deletions(-) create mode 100644 tests/amalgam/libtest/build/bootstrap.build create mode 100644 tests/amalgam/libtest/build/export.build create mode 100644 tests/amalgam/libtest/buildfile create mode 100644 tests/amalgam/libtest/test.cxx delete mode 100644 tests/amalgam/simple1/build/bootstrap.build delete mode 100644 tests/amalgam/simple1/buildfile delete mode 100644 tests/amalgam/simple1/driver.cxx delete mode 100644 tests/amalgam/simple2/build/bootstrap.build delete mode 100644 tests/amalgam/simple2/buildfile delete mode 100644 tests/amalgam/simple2/driver.cxx create mode 100644 tests/amalgam/test/build/bootstrap.build create mode 100644 tests/amalgam/test/buildfile create mode 100644 tests/amalgam/test/driver.cxx diff --git a/build/config/operation.cxx b/build/config/operation.cxx index 43a5718..57bb60d 100644 --- a/build/config/operation.cxx +++ b/build/config/operation.cxx @@ -245,10 +245,10 @@ namespace build } static void - disfigure_match (action a, + disfigure_match (action, scope& root, - const target_key& tk, - const location& l, + const target_key&, + const location&, action_targets& ts) { tracer trace ("disfigure_match"); diff --git a/build/file.cxx b/build/file.cxx index b58d8e8..0dff025 100644 --- a/build/file.cxx +++ b/build/file.cxx @@ -647,6 +647,8 @@ namespace build string project; name target; + // @@ This is probably all wrong. + // if (n.dir.empty ()) { if (!n.simple ()) @@ -656,7 +658,7 @@ namespace build // means sub-projects? Or only to a certain point, then // (untyped) target? Looks like I will need to scan anything // that looks like a directory checking if this is a subproject. - // If not, then that's part of the target. + // If not, then that's part of the target. No, no, nooooo! // project = n.value; } @@ -680,48 +682,77 @@ namespace build // Figure out this project's out_root. // dir_path out_root; - string var ("config.import." + project); + dir_path fallback_src_root; // We have seen this already, havent' we ? - if (auto v = iroot[var]) + // First search subprojects, starting with our root and then trying + // outer roots for as long as we are inside an amalgamation. + // + for (scope* r (&iroot);; r = r->parent_scope ()->root_scope ()) { - if (!v.belongs (*global_scope)) // A value from (some) config.build. - out_root = v.as (); - else + if (auto v = r->vars["subprojects"]) { - // Process the path by making it absolute and normalized. Also, - // for usability's sake, treat a simple name that doesn't end - // with '/' as a directory. + // @@ Map sure would have been handy. // - list_value& lv (v.as ()); + if (const name* n = v.as ().find_pair (project)) + { + out_root = r->path () / n->dir; + fallback_src_root = r->src_path () / n->dir; + break; + } + } - if (lv.size () != 1 || lv[0].empty () || !lv[0].type.empty ()) - fail (l) << "invalid " << var << " value " << lv; + if (!r->vars["amalgamation"]) + break; + } - name& n (lv[0]); - if (n.directory ()) - out_root = n.dir; + // Then try the config.import.* mechanism. + // + if (out_root.empty ()) + { + string var ("config.import." + project); + + if (auto v = iroot[var]) + { + if (!v.belongs (*global_scope)) // A value from (some) config.build. + out_root = v.as (); else - out_root = dir_path (n.value); + { + // Process the path by making it absolute and normalized. Also, + // for usability's sake, treat a simple name that doesn't end + // with '/' as a directory. + // + list_value& lv (v.as ()); - if (out_root.relative ()) - out_root = work / out_root; + if (lv.size () != 1 || lv[0].empty () || !lv[0].type.empty ()) + fail (l) << "invalid " << var << " value " << lv; - out_root.normalize (); - iroot.assign (var) = out_root; + name& n (lv[0]); - // Also update the command-line value. This is necessary to avoid - // a warning issued by the config module about global/root scope - // value mismatch. - // - if (n.dir != out_root) - n = name (out_root); + if (n.directory ()) + out_root = n.dir; + else + out_root = dir_path (n.value); + + if (out_root.relative ()) + out_root = work / out_root; + + out_root.normalize (); + iroot.assign (var) = out_root; + + // Also update the command-line value. This is necessary to avoid + // a warning issued by the config module about global/root scope + // value mismatch. + // + if (n.dir != out_root) + n = name (out_root); + } } + else + fail (l) << "unable to find out_root for imported " << project << + info << "consider explicitly configuring its out_root via the " + << var << " command line variable"; } - else - fail (l) << "unable to find out_root for imported " << project << - info << "consider explicitly configuring its out_root via the " - << var << " command line variable"; // Bootstrap the imported root scope. This is pretty similar to // what we do in main() except that here we don't try to guess @@ -744,6 +775,14 @@ namespace build root.src_path_ = &p; } + // Otherwise, use fallback if available. + // + else if (!fallback_src_root.empty ()) + { + auto v (root.assign ("src_root")); + v = move (fallback_src_root); + root.src_path_ = &v.as (); + } else fail (l) << "unable to determine src_root for imported " << project << info << "consider configuring " << out_root; diff --git a/build/rule.cxx b/build/rule.cxx index eadbecb..8f3a7a9 100644 --- a/build/rule.cxx +++ b/build/rule.cxx @@ -136,7 +136,7 @@ namespace build // dir_rule // match_result dir_rule:: - match (action a, target& t, const string&) const + match (action, target& t, const string&) const { return t; } @@ -151,7 +151,7 @@ namespace build // fsdir_rule // match_result fsdir_rule:: - match (action a, target& t, const string&) const + match (action, target& t, const string&) const { return t; } diff --git a/build/variable b/build/variable index 2bb3393..835fde1 100644 --- a/build/variable +++ b/build/variable @@ -84,6 +84,19 @@ namespace build const list_value* lv (dynamic_cast (&v)); return lv != nullptr && static_cast (*this) == *lv; } + + // Pair (i.e., key-value) search. Note that this funtion assumes + // the list contains only pairs and keys are simple names. Returns + // NULL if not found. + // + const name* + find_pair (const std::string& key) const + { + for (auto i (begin ()); i != end (); i += 2) + if (i->value == key) + return &*++i; + return nullptr; + } }; typedef std::unique_ptr list_value_ptr; diff --git a/tests/amalgam/config/buildfile b/tests/amalgam/config/buildfile index e9fc7f4..2f01ba3 100644 --- a/tests/amalgam/config/buildfile +++ b/tests/amalgam/config/buildfile @@ -1,3 +1,3 @@ -d = 1/ 2/ +d = #t/ #l/ .: $d include $d diff --git a/tests/amalgam/libtest/build/bootstrap.build b/tests/amalgam/libtest/build/bootstrap.build new file mode 100644 index 0000000..025e510 --- /dev/null +++ b/tests/amalgam/libtest/build/bootstrap.build @@ -0,0 +1,2 @@ +project = amalgam-libtest +using config diff --git a/tests/amalgam/libtest/build/export.build b/tests/amalgam/libtest/build/export.build new file mode 100644 index 0000000..b95e409 --- /dev/null +++ b/tests/amalgam/libtest/build/export.build @@ -0,0 +1,6 @@ +$out_root/: +{ + include buildfile +} + +export $out_root/lib{test} diff --git a/tests/amalgam/libtest/buildfile b/tests/amalgam/libtest/buildfile new file mode 100644 index 0000000..04c44da --- /dev/null +++ b/tests/amalgam/libtest/buildfile @@ -0,0 +1,6 @@ +using cxx + +hxx.ext = hxx +cxx.ext = cxx + +lib{test}: cxx{test} diff --git a/tests/amalgam/libtest/test.cxx b/tests/amalgam/libtest/test.cxx new file mode 100644 index 0000000..34a033a --- /dev/null +++ b/tests/amalgam/libtest/test.cxx @@ -0,0 +1,4 @@ +void +f () +{ +} diff --git a/tests/amalgam/simple1/build/bootstrap.build b/tests/amalgam/simple1/build/bootstrap.build deleted file mode 100644 index e4502f8..0000000 --- a/tests/amalgam/simple1/build/bootstrap.build +++ /dev/null @@ -1,2 +0,0 @@ -project = amalgam-simple1 -using config diff --git a/tests/amalgam/simple1/buildfile b/tests/amalgam/simple1/buildfile deleted file mode 100644 index ec6a4e1..0000000 --- a/tests/amalgam/simple1/buildfile +++ /dev/null @@ -1,9 +0,0 @@ -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/simple1/driver.cxx b/tests/amalgam/simple1/driver.cxx deleted file mode 100644 index 70b4146..0000000 --- a/tests/amalgam/simple1/driver.cxx +++ /dev/null @@ -1,4 +0,0 @@ -int -main () -{ -} diff --git a/tests/amalgam/simple2/build/bootstrap.build b/tests/amalgam/simple2/build/bootstrap.build deleted file mode 100644 index 599ec1d..0000000 --- a/tests/amalgam/simple2/build/bootstrap.build +++ /dev/null @@ -1,2 +0,0 @@ -project = amalgam-simple2 -using config diff --git a/tests/amalgam/simple2/buildfile b/tests/amalgam/simple2/buildfile deleted file mode 100644 index ec6a4e1..0000000 --- a/tests/amalgam/simple2/buildfile +++ /dev/null @@ -1,9 +0,0 @@ -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/simple2/driver.cxx b/tests/amalgam/simple2/driver.cxx deleted file mode 100644 index 70b4146..0000000 --- a/tests/amalgam/simple2/driver.cxx +++ /dev/null @@ -1,4 +0,0 @@ -int -main () -{ -} diff --git a/tests/amalgam/test/build/bootstrap.build b/tests/amalgam/test/build/bootstrap.build new file mode 100644 index 0000000..a53e738 --- /dev/null +++ b/tests/amalgam/test/build/bootstrap.build @@ -0,0 +1,2 @@ +project = amalgam-test +using config diff --git a/tests/amalgam/test/buildfile b/tests/amalgam/test/buildfile new file mode 100644 index 0000000..3fadac3 --- /dev/null +++ b/tests/amalgam/test/buildfile @@ -0,0 +1,8 @@ +using cxx + +hxx.ext = hxx +cxx.ext = cxx + +import libs += amalgam-libtest + +exe{driver}: cxx{driver} $libs diff --git a/tests/amalgam/test/driver.cxx b/tests/amalgam/test/driver.cxx new file mode 100644 index 0000000..70b4146 --- /dev/null +++ b/tests/amalgam/test/driver.cxx @@ -0,0 +1,4 @@ +int +main () +{ +} -- cgit v1.1