aboutsummaryrefslogtreecommitdiff
path: root/build/bd.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build/bd.cxx')
-rw-r--r--build/bd.cxx88
1 files changed, 58 insertions, 30 deletions
diff --git a/build/bd.cxx b/build/bd.cxx
index faae4c4..c592d64 100644
--- a/build/bd.cxx
+++ b/build/bd.cxx
@@ -5,7 +5,6 @@
#include <time.h> // tzset()
#include <vector>
-#include <cstdlib> // exit
#include <cassert>
#include <iostream>
#include <typeinfo>
@@ -14,6 +13,7 @@
#include <build/target>
#include <build/rule>
#include <build/process>
+#include <build/diagnostics>
using namespace std;
@@ -38,7 +38,21 @@ namespace build
{
const rule& ru (rs.first->second);
- if (recipe re = ru.match (t))
+ recipe re;
+
+ {
+ auto g (
+ make_exception_guard (
+ [] (target& t)
+ {
+ cerr << "info: while matching a rule for target " << t << endl;
+ },
+ t));
+
+ re = ru.match (t);
+ }
+
+ if (re)
{
t.recipe (re);
break;
@@ -83,21 +97,23 @@ namespace build
}
}
- try
- {
- t.state ((ts = t.recipe () (t)));
- assert (ts != target_state::unknown);
- return ts;
- }
- catch (const process_error& e)
+ const recipe& r (t.recipe ());
+
{
- // 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);
+ auto g (
+ make_exception_guard (
+ [] (target& t)
+ {
+ cerr << "info: while building target " << t << endl;
+ },
+ t));
+
+ ts = r (t);
}
+
+ assert (ts != target_state::unknown);
+ t.state (ts);
+ return ts;
}
}
@@ -140,24 +156,36 @@ main (int argc, char* argv[])
//
//
- if (!match (bd))
- return 1; // Diagnostics has already been issued.
-
- switch (update (bd))
+ try
{
- case target_state::uptodate:
+ if (!match (bd))
+ return 1; // Diagnostics has already been issued.
+
+ switch (update (bd))
{
- cerr << "info: target " << bd << " is up to date" << endl;
+ case target_state::uptodate:
+ {
+ cerr << "info: target " << bd << " is up to date" << endl;
+ break;
+ }
+ case target_state::updated:
break;
+ case target_state::failed:
+ {
+ cerr << "error: failed to update target " << bd << endl;
+ return 1;
+ }
+ case target_state::unknown:
+ assert (false);
}
- case target_state::updated:
- break;
- case target_state::failed:
- {
- cerr << "error: failed to update target " << bd << endl;
- return 1;
- }
- case target_state::unknown:
- assert (false);
+ }
+ catch (const error&)
+ {
+ return 1; // Diagnostics has already been issued.
+ }
+ catch (const std::exception& e)
+ {
+ cerr << "error: " << e.what () << endl;
+ return 1;
}
}