aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/b.cxx2
-rw-r--r--build/context12
-rw-r--r--build/context.cxx19
-rw-r--r--build/cxx/rule.cxx8
-rw-r--r--build/diagnostics10
-rw-r--r--build/diagnostics.cxx20
-rw-r--r--build/dump3
-rw-r--r--build/dump.cxx116
-rw-r--r--build/name.cxx2
-rw-r--r--build/parser.cxx6
-rw-r--r--build/prerequisite.cxx4
-rw-r--r--build/spec.cxx2
-rw-r--r--build/target.cxx2
13 files changed, 142 insertions, 64 deletions
diff --git a/build/b.cxx b/build/b.cxx
index 0443b4b..c676f8a 100644
--- a/build/b.cxx
+++ b/build/b.cxx
@@ -144,7 +144,7 @@ main (int argc, char* argv[])
// Trace verbosity.
//
- verb = 4;
+ verb = 5;
// Register modules.
//
diff --git a/build/context b/build/context
index ac6e29c..723f9f9 100644
--- a/build/context
+++ b/build/context
@@ -77,10 +77,18 @@ namespace build
out_src (const path& src, const path& out_root, const path& src_root);
// If possible and beneficial, translate an absolute, normalized path
- // into relative to the work directory.
+ // into relative to the relative_base directory, which is normally
+ // work.
//
path
- relative_work (const path&);
+ relative (const path&);
+
+ // By default this points to work. Setting this to something else
+ // should only be done in tightly controlled, non-parallel
+ // situations (see dump). If base is empty, then relative()
+ // returns the original path.
+ //
+ extern const path* relative_base;
}
#include <build/context.txx>
diff --git a/build/context.cxx b/build/context.cxx
index 92f3db9..872a428 100644
--- a/build/context.cxx
+++ b/build/context.cxx
@@ -106,13 +106,20 @@ namespace build
return out_root / s.leaf (src_root);
}
+ const path* relative_base = &work;
+
path
- relative_work (const path& p)
+ relative (const path& p)
{
- if (p.sub (work))
- return p.leaf (work);
+ const path& b (*relative_base);
+
+ if (b.empty ())
+ return p;
+
+ if (p.sub (b))
+ return p.leaf (b);
- // If work is a sub-path of {src,out}_root and this path is also a
+ // If base is a sub-path of {src,out}_root and this path is also a
// sub-path of it, then use '..' to form a relative path.
//
// Don't think this is a good heuristic. For example, why shouldn't
@@ -125,9 +132,9 @@ namespace build
return p.relative (work);
*/
- if (p.root_directory () == work.root_directory ())
+ if (p.root_directory () == b.root_directory ())
{
- path r (p.relative (work));
+ path r (p.relative (b));
if (r.string ().size () < p.string ().size ())
return r;
diff --git a/build/cxx/rule.cxx b/build/cxx/rule.cxx
index f53dd3b..549d987 100644
--- a/build/cxx/rule.cxx
+++ b/build/cxx/rule.cxx
@@ -282,8 +282,8 @@ namespace build
// Translate paths to relative (to working directory) ones. This
// results in easier to read diagnostics.
//
- path ro (relative_work (o.path ()));
- path rs (relative_work (s->path ()));
+ path ro (relative (o.path ()));
+ path rs (relative (s->path ()));
const char* args[] = {
"g++-4.9",
@@ -580,7 +580,7 @@ namespace build
// Translate paths to relative (to working directory) ones. This
// results in easier to read diagnostics.
//
- path re (relative_work (e.path ()));
+ path re (relative (e.path ()));
vector<path> ro;
vector<const char*> args {"g++-4.9", "-std=c++14", "-g", "-o"};
@@ -591,7 +591,7 @@ namespace build
{
if (const obj* o = dynamic_cast<const obj*> (p.target))
{
- ro.push_back (relative_work (o->path ()));
+ ro.push_back (relative (o->path ()));
args.push_back (ro.back ().string ().c_str ());
}
}
diff --git a/build/diagnostics b/build/diagnostics
index 270fa7a..68f449b 100644
--- a/build/diagnostics
+++ b/build/diagnostics
@@ -23,17 +23,17 @@ namespace build
//
class failed: public std::exception {};
- // In addition to calling relative_work(), this function also uses
- // shorter notations such as '~/'. If the path is the same as work,
- // it returns '.'.
+ // In addition to calling relative(), this function also uses shorter
+ // notations such as '~/'. If the path is the same as base, it returns
+ // '.'.
//
std::string
- diag_relative_work (const path&);
+ diag_relative (const path&);
inline std::ostream&
operator<< (std::ostream& os, const path& p)
{
- return os << diag_relative_work (p);
+ return os << diag_relative (p);
}
// Print process commmand line.
diff --git a/build/diagnostics.cxx b/build/diagnostics.cxx
index f5802de..53d1a09 100644
--- a/build/diagnostics.cxx
+++ b/build/diagnostics.cxx
@@ -14,11 +14,13 @@ using namespace std;
namespace build
{
string
- diag_relative_work (const path& p)
+ diag_relative (const path& p)
{
+ const path& b (*relative_base);
+
if (p.absolute ())
{
- if (p == work)
+ if (p == b)
return ".";
#ifndef _WIN32
@@ -26,26 +28,26 @@ namespace build
return "~";
#endif
- path rw (relative_work (p));
+ path rb (relative (p));
#ifndef _WIN32
- if (rw.relative ())
+ if (rb.relative ())
{
// See if the original path with the ~/ shortcut is better
- // that the relative to work.
+ // that the relative to base.
//
if (p.sub (home))
{
path rh (p.leaf (home));
- if (rw.string ().size () > rh.string ().size () + 2) // 2 for '~/'
+ if (rb.string ().size () > rh.string ().size () + 2) // 2 for '~/'
return "~/" + rh.string ();
}
}
- else if (rw.sub (home))
- return "~/" + rw.leaf (home).string ();
+ else if (rb.sub (home))
+ return "~/" + rb.leaf (home).string ();
#endif
- return rw.string ();
+ return rb.string ();
}
return p.string ();
diff --git a/build/dump b/build/dump
index e3cc5d2..48da079 100644
--- a/build/dump
+++ b/build/dump
@@ -9,9 +9,6 @@ namespace build
{
void
dump ();
-
- void
- dump_scopes ();
}
#endif // BUILD_DUMP
diff --git a/build/dump.cxx b/build/dump.cxx
index 98b0ff2..45ec584 100644
--- a/build/dump.cxx
+++ b/build/dump.cxx
@@ -4,6 +4,7 @@
#include <build/dump>
+#include <set>
#include <string>
#include <cassert>
#include <iostream>
@@ -11,53 +12,54 @@
#include <build/scope>
#include <build/target>
#include <build/variable>
+#include <build/context>
#include <build/diagnostics>
using namespace std;
namespace build
{
- void
- dump ()
+ static void
+ dump_target (const target& t)
{
- cout << endl;
+ cerr << t << ':';
- for (const auto& pt: targets)
+ for (const prerequisite& p: t.prerequisites)
{
- target& t (*pt);
-
- cout << t << ':';
-
- for (const auto& p: t.prerequisites)
- {
- cout << ' ' << p;
- }
-
- cout << endl;
+ cerr << ' ' << p;
}
-
- cout << endl;
}
static void
- dump_scope (scope& p, scope_map::iterator& i, string& ind)
+ dump_scope (scope& p,
+ scope_map::iterator& i,
+ string& ind,
+ set<const target*>& rts)
{
- string d (diag_relative_work (p.path ()));
+ string d (diag_relative (p.path ()));
if (d.back () != path::traits::directory_separator)
d += '/';
cerr << ind << d << ":" << endl
- << ind << '{' << endl;
+ << ind << '{';
+
+ const path* orb (relative_base);
+ relative_base = &p.path ();
ind += " ";
+ bool vb (false), sb (false); // Variable/scope block.
+
+ // Variables.
+ //
for (const auto& e: p.variables)
{
const variable& var (e.first);
const value_ptr& val (e.second);
- cerr << ind << var.name << " = ";
+ cerr << endl
+ << ind << var.name << " = ";
if (val == nullptr)
cerr << "[undefined]";
@@ -68,28 +70,90 @@ namespace build
cerr << dynamic_cast<list_value&> (*val).data;
}
- cerr << endl;
+ vb = true;
}
- // Print nested scopes of which we are a parent.
+ // Nested scopes of which we are a parent.
//
for (auto e (scopes.end ()); i != e && i->second.parent () == &p; )
{
+ if (vb)
+ {
+ cerr << endl;
+ vb = false;
+ }
+
+ if (sb)
+ cerr << endl; // Extra newline between scope blocks.
+
+ cerr << endl;
scope& s (i->second);
- dump_scope (s, ++i, ind);
+ dump_scope (s, ++i, ind, rts);
+
+ sb = true;
+ }
+
+ // Targets.
+ //
+ for (const auto& pt: targets)
+ {
+ const target& t (*pt);
+ const scope* ts (&scopes.find (t.dir));
+
+ bool f (false);
+
+ if (ts == &p)
+ {
+ // If this is the ultimate root scope, check that this target
+ // hasn't been handled by the src logic below.
+ //
+ f = (ts != root_scope || rts.find (&t) == rts.end ());
+ }
+ // If this target is in the ultimate root scope and we have a
+ // corresponding src directory (i.e., we are a scope inside a
+ // project), check whether this target is in our src.
+ //
+ else if (ts == root_scope && p.src_path_ != nullptr)
+ {
+ if (t.dir.sub (p.src_path ()))
+ {
+ // Check that it hasn't already been handled by a more qualified
+ // scope.
+ //
+ f = rts.insert (&t).second;
+ }
+ }
+
+ if (!f)
+ continue;
+
+ if (vb || sb)
+ {
+ cerr << endl;
+ vb = sb = false;
+ }
+
+ cerr << endl
+ << ind;
+ dump_target (t);
}
ind.resize (ind.size () - 2);
- cerr << ind << '}' << endl;
+ relative_base = orb;
+
+ cerr << endl
+ << ind << '}';
}
void
- dump_scopes ()
+ dump ()
{
string ind;
+ set<const target*> rts;
auto i (scopes.begin ());
scope& r (i->second); // Root scope.
assert (&r == root_scope);
- dump_scope (r, ++i, ind);
+ dump_scope (r, ++i, ind, rts);
+ cerr << endl;
}
}
diff --git a/build/name.cxx b/build/name.cxx
index 46e2440..ebc7372 100644
--- a/build/name.cxx
+++ b/build/name.cxx
@@ -24,7 +24,7 @@ namespace build
if (!n.dir.empty ())
{
- string s (diag_relative_work (n.dir));
+ string s (diag_relative (n.dir));
// If both type and value are empty, there will be nothing printed.
//
diff --git a/build/parser.cxx b/build/parser.cxx
index 809841f..b21dd6f 100644
--- a/build/parser.cxx
+++ b/build/parser.cxx
@@ -40,7 +40,7 @@ namespace build
void parser::
parse_buildfile (istream& is, const path& p, scope& root, scope& base)
{
- string rw (diag_relative_work (p));
+ string rw (diag_relative (p)); // Relative to work.
path_ = &rw;
lexer l (is, rw);
@@ -431,7 +431,7 @@ namespace build
level4 ([&]{trace (t) << "entering " << p;});
- string rw (diag_relative_work (p));
+ string rw (diag_relative (p)); // Relative to work.
const string* op (path_);
path_ = &rw;
@@ -558,7 +558,7 @@ namespace build
level4 ([&]{trace (t) << "entering " << p;});
- string rw (diag_relative_work (p));
+ string rw (diag_relative (p)); // Relative to work.
const string* op (path_);
path_ = &rw;
diff --git a/build/prerequisite.cxx b/build/prerequisite.cxx
index feb6381..aa6c53c 100644
--- a/build/prerequisite.cxx
+++ b/build/prerequisite.cxx
@@ -28,7 +28,7 @@ namespace build
//
if (!p.dir.absolute ())
{
- string s (diag_relative_work (p.scope.path ()));
+ string s (diag_relative (p.scope.path ()));
if (s != ".")
{
@@ -45,7 +45,7 @@ namespace build
//
if (!p.dir.empty ())
{
- string s (diag_relative_work (p.dir));
+ string s (diag_relative (p.dir));
if (s != ".")
{
diff --git a/build/spec.cxx b/build/spec.cxx
index d68154f..a1f6283 100644
--- a/build/spec.cxx
+++ b/build/spec.cxx
@@ -17,7 +17,7 @@ namespace build
{
if (!s.src_base.empty ())
{
- string d (diag_relative_work (s.src_base));
+ string d (diag_relative (s.src_base));
if (d != ".")
{
diff --git a/build/target.cxx b/build/target.cxx
index 1a8fbf7..dc85402 100644
--- a/build/target.cxx
+++ b/build/target.cxx
@@ -116,7 +116,7 @@ namespace build
if (!k.dir->empty ())
{
- string s (diag_relative_work (*k.dir));
+ string s (diag_relative (*k.dir));
if (s != ".")
{