aboutsummaryrefslogtreecommitdiff
path: root/build/target.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-01-16 14:11:14 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-01-16 14:11:14 +0200
commitc106259517d7693ea8e24564bc890fe575d5edcd (patch)
treebbf87f83edeaf60ff3dfa6fff33c6b7504f5318b /build/target.cxx
parentdf50091259a34fa4718f38c0e3b7b64f6e2469ac (diff)
Implement rule chaining for cxx::link
Diffstat (limited to 'build/target.cxx')
-rw-r--r--build/target.cxx46
1 files changed, 44 insertions, 2 deletions
diff --git a/build/target.cxx b/build/target.cxx
index 61423db..b20f53b 100644
--- a/build/target.cxx
+++ b/build/target.cxx
@@ -4,9 +4,8 @@
#include <build/target>
-#include <ostream>
-
#include <build/context>
+#include <build/diagnostics>
using namespace std;
@@ -37,7 +36,50 @@ namespace build
return os;
}
+ // target_set
+ //
+ auto target_set::
+ insert (const target_type& tt,
+ path dir,
+ std::string name,
+ const std::string* ext,
+ tracer& tr) -> pair<target&, bool>
+ {
+ //@@ OPT: would be nice to somehow first check if this target is
+ // already in the set before allocating a new instance.
+
+ // Find or insert.
+ //
+ auto r (
+ emplace (
+ unique_ptr<target> (tt.factory (move (dir), move (name), ext))));
+
+ target& t (**r.first);
+
+ // Update the extension if the existing target has it unspecified.
+ //
+ if (t.ext != ext)
+ {
+ trace (4, [&]{
+ tracer::record r (tr);
+ r << "assuming target " << t << " is the same as the one with ";
+ if (ext == nullptr)
+ r << "unspecified extension";
+ else if (ext->empty ())
+ r << "no extension";
+ else
+ r << "extension " << *ext;
+ });
+
+ if (ext != nullptr)
+ t.ext = ext;
+ }
+
+ return pair<target&, bool> (t, r.second);
+ }
+
target_set targets;
+
target* default_target = nullptr;
target_type_map target_types;