aboutsummaryrefslogtreecommitdiff
path: root/build2/target
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-04-19 09:24:38 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-04-19 15:25:50 +0200
commitfc18a6dc1fcb02b505f07914e484cebbaf268698 (patch)
tree2cb9b04c5924dfd46e7d934912b41c3efd894a93 /build2/target
parentae20570f2ad55b2fa8e71cf450457cb9c4b21b1b (diff)
Redesign src/out scoping
We no longer enter paths from the src tree into scope map. Instead, targets from the src tree now include their out tree directory (in essence their "configuration"). This is then used to find a target's scope. See the comment in class target for details. The result of this change is that we can now again build multiple configurations (out trees) for same project at once.
Diffstat (limited to 'build2/target')
-rw-r--r--build2/target95
1 files changed, 58 insertions, 37 deletions
diff --git a/build2/target b/build2/target
index 241f6ff..9061e2d 100644
--- a/build2/target
+++ b/build2/target
@@ -127,24 +127,24 @@ namespace build2
public:
typedef build2::action action_type;
- virtual
- ~target () = default;
-
- target (const target&) = delete;
- target& operator= (const target&) = delete;
-
- target (dir_path d, string n, const string* e)
- : dir (move (d)), name (move (n)), ext (e) {}
-
- // Reset the target before matching a rule for it. The
- // default implementation clears prerequisite_targets.
+ // For targets that are in the src tree of a project we also keep the
+ // corresponding out directory. As a result we may end up with multiple
+ // targets for the same file if we are building multiple configurations of
+ // the same project at once. We do it this way because, in a sense, a
+ // target's out directory is its "configuration" (in terms of variables).
+ // As an example, consider installing the same README file (src) but for
+ // two different project configurations at once. Which installation
+ // directory should we use? The answer depends on which configuration you
+ // ask.
+ //
+ // Empty out directory indicates this target is in the out tree (including
+ // when src == out). We also treat out of project targets as being in the
+ // out tree.
//
- virtual void
- reset (action_type);
-
const dir_path dir; // Absolute and normalized.
+ const dir_path out; // Empty or absolute and normalized.
const string name;
- const string* ext; // Extension, NULL - unspecified, empty - no extension.
+ const string* ext; // Extension. NULL - unspecified, empty - no extension.
// Target group to which this target belongs, if any. Note that
// we assume that the group and all its members are in the same
@@ -187,6 +187,22 @@ namespace build2
//
target* group = nullptr;
+ public:
+ virtual
+ ~target () = default;
+
+ target (const target&) = delete;
+ target& operator= (const target&) = delete;
+
+ target (dir_path d, dir_path o, string n, const string* e)
+ : dir (move (d)), out (move (o)), name (move (n)), ext (e) {}
+
+ // Reset the target before matching a rule for it. The default
+ // implementation clears prerequisite_targets.
+ //
+ virtual void
+ reset (action_type);
+
// You should not call this function directly; rather use
// resolve_group_members() from <build2/algorithm>.
//
@@ -197,7 +213,7 @@ namespace build2
// to the targets's members will be reflected in the key.
//
target_key
- key () const {return target_key {&type (), &dir, &name, ext};}
+ key () const {return target_key {&type (), &dir, &out, &name, ext};}
// Scoping.
//
@@ -227,13 +243,10 @@ namespace build2
scope&
weak_scope () const {return *root_scope ().weak_scope ();}
-
bool
in (const scope& s) const
{
- return
- (s.out_path_ != nullptr && dir.sub (*s.out_path_)) ||
- (s.src_path_ != nullptr && dir.sub (*s.src_path_));
+ return (out.empty () ? dir : out).sub (s.out_path ());
}
// Prerequisites.
@@ -401,8 +414,9 @@ namespace build2
recipe_type recipe_;
};
- ostream&
- operator<< (ostream&, const target&);
+ inline ostream&
+ operator<< (ostream& os, const target& t) {return os << t.key ();}
+
// A "range" that presents the prerequisites of a group and one of
// its members as one continuous sequence, or, in other words, as
@@ -780,21 +794,23 @@ namespace build2
iterator
find (const target_type& type,
const dir_path& dir,
+ const dir_path& out,
const string& name,
const string* ext,
tracer& trace) const
{
- return find (target_key {&type, &dir, &name, ext}, trace);
+ return find (target_key {&type, &dir, &out, &name, ext}, trace);
}
- // As above but ignore the extension and return the target or
- // nullptr instead of the iterator.
+ // As above but ignore the extension and return the target or nullptr
+ // instead of the iterator.
//
template <typename T>
T*
- find (const dir_path& dir, const string& name) const
+ find (const dir_path& dir, const dir_path& out, const string& name) const
{
- auto i (map_.find (target_key {&T::static_type, &dir, &name, nullptr}));
+ auto i (map_.find (
+ target_key {&T::static_type, &dir, &out, &name, nullptr}));
return i != map_.end () ? static_cast<T*> (i->second.get ()) : nullptr;
}
@@ -804,27 +820,33 @@ namespace build2
pair<target&, bool>
insert (const target_type&,
dir_path dir,
+ dir_path out,
string name,
const string* ext,
tracer&);
+
template <typename T>
T&
insert (const dir_path& dir,
+ const dir_path& out,
const string& name,
const string* ext,
tracer& t)
{
return static_cast<T&> (
- insert (T::static_type, dir, name, ext, t).first);
+ insert (T::static_type, dir, out, name, ext, t).first);
}
template <typename T>
T&
- insert (const dir_path& dir, const string& name, tracer& t)
+ insert (const dir_path& dir,
+ const dir_path& out,
+ const string& name,
+ tracer& t)
{
return static_cast<T&> (
- insert (T::static_type, dir, name, nullptr, t).first);
+ insert (T::static_type, dir, out, name, nullptr, t).first);
}
void
@@ -1072,9 +1094,13 @@ namespace build2
//
template <typename T>
target*
- target_factory (const target_type&, dir_path d, string n, const string* e)
+ target_factory (const target_type&,
+ dir_path d,
+ dir_path o,
+ string n,
+ const string* e)
{
- return new T (move (d), move (n), e);
+ return new T (move (d), move (o), move (n), e);
}
// Return fixed target extension.
@@ -1095,11 +1121,6 @@ namespace build2
const string*
target_extension_null (const target_key&, scope&);
- // Issue diagnostics and fail if called.
- //
- const string*
- target_extension_fail (const target_key&, scope&);
-
// Assert if called.
//
const string*