Fri Jan 29 22:52:29 2021 UTC ()
make(1): do not create empty shell files in jobs mode

In a chain of dependencies such as "all: build; build: do-build", the
intermediate targets do not have any commands.  In jobs mode,
nevertheless, an empty file was created and fed to the shell.  This was
unnecessary.  See jobs-empty-commands.mk.

The case of the special command line "...", which was suggested on
current-users, is not optimized since it doesn't occur in practice.

Suggested by Mateusz Guzik on current-users:
https://mail-index.netbsd.org/current-users/2021/01/26/msg040215.html


(rillig)
diff -r1.398 -r1.399 src/usr.bin/make/job.c

cvs diff -r1.398 -r1.399 src/usr.bin/make/job.c (expand / switch to unified diff)

--- src/usr.bin/make/job.c 2021/01/19 20:51:46 1.398
+++ src/usr.bin/make/job.c 2021/01/29 22:52:29 1.399
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: job.c,v 1.398 2021/01/19 20:51:46 rillig Exp $ */ 1/* $NetBSD: job.c,v 1.399 2021/01/29 22:52:29 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -133,27 +133,27 @@ @@ -133,27 +133,27 @@
133#ifndef USE_SELECT 133#ifndef USE_SELECT
134#include <poll.h> 134#include <poll.h>
135#endif 135#endif
136#include <signal.h> 136#include <signal.h>
137#include <utime.h> 137#include <utime.h>
138 138
139#include "make.h" 139#include "make.h"
140#include "dir.h" 140#include "dir.h"
141#include "job.h" 141#include "job.h"
142#include "pathnames.h" 142#include "pathnames.h"
143#include "trace.h" 143#include "trace.h"
144 144
145/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ 145/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */
146MAKE_RCSID("$NetBSD: job.c,v 1.398 2021/01/19 20:51:46 rillig Exp $"); 146MAKE_RCSID("$NetBSD: job.c,v 1.399 2021/01/29 22:52:29 rillig Exp $");
147 147
148/* 148/*
149 * A shell defines how the commands are run. All commands for a target are 149 * A shell defines how the commands are run. All commands for a target are
150 * written into a single file, which is then given to the shell to execute 150 * written into a single file, which is then given to the shell to execute
151 * the commands from it. The commands are written to the file using a few 151 * the commands from it. The commands are written to the file using a few
152 * templates for echo control and error control. 152 * templates for echo control and error control.
153 * 153 *
154 * The name of the shell is the basename for the predefined shells, such as 154 * The name of the shell is the basename for the predefined shells, such as
155 * "sh", "csh", "bash". For custom shells, it is the full pathname, and its 155 * "sh", "csh", "bash". For custom shells, it is the full pathname, and its
156 * basename is used to select the type of shell; the longest match wins. 156 * basename is used to select the type of shell; the longest match wins.
157 * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. 157 * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh.
158 * 158 *
159 * The echoing of command lines is controlled using hasEchoCtl, echoOff, 159 * The echoing of command lines is controlled using hasEchoCtl, echoOff,
@@ -1656,28 +1656,33 @@ JobStart(GNode *gn, Boolean special) @@ -1656,28 +1656,33 @@ JobStart(GNode *gn, Boolean special)
1656 /* 1656 /*
1657 * Check the commands now so any attributes from .DEFAULT have a 1657 * Check the commands now so any attributes from .DEFAULT have a
1658 * chance to migrate to the node. 1658 * chance to migrate to the node.
1659 */ 1659 */
1660 cmdsOK = Job_CheckCommands(gn, Error); 1660 cmdsOK = Job_CheckCommands(gn, Error);
1661 1661
1662 job->inPollfd = NULL; 1662 job->inPollfd = NULL;
1663 /* 1663 /*
1664 * If the -n flag wasn't given, we open up OUR (not the child's) 1664 * If the -n flag wasn't given, we open up OUR (not the child's)
1665 * temporary file to stuff commands in it. The thing is rd/wr so 1665 * temporary file to stuff commands in it. The thing is rd/wr so
1666 * we don't need to reopen it to feed it to the shell. If the -n 1666 * we don't need to reopen it to feed it to the shell. If the -n
1667 * flag *was* given, we just set the file to be stdout. Cute, huh? 1667 * flag *was* given, we just set the file to be stdout. Cute, huh?
1668 */ 1668 */
1669 if (((gn->type & OP_MAKE) && !opts.noRecursiveExecute) || 1669 if (Lst_IsEmpty(&gn->commands)) {
 1670 /* XXX: No need to flush stdout here */
 1671 job->cmdFILE = stdout;
 1672 run = FALSE;
 1673 } else if (((gn->type & OP_MAKE) && !opts.noRecursiveExecute) ||
1670 (!opts.noExecute && !opts.touchFlag)) { 1674 (!opts.noExecute && !opts.touchFlag)) {
 1675 /* XXX: The above conditions are needlessly repeated */
1671 JobOpenTmpFile(job, gn, cmdsOK, &run); 1676 JobOpenTmpFile(job, gn, cmdsOK, &run);
1672 } else if (!GNode_ShouldExecute(gn)) { 1677 } else if (!GNode_ShouldExecute(gn)) {
1673 /* 1678 /*
1674 * Not executing anything -- just print all the commands to 1679 * Not executing anything -- just print all the commands to
1675 * stdout in one fell swoop. This will still set up 1680 * stdout in one fell swoop. This will still set up
1676 * job->tailCmds correctly. 1681 * job->tailCmds correctly.
1677 */ 1682 */
1678 SwitchOutputTo(gn); 1683 SwitchOutputTo(gn);
1679 job->cmdFILE = stdout; 1684 job->cmdFILE = stdout;
1680 /* 1685 /*
1681 * Only print the commands if they're ok, but don't die if 1686 * Only print the commands if they're ok, but don't die if
1682 * they're not -- just let the user know they're bad and 1687 * they're not -- just let the user know they're bad and
1683 * keep going. It doesn't do any harm in this case and may 1688 * keep going. It doesn't do any harm in this case and may