diff options
Diffstat (limited to 'build/bd.cxx')
-rw-r--r-- | build/bd.cxx | 95 |
1 files changed, 84 insertions, 11 deletions
diff --git a/build/bd.cxx b/build/bd.cxx index 918434a..03d0aa4 100644 --- a/build/bd.cxx +++ b/build/bd.cxx @@ -1,10 +1,17 @@ -// file : build/bd.cxx +// file : build/bd.cxx -*- C++ -*- // copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file +#include <time.h> // tzset() + #include <vector> +#include <cstdlib> // exit +#include <cassert> #include <iostream> +#include <system_error> +#include <build/process> +#include <build/timestamp> #include <build/target> using namespace std; @@ -14,33 +21,91 @@ namespace build bool update (target& t) { - const targets& ps (t.prerequisites ()); + auto tts (path_timestamp (t.name ())); + cout << t.name () << ": " << tts << endl; - for (target& p: ps) + bool u (tts == timestamp_nonexistent); + for (target& p: t.prerequisites ()) + { if (!update (p)) return false; - //@@ TODO: check for existance, compare timestamps. + if (!u) + { + auto tps (path_timestamp (p.name ())); + + if (tts <= tps) // Note: not just less. + { + cout << t.name () << " vs " << p.name () << ": " << (tps - tts) + << " ahead" << endl; + u = true; + } + } + } - auto r (t.rule ()); - return r != 0 ? r (t, t.prerequisites ()) : true; + if (!u) // Nothing to do. + return true; + + try + { + auto r (t.rule ()); + return r != 0 ? r (t) : true; + } + catch (const process_error& e) + { + // Take care of failed children. In a multi-threaded program that + // fork()'ed but did not exec(), it is unwise to try to do any kind + // of cleanup (like unwinding the stack and running destructors). + // + assert (e.child ()); + exit (1); + } } } using namespace build; bool -cxx_compile_rule (target& t, const targets& p) +cxx_compile_rule (target& t) { - //@@ TODO: actually execute + const targets& ps (t.prerequisites ()); + + //@@ TODO: assuming .cxx is first. + // + const target& p0 (ps[0]); + const char* args[] { + "g++-4.9", + "-std=c++11", + "-I..", + "-c", + "-o", t.name ().c_str (), + p0.name ().c_str (), + nullptr}; cerr << "c++ " << t.name () << endl; - return true; + + try + { + process pr (args); + return pr.wait (); + } + catch (const process_error& e) + { + cerr << "error: unable to execute '" << args[0] << "': " << + e.what () << endl; + + if (e.child ()) + throw; // Let our caller terminate us quickly without causing a scene. + + return false; + } } bool -cxx_link_rule (target& t, const targets& p) +cxx_link_rule (target& t) { + const targets& ps (t.prerequisites ()); + cerr << "ld " << t.name () << endl; return true; } @@ -48,6 +113,10 @@ cxx_link_rule (target& t, const targets& p) int main (int argc, char* argv[]) { + // Initialize time conversion data that is used by localtime_r(). + // + tzset (); + exe bd ("bd"); obj bd_o ("bd.o"); bd.prerequisite (bd_o); @@ -59,5 +128,9 @@ main (int argc, char* argv[]) bd_o.prerequisite (target); bd_o.rule (&cxx_compile_rule); - update (bd); + if (!update (bd)) + { + cerr << "unable to update '" << bd.name () << "'" << endl; + return 1; + } } |