aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/file.cxx92
1 files changed, 53 insertions, 39 deletions
diff --git a/build2/file.cxx b/build2/file.cxx
index 56e1600..d267fec 100644
--- a/build2/file.cxx
+++ b/build2/file.cxx
@@ -829,62 +829,76 @@ namespace build2
//
dir_path out_root;
- // First search subprojects, starting with our root and then trying
- // outer roots for as long as we are inside an amalgamation.
+ // First try the config.import.* mechanism. The idea is that if the user
+ // explicitly told us the project's location, then we should prefer that
+ // over anything that we may discover. In particular, we will prefer it
+ // over any bundled subprojects.
//
- for (scope* r (&iroot);; r = r->parent_scope ()->root_scope ())
+
+ // Note: overridable variable with path auto-completion.
+ //
+ const variable& var (
+ var_pool.insert<abs_dir_path> ("config.import." + project, true));
+
+ if (auto l = iroot[var])
{
- l5 ([&]{trace << "looking in " << r->out_path ();});
+ out_root = cast<dir_path> (l); // Normalized and actualized.
+ config::save_variable (iroot, var); // Mark as part of configuration.
- // First check the amalgamation itself.
+ // Empty config.import.* value means don't look in subprojects or
+ // amalgamations and go straight to the rule-specific import (e.g., to
+ // use system-installed).
//
- if (r != &iroot && cast<string> (r->vars["project"]) == project)
+ if (out_root.empty ())
{
- out_root = r->out_path ();
- break;
+ target.proj = &project;
+ l5 ([&]{trace << "skipping " << target;});
+ return names {move (target)};
}
-
- if (auto l = r->vars["subprojects"])
+ }
+ else
+ {
+ // Otherwise 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 ())
{
- const auto& m (cast<subprojects> (l));
- auto i (m.find (project));
+ l5 ([&]{trace << "looking in " << r->out_path ();});
- if (i != m.end ())
+ // First check the amalgamation itself.
+ //
+ if (r != &iroot && cast<string> (r->vars["project"]) == project)
{
- const dir_path& d ((*i).second);
- out_root = r->out_path () / d;
+ out_root = r->out_path ();
break;
}
- }
- if (!r->vars["amalgamation"])
- break;
+ if (auto l = r->vars["subprojects"])
+ {
+ const auto& m (cast<subprojects> (l));
+ auto i (m.find (project));
+
+ if (i != m.end ())
+ {
+ const dir_path& d ((*i).second);
+ out_root = r->out_path () / d;
+ break;
+ }
+ }
+
+ if (!r->vars["amalgamation"])
+ break;
+ }
}
- // Then try the config.import.* mechanism.
+ // If we couldn't find the project, convert it back into qualified target
+ // and return to let someone else (e.g., a rule) to take a stab at it.
//
if (out_root.empty ())
{
- // Note: overridable variable with path auto-completion.
- //
- const variable& var (
- var_pool.insert<abs_dir_path> ("config.import." + project, true));
-
- if (auto l = iroot[var])
- {
- out_root = cast<dir_path> (l); // Normalized and actualized.
- config::save_variable (iroot, var); // Mark as part of configuration.
- }
- else
- {
- // If we can't find the project, convert it back into qualified
- // target and return to let someone else (e.g., a rule) to take
- // a stab at it.
- //
- target.proj = &project;
- l5 ([&]{trace << "postponing " << target;});
- return names {move (target)};
- }
+ target.proj = &project;
+ l5 ([&]{trace << "postponing " << target;});
+ return names {move (target)};
}
// Bootstrap the imported root scope. This is pretty similar to what we do