aboutsummaryrefslogtreecommitdiff
path: root/build
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-06-24 17:26:17 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-06-24 17:26:17 +0200
commitf56b5a42b9aaaeb0c4e7dee894dea9686599b88c (patch)
treea4c042781770c4fd75fad031b686153bba1beadf /build
parente815af118562c68794efbd310c887acd8eae800c (diff)
Implement proper target type detection in dependency injection
Diffstat (limited to 'build')
-rw-r--r--build/cxx/rule.cxx67
-rw-r--r--build/diagnostics.cxx5
-rw-r--r--build/root.build5
3 files changed, 69 insertions, 8 deletions
diff --git a/build/cxx/rule.cxx b/build/cxx/rule.cxx
index cba1a1b..79b6072 100644
--- a/build/cxx/rule.cxx
+++ b/build/cxx/rule.cxx
@@ -4,6 +4,7 @@
#include <build/cxx/rule>
+#include <map>
#include <string>
#include <vector>
#include <cstddef> // size_t
@@ -211,6 +212,37 @@ namespace build
return r;
}
+ // The strings used as the map key should be from the extension_pool.
+ // This way we can just compare pointers.
+ //
+ using ext_map = map<const string*, const target_type*>;
+
+ static ext_map
+ build_ext_map (scope& r)
+ {
+ ext_map m;
+
+ if (auto val = r["h.ext"])
+ m[&extension_pool.find (val.as<const string&> ())] = &h::static_type;
+
+ if (auto val = r["c.ext"])
+ m[&extension_pool.find (val.as<const string&> ())] = &c::static_type;
+
+ if (auto val = r["hxx.ext"])
+ m[&extension_pool.find (val.as<const string&> ())] = &hxx::static_type;
+
+ if (auto val = r["ixx.ext"])
+ m[&extension_pool.find (val.as<const string&> ())] = &ixx::static_type;
+
+ if (auto val = r["txx.ext"])
+ m[&extension_pool.find (val.as<const string&> ())] = &txx::static_type;
+
+ if (auto val = r["cxx.ext"])
+ m[&extension_pool.find (val.as<const string&> ())] = &cxx::static_type;
+
+ return m;
+ }
+
void compile::
inject_prerequisites (action a, target& t, const cxx& s, scope& ds) const
{
@@ -326,18 +358,39 @@ namespace build
// then assume it is a header. Otherwise, let the standard
// mechanism derive the type from the extension. @@ TODO.
//
- const target_type* tt (&hxx::static_type);
- //@@ TMP
+ // Determine the target type.
//
- if (e != nullptr)
+ const target_type* tt (nullptr);
+
+ // See if this directory is part of any project out_root
+ // hierarchy. Note that this will miss all the headers
+ // that come from src_root (so they will be treated as
+ // generic C headers below). Generally, we don't have
+ // the ability to determine that some file belongs to
+ // src_root of some project. But that's not a problem
+ // for our purposes: it is only important for us to
+ // accurately determine target types for headers that
+ // could be auto-generated.
+ //
+ if (scope* r = scopes.find (d).root_scope ())
{
- if (*e == "ixx")
- tt = &ixx::static_type;
- else if (*e == "txx")
- tt = &txx::static_type;
+ // Get cahed (or build) a map of the extensions for the
+ // C/C++ files this project is using.
+ //
+ const ext_map& m (build_ext_map (*r));
+
+ auto i (m.find (e));
+ if (i != m.end ())
+ tt = i->second;
}
+ // If it is outside any project, or the project doesn't have
+ // such an extension, assume it is a plain old C header.
+ //
+ if (tt == nullptr)
+ tt = &h::static_type;
+
path_target& pt (
static_cast<path_target&> (search (*tt, d, n, e, &ds)));
diff --git a/build/diagnostics.cxx b/build/diagnostics.cxx
index d820145..f6d81bf 100644
--- a/build/diagnostics.cxx
+++ b/build/diagnostics.cxx
@@ -162,7 +162,10 @@ namespace build
diag_record r (text);
for (const char* const* p (args); *p != nullptr; p++)
- r << (p != args ? " " : "") << *p;
+ r << (p != args ? " " : "")
+ << (**p == '\0' ? "\"" : "") // Quote empty arguments.
+ << *p
+ << (**p == '\0' ? "\"" : "");
}
// Trace verbosity level.
diff --git a/build/root.build b/build/root.build
index dc1c297..5af4637 100644
--- a/build/root.build
+++ b/build/root.build
@@ -4,5 +4,10 @@
using cxx
+hxx.ext =
+ixx.ext = ixx
+txx.ext = txx
+cxx.ext = cxx
+
cxx.std = 14
cxx.poptions += -I$src_root