From fefe0657f29b8db782f7a722dd46b074b991cf08 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 23 Feb 2015 15:56:03 +0200 Subject: Redo rule match/build logic Now the rule is fully responsible for searching, matching, and building of prerequisites. --- build/search.cxx | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 build/search.cxx (limited to 'build/search.cxx') diff --git a/build/search.cxx b/build/search.cxx new file mode 100644 index 0000000..966f5f1 --- /dev/null +++ b/build/search.cxx @@ -0,0 +1,144 @@ +// file : build/search.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include + +#include // move +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace build +{ + target* + search_existing_target (prerequisite& p) + { + tracer trace ("search_existing_target"); + + assert (p.target == nullptr); + + // Look for an existing target in this prerequisite's directory scope. + // + path d; + if (p.dir.absolute ()) + d = p.dir; // Already normalized. + else + { + d = p.scope.path (); + + if (!p.dir.empty ()) + { + d /= p.dir; + d.normalize (); + } + } + + auto i (targets.find (p.type.id, d, p.name, p.ext, trace)); + + if (i == targets.end ()) + return 0; + + target& t (**i); + + level4 ([&]{trace << "existing target " << t << " for prerequsite " + << p;}); + + p.target = &t; + return &t; + } + + target* + search_existing_file (prerequisite& p, const paths& sp) + { + tracer trace ("search_existing_file"); + + assert (p.dir.relative ()); + + // Go over paths and extension looking for a file. + // + for (const path& d: sp) + { + path f (d / p.dir / path (p.name)); + + // @@ TMP: use target name as an extension. + // + const string& e (p.ext != nullptr ? *p.ext : p.type.name); + + if (!e.empty ()) + { + f += '.'; + f += e; + } + + timestamp mt (path_mtime (f)); + + if (mt == timestamp_nonexistent) + continue; + + level4 ([&]{trace << "found existing file " << f << " for prerequsite " + << p;}); + + // Find or insert. + // + auto r (targets.insert (p.type, f.directory (), p.name, p.ext, trace)); + + // Has to be a path_target. + // + path_target& t (dynamic_cast (r.first)); + + level4 ([&]{trace << (r.second ? "new" : "existing") << " target " + << t << " for prerequsite " << p;}); + + t.path (move (f)); + t.mtime (mt); + p.target = &t; + return &t; + } + + return nullptr; + } + + target& + create_new_target (prerequisite& p) + { + tracer trace ("search_new_target"); + + assert (p.target == nullptr); + + // We default to the target in this prerequisite's directory scope. + // + path d; + if (p.dir.absolute ()) + d = p.dir; // Already normalized. + else + { + d = p.scope.path (); + + if (!p.dir.empty ()) + { + d /= p.dir; + d.normalize (); + } + } + + // Find or insert. + // + auto r (targets.insert (p.type, move (d), p.name, p.ext, trace)); + assert (r.second); + + target& t (r.first); + + level4 ([&]{trace << "new target " << t << " for prerequsite " << p;}); + + p.target = &t; + return t; + } +} -- cgit v1.1