Subject: make: add ksh spec and have compat mode use default shell
To: None <tech-toolchain@netbsd.org>
From: Simon J. Gerraty <sjg@crufty.net>
List: tech-toolchain
Date: 07/30/2003 22:49:47
The patch below adds a spec for ksh so that it can be selected as the
default shell with just:
.SHELL: name=ksh
That's simple enough... possibly more contentious is having compat
mode use the default shell spec (typically Bourne shell).
This allows one to use .SHELL: to control the shell that will be used
by compat mode.
The goal is to allow folk trying to build pkgsrc on non-BSD platforms
to overcome some of the modern features used in our makefiles that are
not supported by the native /bin/sh.
Obviously this patch is mostly of value to bmake - but since its
totally generic I figured changing make is the go.
Thoughts?
--sjg
Index: compat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/compat.c,v
retrieving revision 1.45
diff -u -p -r1.45 compat.c
--- compat.c 2003/07/14 18:19:11 1.45
+++ compat.c 2003/07/31 05:48:17
@@ -259,8 +259,12 @@ CompatRunCommand(ClientData cmdp, Client
* -e flag as well as -c if it's supposed to exit when it hits an
* error.
*/
- static const char *shargv[4] = { _PATH_BSHELL };
+ static const char *shargv[4];
+ shargv[0] = shellPath;
+ /*
+ * The following work for any of the builtin shell specs.
+ */
if (DEBUG(SHELL))
shargv[1] = (errCheck ? "-exc" : "-xc");
else
@@ -549,6 +553,8 @@ Compat_Run(Lst targs)
const char *cp; /* Pointer to string of shell meta-characters */
GNode *gn = NULL;/* Current root target */
int errors; /* Number of targets not remade due to errors */
+
+ Shell_Init(); /* setup default shell */
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
signal(SIGINT, CompatInterrupt);
Index: config.h
===================================================================
RCS file: /cvsroot/src/usr.bin/make/config.h,v
retrieving revision 1.14
diff -u -p -r1.14 config.h
--- config.h 2002/01/16 03:40:29 1.14
+++ config.h 2003/07/31 05:48:17
@@ -40,7 +40,9 @@
* from: @(#)config.h 8.1 (Berkeley) 6/6/93
*/
+#ifndef DEFSHELL
#define DEFSHELL 1 /* Bourne shell */
+#endif
/*
* DEFMAXJOBS
Index: job.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/job.c,v
retrieving revision 1.80
diff -u -p -r1.80 job.c
--- job.c 2003/07/16 07:16:24 1.80
+++ job.c 2003/07/31 05:48:20
@@ -209,6 +209,16 @@ static Shell shells[] = {
"e",
},
/*
+ * KSH description.
+ */
+{
+ "ksh",
+ TRUE, "set +v", "set -v", "set +v", 6,
+ TRUE, "set -e", "set +e",
+ "v",
+ "e",
+},
+ /*
* UNKNOWN.
*/
{
@@ -223,10 +233,10 @@ static Shell *commandShell = &shells[DE
* commands in the Makefile.
* It is set by the
* Job_ParseShell function */
-static const char *shellPath = NULL, /* full pathname of
+const char *shellPath = NULL, /* full pathname of
* executable image */
- *shellName = NULL, /* last component of shell */
- *shellArgv = NULL; /* Custom shell args */
+ *shellName = NULL; /* last component of shell */
+static const char *shellArgv = NULL; /* Custom shell args */
static int maxJobs; /* The most children we can run at once */
@@ -2531,6 +2541,28 @@ Job_Make(GNode *gn)
(void) JobStart(gn, 0, NULL);
}
+void
+Shell_Init()
+{
+ if (shellPath == NULL) {
+ /*
+ * The user didn't specify a shell to use, so we are using the
+ * default one... Both the absolute path and the last component
+ * must be set. The last component is taken from the 'name' field
+ * of the default shell description pointed-to by commandShell.
+ * All default shells are located in _PATH_DEFSHELLDIR.
+ */
+ shellName = commandShell->name;
+ shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
+ }
+ if (commandShell->exit == NULL) {
+ commandShell->exit = "";
+ }
+ if (commandShell->echo == NULL) {
+ commandShell->echo = "";
+ }
+}
+
/*-
*-----------------------------------------------------------------------
* Job_Init --
@@ -2581,24 +2613,7 @@ Job_Init(int maxproc, int maxlocal)
targFmt = TARG_FMT;
}
- if (shellPath == NULL) {
- /*
- * The user didn't specify a shell to use, so we are using the
- * default one... Both the absolute path and the last component
- * must be set. The last component is taken from the 'name' field
- * of the default shell description pointed-to by commandShell.
- * All default shells are located in _PATH_DEFSHELLDIR.
- */
- shellName = commandShell->name;
- shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
- }
-
- if (commandShell->exit == NULL) {
- commandShell->exit = "";
- }
- if (commandShell->echo == NULL) {
- commandShell->echo = "";
- }
+ Shell_Init();
if (pipe(exit_pipe) < 0)
Fatal("error in pipe: %s", strerror(errno));
Index: job.h
===================================================================
RCS file: /cvsroot/src/usr.bin/make/job.h,v
retrieving revision 1.18
diff -u -p -r1.18 job.h
--- job.h 2003/07/14 18:19:12 1.18
+++ job.h 2003/07/31 05:48:20
@@ -231,6 +231,9 @@ typedef struct Shell {
const char *exit; /* exit on error */
} Shell;
+extern const char *shellPath;
+extern const char *shellName;
+
extern int job_pipe[2]; /* token pipe for jobs. */
extern int jobTokensRunning; /* tokens currently "out" */
extern int jobTokensFree; /* tokens free but not yet released to pipe */
@@ -251,6 +254,7 @@ extern Lst stoppedJobs; /* List of job
* quite get started */
#endif
+void Shell_Init(void);
void Job_Touch(GNode *, Boolean);
Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...));
void Job_CatchChildren(Boolean);
Index: main.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/main.c,v
retrieving revision 1.89
diff -u -p -r1.89 main.c
--- main.c 2003/07/14 18:19:12 1.89
+++ main.c 2003/07/31 05:48:22
@@ -1224,10 +1224,12 @@ Cmd_Exec(const char *cmd, const char **e
*err = NULL;
+ if (!shellName)
+ Shell_Init();
/*
* Set up arguments for shell
*/
- args[0] = "sh";
+ args[0] = shellName;
args[1] = "-c";
args[2] = cmd;
args[3] = NULL;
@@ -1258,7 +1260,7 @@ Cmd_Exec(const char *cmd, const char **e
(void) dup2(fds[1], 1);
(void) close(fds[1]);
- (void) execv(_PATH_BSHELL, UNCONST(args));
+ (void) execv(shellPath, UNCONST(args));
_exit(1);
/*NOTREACHED*/