aboutsummaryrefslogtreecommitdiff
path: root/build/bd.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build/bd.cxx')
-rw-r--r--build/bd.cxx95
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;
+ }
}