mirror of
https://salsa.debian.org/srivasta/make-dfsg.git
synced 2024-12-29 08:09:03 +00:00
Fix for bug #1276: Handle SHELL according to POSIX requirements.
POSIX requires that the value of SHELL in the makefile NOT be exported to sub-commands. Instead, the value in the environment when make was invoked should be passed to the environment of sub-commands. Note that make still uses SHELL to _run_ sub-commands; it just doesn't change the value of the SHELL variable in the environment of sub-commands. As an extension to POSIX, if the makefile explicitly exports SHELL then GNU make _will_ use it in the environment of sub-commands.
This commit is contained in:
parent
d27cac1598
commit
539f513773
8 changed files with 150 additions and 46 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2004-11-28 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
Fix for bug #1276: Handle SHELL according to POSIX requirements.
|
||||
|
||||
* main.c (main): Set SHELL to v_noexport by default. Remember the
|
||||
original environment setting of SHELL in the env_shell variable.
|
||||
* main.h: Export new env_shell variable.
|
||||
* variable.c (target_environment): If we find a v_noexport
|
||||
variable for SHELL, add a SHELL variable with the env_shell value.
|
||||
* doc/make.texi (Quick Reference): Document the POSIX behavior.
|
||||
* doc/make.texi (Variables/Recursion): Ditto.
|
||||
|
||||
2004-11-28 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* main.c (find_and_set_default_shell) [WINDOWS32]: check for
|
||||
|
|
|
@ -3732,9 +3732,15 @@ line, and if its name consists only of letters, numbers, and underscores.
|
|||
Some shells cannot cope with environment variable names consisting of
|
||||
characters other than letters, numbers, and underscores.
|
||||
|
||||
The special variables @code{SHELL} and @code{MAKEFLAGS} are always
|
||||
exported (unless you unexport them).
|
||||
@code{MAKEFILES} is exported if you set it to anything.
|
||||
@cindex SHELL, exported value
|
||||
The value of the @code{make} variable @code{SHELL} is not exported.
|
||||
Instead, the value of the @code{SHELL} variable from the invoking
|
||||
environment is passed to the sub-@code{make}. You can force
|
||||
@code{make} to export its value for @code{SHELL} by using the
|
||||
@code{export} directive, described below.
|
||||
|
||||
The special variable @code{MAKEFLAGS} is always exported (unless you
|
||||
unexport it). @code{MAKEFILES} is exported if you set it to anything.
|
||||
|
||||
@code{make} automatically passes down variable values that were defined
|
||||
on the command line, by putting them in the @code{MAKEFLAGS} variable.
|
||||
|
@ -5137,28 +5143,28 @@ endef
|
|||
@cindex variables, environment
|
||||
@cindex environment
|
||||
Variables in @code{make} can come from the environment in which
|
||||
@code{make} is run. Every environment variable that @code{make} sees when
|
||||
it starts up is transformed into a @code{make} variable with the same name
|
||||
and value. But an explicit assignment in the makefile, or with a command
|
||||
argument, overrides the environment. (If the @samp{-e} flag is specified,
|
||||
then values from the environment override assignments in the makefile.
|
||||
@xref{Options Summary, ,Summary of Options}.
|
||||
But this is not recommended practice.)
|
||||
@code{make} is run. Every environment variable that @code{make} sees
|
||||
when it starts up is transformed into a @code{make} variable with the
|
||||
same name and value. However, an explicit assignment in the makefile,
|
||||
or with a command argument, overrides the environment. (If the
|
||||
@samp{-e} flag is specified, then values from the environment override
|
||||
assignments in the makefile. @xref{Options Summary, ,Summary of
|
||||
Options}. But this is not recommended practice.)
|
||||
|
||||
Thus, by setting the variable @code{CFLAGS} in your environment, you can
|
||||
cause all C compilations in most makefiles to use the compiler switches you
|
||||
prefer. This is safe for variables with standard or conventional meanings
|
||||
because you know that no makefile will use them for other things. (But
|
||||
because you know that no makefile will use them for other things. (Note
|
||||
this is not totally reliable; some makefiles set @code{CFLAGS} explicitly
|
||||
and therefore are not affected by the value in the environment.)
|
||||
|
||||
When @code{make} is invoked recursively, variables defined in the
|
||||
outer invocation can be passed to inner invocations through the
|
||||
environment (@pxref{Recursion, ,Recursive Use of @code{make}}). By
|
||||
default, only variables that came from the environment or the command
|
||||
line are passed to recursive invocations. You can use the
|
||||
@code{export} directive to pass other variables.
|
||||
@xref{Variables/Recursion, , Communicating Variables to a
|
||||
When @code{make} runs a command script, variables defined in the
|
||||
makefile are placed into the environment of that command. This allows
|
||||
you to pass values to sub-@code{make} invocations. (@pxref{Recursion,
|
||||
,Recursive Use of @code{make}}). By default, only variables that came
|
||||
from the environment or the command line are passed to recursive
|
||||
invocations. You can use the @code{export} directive to pass other
|
||||
variables. @xref{Variables/Recursion, , Communicating Variables to a
|
||||
Sub-@code{make}}, for full details.
|
||||
|
||||
Other use of variables from the environment is not recommended. It is not
|
||||
|
@ -5167,6 +5173,7 @@ set up outside their control, since this would cause different users to get
|
|||
different results from the same makefile. This is against the whole
|
||||
purpose of most makefiles.
|
||||
|
||||
@cindex SHELL, import from environment
|
||||
Such problems would be especially likely with the variable @code{SHELL},
|
||||
which is normally present in the environment to specify the user's choice
|
||||
of interactive shell. It would be very undesirable for this choice to
|
||||
|
@ -5175,6 +5182,15 @@ affect @code{make}. So @code{make} ignores the environment value of
|
|||
usually not set. @xref{Execution, ,Special handling of SHELL on
|
||||
MS-DOS}.)@refill
|
||||
|
||||
@cindex SHELL, export to environment
|
||||
The @code{SHELL} variable is special in another way: just as the value
|
||||
of the @code{make} variable @code{SHELL} is not taken from the
|
||||
environment, so also it is not placed into the environment of commands
|
||||
that @code{make} invokes. Instead, the value of @code{SHELL} from the
|
||||
invoking environment is provided to the command. You can use
|
||||
@code{export SHELL} to force the value of the @code{make} variable
|
||||
@code{SHELL} to be placed in the environment of commands.
|
||||
|
||||
@node Target-specific, Pattern-specific, Environment, Using Variables
|
||||
@section Target-specific Variable Values
|
||||
@cindex target-specific variables
|
||||
|
@ -9865,7 +9881,9 @@ Directory search path for files not found in the current directory.@*
|
|||
|
||||
The name of the system default command interpreter, usually @file{/bin/sh}.
|
||||
You can set @code{SHELL} in the makefile to change the shell used to run
|
||||
commands. @xref{Execution, ,Command Execution}.
|
||||
commands. @xref{Execution, ,Command Execution}. The @code{SHELL}
|
||||
variable is handled specially when importing from and exporting to the
|
||||
environment. @xref{Environment, ,Using Variable from the Environment}.
|
||||
|
||||
@item MAKESHELL
|
||||
|
||||
|
|
43
main.c
43
main.c
|
@ -264,6 +264,10 @@ int always_make_flag = 0;
|
|||
|
||||
int rebuilding_makefiles = 0;
|
||||
|
||||
/* Remember the original value of the SHELL variable, from the environment. */
|
||||
|
||||
const char *env_shell = 0;
|
||||
|
||||
|
||||
/* The usage output. We write it this way to make life easier for the
|
||||
translators, especially those trying to translate to right-to-left
|
||||
|
@ -1045,11 +1049,8 @@ main (int argc, char **argv, char **envp)
|
|||
#ifndef _AMIGA
|
||||
for (i = 0; envp[i] != 0; ++i)
|
||||
{
|
||||
int do_not_define;
|
||||
register char *ep = envp[i];
|
||||
|
||||
/* by default, everything gets defined and exported */
|
||||
do_not_define = 0;
|
||||
int do_not_define = 0;
|
||||
char *ep = envp[i];
|
||||
|
||||
while (*ep != '=')
|
||||
++ep;
|
||||
|
@ -1065,17 +1066,27 @@ main (int argc, char **argv, char **envp)
|
|||
machines where ptrdiff_t is a different size that doesn't widen
|
||||
the same. */
|
||||
if (!do_not_define)
|
||||
define_variable (envp[i], (unsigned int) (ep - envp[i]),
|
||||
ep + 1, o_env, 1)
|
||||
/* Force exportation of every variable culled from the environment.
|
||||
We used to rely on target_environment's v_default code to do this.
|
||||
But that does not work for the case where an environment variable
|
||||
is redefined in a makefile with `override'; it should then still
|
||||
be exported, because it was originally in the environment.
|
||||
Another wrinkle is that POSIX says the value of SHELL set in the
|
||||
makefile should not change the value of SHELL given to
|
||||
subprocesses, which seems silly to me but... */
|
||||
->export = strncmp(envp[i], "SHELL=", 6) ? v_noexport : v_export;
|
||||
{
|
||||
struct variable *v;
|
||||
|
||||
v = define_variable (envp[i], (unsigned int) (ep - envp[i]),
|
||||
ep + 1, o_env, 1);
|
||||
/* Force exportation of every variable culled from the environment.
|
||||
We used to rely on target_environment's v_default code to do this.
|
||||
But that does not work for the case where an environment variable
|
||||
is redefined in a makefile with `override'; it should then still
|
||||
be exported, because it was originally in the environment. */
|
||||
v->export = v_export;
|
||||
|
||||
/* Another wrinkle is that POSIX says the value of SHELL set in the
|
||||
makefile should not change the value of SHELL given to
|
||||
subprocesses, which seems silly to me but... */
|
||||
if (strncmp (envp[i], "SHELL=", 6) == 0)
|
||||
{
|
||||
v->export = v_noexport;
|
||||
env_shell = xstrdup (ep + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef WINDOWS32
|
||||
/*
|
||||
|
|
2
make.h
2
make.h
|
@ -496,6 +496,8 @@ extern int print_version_flag, print_directory_flag;
|
|||
extern int warn_undefined_variables_flag, posix_pedantic, not_parallel;
|
||||
extern int clock_skew_detected, rebuilding_makefiles;
|
||||
|
||||
extern const char *env_shell;
|
||||
|
||||
/* can we run commands via 'sh -c xxx' or must we use batch files? */
|
||||
extern int batch_mode_shell;
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2004-11-28 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/variables/SHELL: New file: test proper handling of SHELL
|
||||
according to POSIX rules. Fixes bug #1276.
|
||||
|
||||
2004-10-21 Boris Kolpackov <boris@kolpackov.net>
|
||||
|
||||
* scripts/functions/word: Test $(firstword ) and $(lastword ).
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# -*-perl-mode-*-
|
||||
# -*-perl-*-
|
||||
|
||||
$description = "The following test creates a makefile to test
|
||||
makelevels in Make. It prints \$(MAKELEVEL) and then
|
||||
|
@ -9,7 +9,6 @@ open(MAKEFILE,"> $makefile");
|
|||
# The Contents of the MAKEFILE ...
|
||||
|
||||
print MAKEFILE <<EOF;
|
||||
SHELL = /bin/sh
|
||||
all:
|
||||
\t\@echo MAKELEVEL is \$(MAKELEVEL)
|
||||
\techo \$\$MAKELEVEL
|
||||
|
|
49
tests/scripts/variables/SHELL
Normal file
49
tests/scripts/variables/SHELL
Normal file
|
@ -0,0 +1,49 @@
|
|||
# -*-perl-*-
|
||||
|
||||
$description = "Test proper handling of SHELL.";
|
||||
|
||||
# Find the default value when SHELL is not set. On UNIX it will be /bin/sh,
|
||||
# but on other platforms who knows?
|
||||
$oshell = $ENV{SHELL};
|
||||
delete $ENV{SHELL};
|
||||
$mshell = `echo 'all:;\@echo \$(SHELL)' | $make_name -f-`;
|
||||
chop $mshell;
|
||||
|
||||
# According to POSIX, the value of SHELL in the environment has no impact on
|
||||
# the value in the makefile.
|
||||
|
||||
$ENV{SHELL} = '/dev/null';
|
||||
run_make_test('all:;@echo "$(SHELL)"', '', $mshell);
|
||||
|
||||
# According to POSIX, any value of SHELL set in the makefile should _NOT_ be
|
||||
# exported to the subshell! I wanted to set SHELL to be $^X (perl) in the
|
||||
# makefile, but make runs $(SHELL) -c 'commandline' and that doesn't work at
|
||||
# all when $(SHELL) is perl :-/. So, we just add an extra initial / and hope
|
||||
# for the best on non-UNIX platforms :-/.
|
||||
|
||||
$ENV{SHELL} = $mshell;
|
||||
|
||||
run_make_test("SHELL := /$mshell\n".'
|
||||
all:;@echo "$(SHELL) $$SHELL"
|
||||
', '', "/$mshell $mshell");
|
||||
|
||||
# As a GNU make extension, if make's SHELL variable is explicitly exported,
|
||||
# then we really _DO_ export it.
|
||||
|
||||
run_make_test("export SHELL := /$mshell\n".'
|
||||
all:;@echo "$(SHELL) $$SHELL"
|
||||
', '', "/$mshell /$mshell");
|
||||
|
||||
|
||||
# Test out setting of SHELL, both exported and not, as a target-specific
|
||||
# variable.
|
||||
|
||||
run_make_test("all: SHELL := /$mshell\n".'
|
||||
all:;@echo "$(SHELL) $$SHELL"
|
||||
', '', "/$mshell $mshell");
|
||||
|
||||
run_make_test("all: export SHELL := /$mshell\n".'
|
||||
all:;@echo "$(SHELL) $$SHELL"
|
||||
', '', "/$mshell $mshell");
|
||||
|
||||
1;
|
26
variable.c
26
variable.c
|
@ -739,16 +739,14 @@ define_automatic_variables (void)
|
|||
|
||||
#endif
|
||||
|
||||
/* This won't override any definition, but it
|
||||
will provide one if there isn't one there. */
|
||||
/* This won't override any definition, but it will provide one if there
|
||||
isn't one there. */
|
||||
v = define_variable ("SHELL", 5, default_shell, o_default, 0);
|
||||
v->export = v_export; /* Always export SHELL. */
|
||||
|
||||
/* On MSDOS we do use SHELL from environment, since
|
||||
it isn't a standard environment variable on MSDOS,
|
||||
so whoever sets it, does that on purpose.
|
||||
On OS/2 we do not use SHELL from environment but
|
||||
we have already handled that problem above. */
|
||||
/* On MSDOS we do use SHELL from environment, since it isn't a standard
|
||||
environment variable on MSDOS, so whoever sets it, does that on purpose.
|
||||
On OS/2 we do not use SHELL from environment but we have already handled
|
||||
that problem above. */
|
||||
#if !defined(__MSDOS__) && !defined(__EMX__)
|
||||
/* Don't let SHELL come from the environment. */
|
||||
if (*v->value == '\0' || v->origin == o_env || v->origin == o_env_override)
|
||||
|
@ -809,6 +807,11 @@ target_environment (struct file *file)
|
|||
struct variable makelevel_key;
|
||||
char **result_0;
|
||||
char **result;
|
||||
struct variable ev;
|
||||
|
||||
/* Set up a fake variable struct for the original SHELL value. */
|
||||
ev.name = "SHELL";
|
||||
ev.value = env_shell;
|
||||
|
||||
if (file == 0)
|
||||
set_list = current_variable_set_list;
|
||||
|
@ -865,7 +868,12 @@ target_environment (struct file *file)
|
|||
break;
|
||||
|
||||
case v_noexport:
|
||||
continue;
|
||||
if (!streq (v->name, "SHELL"))
|
||||
continue;
|
||||
/* If this is the SHELL variable and it's not exported, then
|
||||
add the value from our original environment. */
|
||||
v = &ev;
|
||||
break;
|
||||
|
||||
case v_ifset:
|
||||
if (v->origin == o_default)
|
||||
|
|
Loading…
Reference in a new issue