aboutsummaryrefslogtreecommitdiff
path: root/build2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-03-09 11:06:26 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-03-09 11:06:26 +0200
commit51267fc81abdbf0ca7f1098fccd7f3e0d7da5306 (patch)
tree3dd4f7216a49064e2ba9a9eee5c0133749b35fe1 /build2
parenta18191ff73781a92605762f3f409b9f6783d3ce8 (diff)
Force creation of output directory before opening depdb
Diffstat (limited to 'build2')
-rw-r--r--build2/algorithm10
-rw-r--r--build2/algorithm.cxx15
-rw-r--r--build2/cxx/compile.cxx16
3 files changed, 28 insertions, 13 deletions
diff --git a/build2/algorithm b/build2/algorithm
index 7c9239d..06a5c01 100644
--- a/build2/algorithm
+++ b/build2/algorithm
@@ -128,12 +128,12 @@ namespace build2
group_view
resolve_group_members (action, target&);
- // Inject dependency on the parent directory's fsdir{}, unless it is
- // the project's out_root (or is outside of any project; say, for
- // example, an install directory). Normally this function is called
- // from the rule's apply() function.
+ // Inject dependency on the parent directory's fsdir{}, unless it is outside
+ // of any project (say, for example, an installation directory). Return the
+ // injected target or NULL. Normally this function is called from the rule's
+ // apply() function.
//
- void
+ fsdir*
inject_parent_fsdir (action, target&);
// Execute the action on target, assuming a rule has been matched
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index 89dd029..80325ed 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -300,7 +300,7 @@ namespace build2
}
}
- void
+ fsdir*
inject_parent_fsdir (action a, target& t)
{
tracer trace ("inject_parent_fsdir");
@@ -309,7 +309,7 @@ namespace build2
scope* rs (s.root_scope ());
if (rs == nullptr) // Could be outside any project.
- return;
+ return nullptr;
const dir_path& out_root (rs->out_path ());
@@ -318,14 +318,15 @@ namespace build2
//
const dir_path& d (t.name.empty () ? t.dir.directory () : t.dir);
- if (!d.sub (out_root) || d == out_root)
- return;
+ if (!d.sub (out_root))
+ return nullptr;
l6 ([&]{trace << "for " << t;});
- fsdir& dt (search<fsdir> (d, string (), nullptr, &s));
- match (a, dt);
- t.prerequisite_targets.emplace_back (&dt);
+ fsdir* r (&search<fsdir> (d, string (), nullptr, &s));
+ match (a, *r);
+ t.prerequisite_targets.emplace_back (r);
+ return r;
}
target_state
diff --git a/build2/cxx/compile.cxx b/build2/cxx/compile.cxx
index 015d538..2d42cbc 100644
--- a/build2/cxx/compile.cxx
+++ b/build2/cxx/compile.cxx
@@ -77,7 +77,7 @@ namespace build2
// Inject dependency on the output directory.
//
- inject_parent_fsdir (a, t);
+ fsdir* dir (inject_parent_fsdir (a, t));
// Search and match all the existing prerequisites. The injection
// code (below) takes care of the ones it is adding.
@@ -143,6 +143,20 @@ namespace build2
dynamic_cast<cxx&> (
mr.target != nullptr ? *mr.target : *mr.prerequisite->target));
+ // Make sure the output directory exists.
+ //
+ // Is this the right thing to do? It does smell a bit, but then we do
+ // worse things in inject_prerequisites() below. There is also no way
+ // to postpone this until update since we need to extract and inject
+ // header dependencies now (we don't want to be calling search() and
+ // match() in update), which means we need to cache them now as well.
+ // So the only alternative, it seems, is to cache the updates to the
+ // database until later which will sure complicate (and slow down)
+ // things.
+ //
+ if (dir != nullptr)
+ execute_direct (a, *dir);
+
depdb dd (t.path () + ".d");
// First should come the rule name/version.