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/file.cxx | 99 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 30 deletions(-) (limited to 'build/file.cxx') 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; -- cgit v1.1