diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | config.ami.template | 9 | ||||
-rw-r--r-- | config.h-vms.template | 9 | ||||
-rw-r--r-- | config.h.W32.template | 13 | ||||
-rw-r--r-- | configh.dos.template | 7 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | filedef.h | 10 | ||||
-rw-r--r-- | implicit.c | 8 | ||||
-rw-r--r-- | job.c | 86 | ||||
-rw-r--r-- | makeint.h | 23 | ||||
-rw-r--r-- | misc.c | 164 | ||||
-rw-r--r-- | tests/ChangeLog | 1 | ||||
-rw-r--r-- | tests/scripts/features/output-sync | 8 |
13 files changed, 182 insertions, 176 deletions
@@ -6,6 +6,21 @@ 2013-04-28 Paul Smith <psmith@gnu.org> + * makeint.h (message_s, error_s): Functions that print to strings + rather than directly to files. + * misc.c (message_s, error_s): Create them. + * job.c (child_error): Print error messages to the output sync + logs, if one exists, rather then directly to the terminal. + (reap_children): Move the per-line sync after child_error(). + + * configure.ac: Remove support for pre-ANSI variadic function calls. + * makeint.h: Ditto. + * misc.c: Ditto. + * config.ami.template: Ditto. + * config.h-vms.template: Ditto. + * config.h.W32.template: Ditto. + * configh.dos.template: Ditto. + Implement a "per-job" output synchronization option. * main.c (decode_output_sync_flags): Recognize the new option. diff --git a/config.ami.template b/config.ami.template index aa3a57e..8fe26bd 100644 --- a/config.ami.template +++ b/config.ami.template @@ -53,9 +53,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ /* Define if you have <alloca.h> and it should be used (not on Ultrix). */ /* #undef HAVE_ALLOCA_H */ -/* Define if you don't have vprintf but do have _doprnt. */ -/* #undef HAVE_DOPRNT */ - /* Define if your system has a working fnmatch function. */ /* #undef HAVE_FNMATCH */ @@ -115,9 +112,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ /* Define if you have <vfork.h>. */ /* #undef HAVE_VFORK_H */ -/* Define if you have the vprintf function. */ -#define HAVE_VPRINTF 1 - /* Define if you have the wait3 system call. */ /* #undef HAVE_WAIT3 */ @@ -303,9 +297,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ /* Define if you have the <ndir.h> header file. */ /* #undef HAVE_NDIR_H */ -/* Define to 1 if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - /* Define if you have the <stdlib.h> header file. */ /* #undef HAVE_STDLIB_H */ diff --git a/config.h-vms.template b/config.h-vms.template index de7665e..1b99dd4 100644 --- a/config.h-vms.template +++ b/config.h-vms.template @@ -75,9 +75,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ /* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */ /* #undef HAVE_ALLOCA_H */ -/* Define to 1 if you don't have vprintf but do have _doprnt. */ -/* #undef HAVE_DOPRNT */ - /* Define to 1 if you have the fdopen function. */ #define HAVE_FDOPEN 1 @@ -144,9 +141,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ /* Define to 1 if you have <vfork.h>. */ /* #undef HAVE_VFORK_H */ -/* Define to 1 if you have the vprintf function. */ -#define HAVE_VPRINTF 1 - /* Define to 1 if you have the wait3 system call. */ /* #undef HAVE_WAIT3 */ @@ -339,9 +333,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ /* Define to 1 if your compiler conforms to the ANSI C standard. */ #define HAVE_ANSI_COMPILER 1 -/* Define to 1 if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - /* Define to 1 if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 diff --git a/config.h.W32.template b/config.h.W32.template index a00e095..8818a76 100644 --- a/config.h.W32.template +++ b/config.h.W32.template @@ -109,9 +109,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ # define HAVE_DIRECT_H 1 #endif -/* Define to 1 if you don't have 'vprintf' but do have '_doprnt.' */ -/* #undef HAVE_DOPRNT */ - /* Use platform specific coding */ #define HAVE_DOS_PATHS 1 @@ -247,9 +244,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ /* Define to 1 if you have the 'socket' function. */ /* #undef HAVE_SOCKET */ -/* Define to 1 if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - /* Define to 1 if you have the <stdint.h> header file. */ #ifdef __MINGW32__ #define HAVE_STDINT_H 1 @@ -348,19 +342,12 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ #define HAVE_UNISTD_H 1 #endif -/* Define to 1 if you have the <varargs.h> header file. */ -/* #undef HAVE_VARARGS_H */ - /* Define to 1 if you have the 'vfork' function. */ /* #undef HAVE_VFORK */ /* Define to 1 if you have the <vfork.h> header file. */ /* #undef HAVE_VFORK_H */ -/* Define to 1 if you have the 'vprintf' function. */ -#define HAVE_VPRINTF 1 - - /* Define to 1 if you have the 'wait3' function. */ /* #undef HAVE_WAIT3 */ diff --git a/configh.dos.template b/configh.dos.template index 10d848f..61857ab 100644 --- a/configh.dos.template +++ b/configh.dos.template @@ -79,13 +79,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ /* Define to 1 if your compiler conforms to the ANSI C standard. */ #define HAVE_ANSI_COMPILER 1 -/* Define to 1 if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - -/* Define to 1 if you have the vprintf library function. */ -#undef HAVE_VPRINTF -#define HAVE_VPRINTF 1 - /* Define to 1 if you have the stricmp function. */ #define HAVE_STRICMP 1 diff --git a/configure.ac b/configure.ac index 2ba81ad..d610343 100644 --- a/configure.ac +++ b/configure.ac @@ -70,10 +70,6 @@ AS_IF([test "$ac_cv_prog_cc_stdc" != no], [Define to 1 if your compiler conforms to the ANSI C standard.]) ]) - -# Determine what kind of variadic function calls we support -AC_CHECK_HEADERS([stdarg.h varargs.h], [break]) - AM_PROG_CC_C_O AC_C_CONST AC_TYPE_SIGNAL @@ -164,7 +160,6 @@ AC_FUNC_STRCOLL AC_FUNC_ALLOCA AC_FUNC_FORK([]) -AC_FUNC_VPRINTF AC_FUNC_CLOSEDIR_VOID # See if the user wants to add (or not) GNU Guile support @@ -28,13 +28,9 @@ struct file const char *vpath; /* VPATH/vpath pathname */ struct dep *deps; /* all dependencies, including duplicates */ struct commands *cmds; /* Commands to execute for this target. */ - int command_flags; /* Flags OR'd in for cmds; see commands.h. */ const char *stem; /* Implicit stem, if an implicit rule has been used */ struct dep *also_make; /* Targets that are made by making this. */ - FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */ - FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating - has been performed. */ struct file *prev; /* Previous entry for same file name; used when there are multiple double-colon entries for the same file. */ @@ -59,7 +55,11 @@ struct file the same file. Otherwise this is null. */ struct file *double_colon; - short int update_status; /* Status of the last attempt to update, + FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */ + FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating + has been performed. */ + int command_flags; /* Flags OR'd in for cmds; see commands.h. */ + char update_status; /* Status of the last attempt to update, or -1 if none has been made. */ enum cmd_state /* State of the commands. */ { /* Note: It is important that cs_not_started be zero. */ @@ -221,9 +221,6 @@ pattern_search (struct file *file, int archive, = xmalloc (max_pattern_deps * sizeof (struct patdeps)); struct patdeps *pat = deplist; - /* All the prerequisites actually found for a rule, after expansion. */ - struct dep *deps; - /* Names of possible dependencies are constructed in this buffer. */ char *depname = alloca (namelen + max_pattern_dep_length); @@ -800,10 +797,7 @@ pattern_search (struct file *file, int archive, /* This pattern rule does apply. Stop looking for one. */ break; - /* This pattern rule does not apply. If some of its dependencies - succeeded, free the data structure describing them. */ - /* free_idep_chain (deps); */ - deps = 0; + /* This pattern rule does not apply. Keep looking. */ } /* If we found an applicable rule without intermediate files, don't try @@ -467,19 +467,46 @@ is_bourne_compatible_shell (const char *path) } +/* Write a message relating to a child. Write it to the child's output + sync file if present, otherwise to the terminal. */ + +static void +child_out (const struct child *child, const char *msg, int out) +{ + int outfd = out ? child->outfd : child->errfd; + + if (outfd >= 0) + { + lseek (outfd, 0, SEEK_END); + write (outfd, msg, strlen (msg)); + write (outfd, "\n", 1); + } + else + { + FILE *outf = out ? stdout : stderr; + + fputs (msg, outf); + putc ('\n', outf); + fflush (outf); + } +} + /* Write an error message describing the exit status given in EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME. Append "(ignored)" if IGNORED is nonzero. */ static void -child_error (const struct file *file, +child_error (const struct child *child, int exit_code, int exit_sig, int coredump, int ignored) { - const char *nm; const char *pre = "*** "; const char *post = ""; const char *dump = ""; - gmk_floc *flocp = &file->cmds->fileinfo; + const struct file *f = child->file; + gmk_floc *flocp = &f->cmds->fileinfo; + const char *msg; + const char *nm; + unsigned int l; if (ignored && silent_flag) return; @@ -501,18 +528,32 @@ child_error (const struct file *file, sprintf (a, "%s:%lu", flocp->filenm, flocp->lineno); nm = a; } - message (0, _("%s: recipe for target '%s' failed"), nm, file->name); + + msg = message_s (strlen (nm) + strlen (f->name), + 0, _("%s: recipe for target '%s' failed"), nm, f->name); + child_out (child, msg, 1); + + l = strlen (pre) + strlen (f->name) + strlen (post); #ifdef VMS - if (!(exit_code & 1)) - error (NILF, _("%s[%s] Error 0x%x%s"), pre, file->name, exit_code, post); + if (exit_code & 1 != 0) + return; + + msg = error_s (l + INTEGER_LENGTH, NILF, _("%s[%s] Error 0x%x%s"), + pre, f->name, exit_code, post); #else if (exit_sig == 0) - error (NILF, _("%s[%s] Error %d%s"), pre, file->name, exit_code, post); + msg = error_s (l + INTEGER_LENGTH, NILF, _("%s[%s] Error %d%s"), + pre, f->name, exit_code, post); else - error (NILF, _("%s[%s] %s%s%s"), - pre, file->name, strsignal (exit_sig), dump, post); + { + const char *s = strsignal (exit_sig); + msg = error_s (l + strlen (s) + strlen (dump), + NILF, _("%s[%s] %s%s%s"), pre, f->name, s, dump, post); + } #endif /* VMS */ + + child_out (child, msg, 0); } @@ -659,7 +700,7 @@ acquire_semaphore (void) fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; - fl.l_start = 0; /* lock just one byte */ + fl.l_start = 0; fl.l_len = 1; if (fcntl (sync_handle, F_SETLKW, &fl) != -1) return &fl; @@ -976,7 +1017,7 @@ reap_children (int block, int err) /* Search for a child matching the deceased one. */ lastc = 0; for (c = children; c != 0; lastc = c, c = c->next) - if (c->remote == remote && c->pid == pid) + if (c->pid == pid && c->remote == remote) break; if (c == 0) @@ -1006,11 +1047,6 @@ reap_children (int block, int err) c->sh_batch_file = NULL; } -#ifdef OUTPUT_SYNC - if (output_sync == OUTPUT_SYNC_JOB) - sync_output (c); -#endif - /* If this child had the good stdin, say it is now free. */ if (c->good_stdin) good_stdin_used = 0; @@ -1024,7 +1060,7 @@ reap_children (int block, int err) static int delete_on_error = -1; if (!dontcare) - child_error (c->file, exit_code, exit_sig, coredump, 0); + child_error (c, exit_code, exit_sig, coredump, 0); c->file->update_status = 2; if (delete_on_error == -1) @@ -1040,7 +1076,7 @@ reap_children (int block, int err) if (child_failed) { /* The commands failed, but we don't care. */ - child_error (c->file, exit_code, exit_sig, coredump, 1); + child_error (c, exit_code, exit_sig, coredump, 1); child_failed = 0; } @@ -1057,6 +1093,11 @@ reap_children (int block, int err) } else { +#ifdef OUTPUT_SYNC + /* If we're sync'ing per job, write it now. */ + if (output_sync == OUTPUT_SYNC_JOB) + sync_output (c); +#endif /* Check again whether to start remotely. Whether or not we want to changes over time. Also, start_remote_job may need state set up @@ -1089,7 +1130,7 @@ reap_children (int block, int err) #ifdef OUTPUT_SYNC /* Synchronize parallel output if requested */ - if (output_sync > OUTPUT_SYNC_JOB) + if (output_sync) sync_output (c); #endif /* OUTPUT_SYNC */ @@ -2199,14 +2240,15 @@ new_job (struct file *file) if (trace_flag) { char *newer = allocated_variable_expand_for_file ("$?", c->file); - char *nm; + const char *nm; if (! cmds->fileinfo.filenm) nm = _("<builtin>"); else { - nm = alloca (strlen (cmds->fileinfo.filenm) + 1 + 11 + 1); - sprintf (nm, "%s:%lu", cmds->fileinfo.filenm, cmds->fileinfo.lineno); + char *n = alloca (strlen (cmds->fileinfo.filenm) + 1 + 11 + 1); + sprintf (n, "%s:%lu", cmds->fileinfo.filenm, cmds->fileinfo.lineno); + nm = n; } if (newer[0] == '\0') @@ -168,6 +168,9 @@ unsigned int get_path_max (void); (! INTEGER_TYPE_SIGNED (t) ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)) #define INTEGER_TYPE_MAXIMUM(t) (~ (t) 0 - INTEGER_TYPE_MINIMUM (t)) +/* The maximum number of digits needed to represent the largest integer. */ +#define INTEGER_LENGTH sizeof("18446744073709551616") + #ifndef CHAR_MAX # define CHAR_MAX INTEGER_TYPE_MAXIMUM (char) #endif @@ -379,29 +382,17 @@ extern struct rlimit stack_limit; #define STRING_SIZE_TUPLE(_s) (_s), CSTRLEN(_s) -/* We have to have stdarg.h or varargs.h AND v*printf or doprnt to use - variadic versions of these functions. */ - -#if HAVE_STDARG_H || HAVE_VARARGS_H -# if HAVE_VPRINTF || HAVE_DOPRNT -# define USE_VARIADIC 1 -# endif -#endif - -#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H const char *concat (unsigned int, ...); +const char *message_s (unsigned int length, int prefix, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +const char *error_s (unsigned int length, const gmk_floc *flocp, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); void message (int prefix, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); void error (const gmk_floc *flocp, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); void fatal (const gmk_floc *flocp, const char *fmt, ...) __attribute__ ((noreturn, __format__ (__printf__, 2, 3))); -#else -const char *concat (); -void message (); -void error (); -void fatal (); -#endif void die (int) __attribute__ ((noreturn)); void log_working_directory (int, int); @@ -18,36 +18,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ #include "dep.h" #include "debug.h" -/* Variadic functions. We go through contortions to allow proper function - prototypes for both ANSI and pre-ANSI C compilers, and also for those - which support stdarg.h vs. varargs.h, and finally those which have - vfprintf(), etc. and those who have _doprnt... or nothing. - - This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and - VA_END macros used here since we have multiple print functions. */ - -#if USE_VARIADIC -# if HAVE_STDARG_H -# include <stdarg.h> -# define VA_START(args, lastarg) va_start(args, lastarg) -# else -# include <varargs.h> -# define VA_START(args, lastarg) va_start(args) -# endif -# if HAVE_VPRINTF -# define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args)) -# else -# define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp)) -# endif -# define VA_END(args) va_end(args) -#else -/* We can't use any variadic interface! */ -# define va_alist a1, a2, a3, a4, a5, a6, a7, a8 -# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; -# define VA_START(args, lastarg) -# define VA_PRINTF(fp, lastarg, args) fprintf((fp), (lastarg), va_alist) -# define VA_END(args) -#endif +/* GNU make no longer supports pre-ANSI89 environments. */ + +#include <stdarg.h> /* Compare strings *S1 and *S2. @@ -164,23 +137,14 @@ print_spaces (unsigned int n) This string lives in static, re-used memory. */ const char * -#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H concat (unsigned int num, ...) -#else -concat (num, va_alist) - unsigned int num; - va_dcl -#endif { static unsigned int rlen = 0; static char *result = NULL; unsigned int ri = 0; - -#if USE_VARIADIC va_list args; -#endif - VA_START (args, num); + va_start (args, num); while (num-- > 0) { @@ -200,7 +164,7 @@ concat (num, va_alist) ri += l; } - VA_END (args); + va_end (args); /* Get some more memory if we don't have enough space for the terminating '\0'. */ @@ -215,21 +179,85 @@ concat (num, va_alist) return result; } +/* If we had a standard-compliant vsnprintf() this would be a lot simpler. + Maybe in the future we'll include gnulib's version. */ + +/* Return a formatted string buffer. */ + +const char * +message_s (unsigned int length, int prefix, const char *fmt, ...) +{ + static char *buffer = NULL; + static unsigned int bsize = 0; + char *bp; + va_list args; + + /* Compute the maximum buffer size we'll need, and make sure we have it. */ + length += strlen (fmt) + strlen (program) + 4 + INTEGER_LENGTH + 1; + if (length > bsize) + { + bsize = length * 2; + buffer = xrealloc (buffer, bsize); + } + + bp = buffer; + if (prefix) + { + if (makelevel == 0) + sprintf (bp, "%s: ", program); + else + sprintf (bp, "%s[%u]: ", program, makelevel); + bp += strlen (buffer); + } + + va_start (args, fmt); + vsprintf (bp, fmt, args); + va_end (args); + + return buffer; +} + +/* Return a formatted error message in a buffer. */ + +const char * +error_s (unsigned int length, const gmk_floc *flocp, const char *fmt, ...) +{ + static char *buffer = NULL; + static unsigned int bsize = 0; + char *bp; + va_list args; + + /* Compute the maximum buffer size we'll need, and make sure we have it. */ + length += (strlen (fmt) + strlen (program) + 4 + INTEGER_LENGTH + 1 + + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)); + if (length > bsize) + { + bsize = length * 2; + buffer = xrealloc (buffer, bsize); + } + + bp = buffer; + if (flocp && flocp->filenm) + sprintf (bp, "%s:%lu: ", flocp->filenm, flocp->lineno); + else if (makelevel == 0) + sprintf (bp, "%s: ", program); + else + sprintf (bp, "%s[%u]: ", program, makelevel); + bp += strlen (bp); + + va_start (args, fmt); + vsprintf (bp, fmt, args); + va_end (args); + + return buffer; +} + /* Print a message on stdout. */ void -#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H message (int prefix, const char *fmt, ...) -#else -message (prefix, fmt, va_alist) - int prefix; - const char *fmt; - va_dcl -#endif { -#if USE_VARIADIC va_list args; -#endif log_working_directory (1, 0); @@ -245,9 +273,9 @@ message (prefix, fmt, va_alist) else printf ("%s[%u]: ", program, makelevel); } - VA_START (args, fmt); - VA_PRINTF (stdout, fmt, args); - VA_END (args); + va_start (args, fmt); + vfprintf (stdout, fmt, args); + va_end (args); putchar ('\n'); if (output_sync) @@ -260,18 +288,9 @@ message (prefix, fmt, va_alist) /* Print an error message. */ void -#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H error (const gmk_floc *flocp, const char *fmt, ...) -#else -error (flocp, fmt, va_alist) - const gmk_floc *flocp; - const char *fmt; - va_dcl -#endif { -#if USE_VARIADIC va_list args; -#endif if (output_sync) log_working_directory (1, 1); @@ -285,9 +304,9 @@ error (flocp, fmt, va_alist) else fprintf (stderr, "%s[%u]: ", program, makelevel); - VA_START(args, fmt); - VA_PRINTF (stderr, fmt, args); - VA_END (args); + va_start (args, fmt); + vfprintf (stderr, fmt, args); + va_end (args); putc ('\n', stderr); fflush (stderr); @@ -299,18 +318,9 @@ error (flocp, fmt, va_alist) /* Print an error message and exit. */ void -#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H fatal (const gmk_floc *flocp, const char *fmt, ...) -#else -fatal (flocp, fmt, va_alist) - const gmk_floc *flocp; - const char *fmt; - va_dcl -#endif { -#if USE_VARIADIC va_list args; -#endif if (output_sync) log_working_directory (1, 1); @@ -324,9 +334,9 @@ fatal (flocp, fmt, va_alist) else fprintf (stderr, "%s[%u]: *** ", program, makelevel); - VA_START(args, fmt); - VA_PRINTF (stderr, fmt, args); - VA_END (args); + va_start (args, fmt); + vfprintf (stderr, fmt, args); + va_end (args); fputs (_(". Stop.\n"), stderr); diff --git a/tests/ChangeLog b/tests/ChangeLog index 642ba85..98c5970 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -2,6 +2,7 @@ * scripts/features/output-sync (output_sync_set): Add tests for the per-job syntax mode. + (output_sync_set): Test improved error message location. 2013-04-15 Paul Smith <psmith@gnu.org> diff --git a/tests/scripts/features/output-sync b/tests/scripts/features/output-sync index babc08f..c8ff291 100644 --- a/tests/scripts/features/output-sync +++ b/tests/scripts/features/output-sync @@ -197,14 +197,10 @@ bar: end #MAKE#[1]: Leaving directory '#PWD#/bar' #MAKE#[1]: Leaving directory '#PWD#/bar' #MAKE#[1]: Entering directory '#PWD#/foo' -Makefile:20: recipe for target 'foo-fail' failed -make[1]: Leaving directory '/home/psmith/src/make/make/tests/foo' -make[1]: Entering directory '/home/psmith/src/make/make/tests/foo' -make[1]: *** [foo-fail] Error 1 -make[1]: Leaving directory '/home/psmith/src/make/make/tests/foo' -make[1]: Entering directory '/home/psmith/src/make/make/tests/foo' foo-fail: start foo-fail: end +Makefile:20: recipe for target 'foo-fail' failed +#MAKE#[1]: *** [foo-fail] Error 1 #MAKE#[1]: Leaving directory '#PWD#/foo' #MAKE#[1]: Leaving directory '#PWD#/foo' #MAKEFILE#:4: recipe for target 'make-foo-fail' failed |