[PATCH] make: Also print -de error information when running multiple jobs
Alexander Richardson <[email protected]>
| Newsgroups | gmane.os.netbsd.devel.toolchain |
|---|---|
| Message-ID | <CA+Z_v8qjVve7GDOWJLFB86NmFQdqFB19hmZC8_HdzU49_BOPcQ@mail.gmail.com> |
Hello all,
I recently submitted a minor make(1) change request to FreeBSD and
would like to suggest this upstream.
I've attached the patch rebased on the latest revision from
https://github.com/NetBSD/src.
Please let me know what you think.
Problem and patch description from https://reviews.freebsd.org/D29647:
When running `make -de` (without any -j flag) bmake prints which command
failed. However, when using the -j flag the -de flag is ignored. This can
make it rather difficult to determine which command failed in an very
parallel build (especially when combined with the -s flag to avoid
ridiculously large logfiles). For single-threaded builds we can combine
-s with -de to get the failed command but this does not work with -jN
(even with -j1). This patch prints the failed shell script with -de in the
multiple jobs mode as well.
If we look at the following example makefile:
```
all:
echo "Running all"
if [ a = b ]; then \
echo "a = b"; \
else \
echo "a != b"; \
fi; false
```
Running `make -de` gives me the following output
```
Running all
a != b
*** Failed target: all
*** Failed command: if [ a = b ]; then echo "a = b"; else echo "a !=
b"; fi; false
*** Error code 1
```
Running `make -de -j1` before:
```
Running all
a != b
*** [all] Error code 1
```
Running `make -de -j1`
```
Running all
a != b
*** Failed target: all
*** Failed commands:
echo "Running all"
if [ a = b ]; then echo "a = b"; else echo "a != b"; fi; false
*** [all] Error code 1
```
Since we pass the entire list of command for the target to the shell we
can't determine which of the multiple commands failed, but in most cases
this will be a single compiler command so printing the entire list should
be sufficient to debug the problem and allows me to use -s together with
-jN
make-de-with-j.patch
(application/octet-stream, 1.5 KB)
diff --git a/usr.bin/make/compat.c b/usr.bin/make/compat.c
index a86ad4f3969..a13f407dbf4 100644
--- a/usr.bin/make/compat.c
+++ b/usr.bin/make/compat.c
@@ -414,6 +414,8 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
}
} else {
status = WTERMSIG(reason); /* signaled */
+ if (DEBUG(ERROR))
+ DebugFailedTarget(cmd, gn);
printf("*** Signal %d", status);
}
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index 91edd4e2f81..129a8da7b93 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -1060,6 +1060,21 @@ JobClosePipes(Job *job)
job->inPipe = -1;
}
+static void
+DebugFailedJob(Job *job)
+{
+ const ListNode *l;
+
+ if (!DEBUG(ERROR))
+ return;
+
+ debug_printf("\n*** Failed target: %s\n*** Failed commands:\n",
+ job->node->name);
+ for (l = job->node->commands.first; l != NULL; l = l->next) {
+ debug_printf("\t%s\n", (const char *)l->datum);
+ }
+}
+
static void
JobFinishDoneExitedError(Job *job, int *inout_status)
{
@@ -1071,6 +1086,7 @@ JobFinishDoneExitedError(Job *job, int *inout_status)
}
#endif
if (!shouldDieQuietly(job->node, -1)) {
+ DebugFailedJob(job);
(void)printf("*** [%s] Error code %d%s\n",
job->node->name, WEXITSTATUS(*inout_status),
job->ignerr ? " (ignored)" : "");
@@ -1103,6 +1119,7 @@ static void
JobFinishDoneSignaled(Job *job, int status)
{
SwitchOutputTo(job->node);
+ DebugFailedJob(job);
(void)printf("*** [%s] Signal %d\n", job->node->name, WTERMSIG(status));
if (deleteOnError)
JobDeleteTarget(job->node);