Hey Martin, sorry for the delay when it came to posting this patch.
Here is a small patch that adds a new option to make that causes make to abort after N failures. Martin suggest that -k should take an extra argument where the user can tell make to abort after N failures, quite useful if you want are running a build robot, or similar. The patch is a bit rough, but does anyone object to the idea of getting something like this into GNU make? If not, I'll happily clean up the patch and submit a ChangeLog and anything else that might be required. Cheers, Alfred diff --git a/job.c b/job.c index a81cd81..200f754 100644 --- a/job.c +++ b/job.c @@ -379,9 +379,19 @@ static void child_error (char *target_name, int exit_code, int exit_sig, int coredump, int ignored) { + if (max_keep_going_count <= keep_going_count) + { + error (NILF, _("*** [%s] Error (aborted after %d failures) %d"), + target_name, keep_going_count, exit_code); + die (2); + } + if (ignored && silent_flag) return; + /* Only increase KEEP_GOING_COUNT if the job _really_ failed. */ + keep_going_count++; + #ifdef VMS if (!(exit_code & 1)) error (NILF, diff --git a/main.c b/main.c index 483babf..47e79ba 100644 --- a/main.c +++ b/main.c @@ -189,9 +189,13 @@ int no_builtin_variables_flag = 0; /* Nonzero means keep going even if remaking some file fails (-k). */ -int keep_going_flag; +int keep_going_flag = 0; int default_keep_going_flag = 0; +int keep_going_count = 0; +unsigned int max_keep_going_count = -1; +static unsigned int inf_keep_going_count = 0; + /* Nonzero means check symlink mtimes. */ int check_symlink_flag = 0; @@ -318,6 +322,8 @@ static const char *const usage[] = N_("\ -k, --keep-going Keep going when some targets can't be made.\n"), N_("\ + --keep-going-count[=N] Keep going when N targets can't be made.\n"), + N_("\ -l [N], --load-average[=N], --max-load[=N]\n\ Don't start multiple jobs unless load is below N.\n"), N_("\ @@ -416,6 +422,14 @@ static const struct command_switch switches[] = { 'W', string, (char *) &new_files, 0, 0, 0, 0, 0, "what-if" }, { CHAR_MAX+4, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0, "warn-undefined-variables" }, + /* BUG: There is a bug in the argument parser where if you have a + long-optin, but no corresponding short option in the ASCII + range, the output will produce a charachter that can corrupt + the terminal. + */ + { CHAR_MAX+5, positive_int, (char *) &max_keep_going_count, 1, 1, 0, + (char *) &inf_keep_going_count, + (char *) &max_keep_going_count, "keep-going-count" }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; diff --git a/make.h b/make.h index 994f4f2..43f9677 100644 --- a/make.h +++ b/make.h @@ -499,6 +499,9 @@ extern char *getwd (); extern const struct floc *reading_file; extern const struct floc **expanding_var; +extern int keep_going_count; +extern unsigned int max_keep_going_count; + extern char **environ; extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag; diff --git a/remake.c b/remake.c index a752734..b774dbd 100644 --- a/remake.c +++ b/remake.c @@ -311,7 +311,7 @@ update_file (struct file *file, unsigned int depth) alloca (0); /* If we got an error, don't bother with double_colon etc. */ - if (status != 0 && !keep_going_flag) + if (status != 0 && keep_going_flag == 1) return status; if (f->command_state == cs_running @@ -350,7 +350,7 @@ complain (const struct file *file) const char *msg_parent = _("%sNo rule to make target `%s', needed by `%s'%s"); - if (!keep_going_flag) + if (keep_going_flag == 0) { if (file->parent == 0) fatal (NILF, msg_noparent, "", file->name, ""); @@ -529,7 +529,7 @@ update_file_1 (struct file *file, unsigned int depth) while (f != 0); } - if (dep_status != 0 && !keep_going_flag) + if (dep_status != 0 && keep_going_flag == 0) break; if (!running) @@ -587,7 +587,7 @@ update_file_1 (struct file *file, unsigned int depth) while (f != 0); } - if (dep_status != 0 && !keep_going_flag) + if (dep_status != 0 && keep_going_flag == 0) break; if (!running) @@ -619,7 +619,7 @@ update_file_1 (struct file *file, unsigned int depth) DBF (DB_VERBOSE, _("Giving up on target file `%s'.\n")); - if (depth == 0 && keep_going_flag + if (depth == 0 && keep_going_flag == 1 && !just_print_flag && !question_flag) error (NILF, _("Target `%s' not remade because of errors."), file->name); @@ -1017,7 +1017,7 @@ check_dep (struct file *file, unsigned int depth, if (! d->ignore_mtime) *must_make_ptr = maybe_make; check_renamed (d->file); - if (dep_status != 0 && !keep_going_flag) + if (dep_status != 0 && keep_going_flag == 0) break; if (d->file->command_state == cs_running _______________________________________________ Bug-make mailing list Bug-make@gnu.org http://lists.gnu.org/mailman/listinfo/bug-make