From f56b5a42b9aaaeb0c4e7dee894dea9686599b88c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 24 Jun 2015 17:26:17 +0200 Subject: Implement proper target type detection in dependency injection --- build/cxx/rule.cxx | 67 +++++++++++++++++++++++++++++++++++++++++++++------ build/diagnostics.cxx | 5 +++- build/root.build | 5 ++++ tests/.gitignore | 4 +++ tests/cli/buildfile | 4 +-- 5 files changed, 75 insertions(+), 10 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 +#include #include #include #include // 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; + + static ext_map + build_ext_map (scope& r) + { + ext_map m; + + if (auto val = r["h.ext"]) + m[&extension_pool.find (val.as ())] = &h::static_type; + + if (auto val = r["c.ext"]) + m[&extension_pool.find (val.as ())] = &c::static_type; + + if (auto val = r["hxx.ext"]) + m[&extension_pool.find (val.as ())] = &hxx::static_type; + + if (auto val = r["ixx.ext"]) + m[&extension_pool.find (val.as ())] = &ixx::static_type; + + if (auto val = r["txx.ext"]) + m[&extension_pool.find (val.as ())] = &txx::static_type; + + if (auto val = r["cxx.ext"]) + m[&extension_pool.find (val.as ())] = &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 (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 diff --git a/tests/.gitignore b/tests/.gitignore index e54525b..d22ca88 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1 +1,5 @@ driver + +# Temporary out-of-tree build directories. +# +*-build diff --git a/tests/cli/buildfile b/tests/cli/buildfile index 705f302..d71a677 100644 --- a/tests/cli/buildfile +++ b/tests/cli/buildfile @@ -1,6 +1,6 @@ -hxx.ext = hpp +hxx.ext = cxx.ext = cpp ixx.ext = ipp -exe{test}: cxx{driver test} +exe{driver}: cxx{driver test} cxx{test}: cli{test} -- cgit v1.1