From 51267fc81abdbf0ca7f1098fccd7f3e0d7da5306 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 9 Mar 2016 11:06:26 +0200 Subject: Force creation of output directory before opening depdb --- build2/algorithm | 10 +++++----- build2/algorithm.cxx | 15 ++++++++------- build2/cxx/compile.cxx | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 13 deletions(-) (limited to 'build2') 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 (d, string (), nullptr, &s)); - match (a, dt); - t.prerequisite_targets.emplace_back (&dt); + fsdir* r (&search (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 ( 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. -- cgit v1.1