mirror of
https://github.com/mirror/make.git
synced 2025-03-27 20:40:35 +08: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
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>
|
2004-11-28 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
* main.c (find_and_set_default_shell) [WINDOWS32]: check for
|
* 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
|
Some shells cannot cope with environment variable names consisting of
|
||||||
characters other than letters, numbers, and underscores.
|
characters other than letters, numbers, and underscores.
|
||||||
|
|
||||||
The special variables @code{SHELL} and @code{MAKEFLAGS} are always
|
@cindex SHELL, exported value
|
||||||
exported (unless you unexport them).
|
The value of the @code{make} variable @code{SHELL} is not exported.
|
||||||
@code{MAKEFILES} is exported if you set it to anything.
|
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
|
@code{make} automatically passes down variable values that were defined
|
||||||
on the command line, by putting them in the @code{MAKEFLAGS} variable.
|
on the command line, by putting them in the @code{MAKEFLAGS} variable.
|
||||||
@ -5137,28 +5143,28 @@ endef
|
|||||||
@cindex variables, environment
|
@cindex variables, environment
|
||||||
@cindex environment
|
@cindex environment
|
||||||
Variables in @code{make} can come from the environment in which
|
Variables in @code{make} can come from the environment in which
|
||||||
@code{make} is run. Every environment variable that @code{make} sees when
|
@code{make} is run. Every environment variable that @code{make} sees
|
||||||
it starts up is transformed into a @code{make} variable with the same name
|
when it starts up is transformed into a @code{make} variable with the
|
||||||
and value. But an explicit assignment in the makefile, or with a command
|
same name and value. However, an explicit assignment in the makefile,
|
||||||
argument, overrides the environment. (If the @samp{-e} flag is specified,
|
or with a command argument, overrides the environment. (If the
|
||||||
then values from the environment override assignments in the makefile.
|
@samp{-e} flag is specified, then values from the environment override
|
||||||
@xref{Options Summary, ,Summary of Options}.
|
assignments in the makefile. @xref{Options Summary, ,Summary of
|
||||||
But this is not recommended practice.)
|
Options}. But this is not recommended practice.)
|
||||||
|
|
||||||
Thus, by setting the variable @code{CFLAGS} in your environment, you can
|
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
|
cause all C compilations in most makefiles to use the compiler switches you
|
||||||
prefer. This is safe for variables with standard or conventional meanings
|
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
|
this is not totally reliable; some makefiles set @code{CFLAGS} explicitly
|
||||||
and therefore are not affected by the value in the environment.)
|
and therefore are not affected by the value in the environment.)
|
||||||
|
|
||||||
When @code{make} is invoked recursively, variables defined in the
|
When @code{make} runs a command script, variables defined in the
|
||||||
outer invocation can be passed to inner invocations through the
|
makefile are placed into the environment of that command. This allows
|
||||||
environment (@pxref{Recursion, ,Recursive Use of @code{make}}). By
|
you to pass values to sub-@code{make} invocations. (@pxref{Recursion,
|
||||||
default, only variables that came from the environment or the command
|
,Recursive Use of @code{make}}). By default, only variables that came
|
||||||
line are passed to recursive invocations. You can use the
|
from the environment or the command line are passed to recursive
|
||||||
@code{export} directive to pass other variables.
|
invocations. You can use the @code{export} directive to pass other
|
||||||
@xref{Variables/Recursion, , Communicating Variables to a
|
variables. @xref{Variables/Recursion, , Communicating Variables to a
|
||||||
Sub-@code{make}}, for full details.
|
Sub-@code{make}}, for full details.
|
||||||
|
|
||||||
Other use of variables from the environment is not recommended. It is not
|
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
|
different results from the same makefile. This is against the whole
|
||||||
purpose of most makefiles.
|
purpose of most makefiles.
|
||||||
|
|
||||||
|
@cindex SHELL, import from environment
|
||||||
Such problems would be especially likely with the variable @code{SHELL},
|
Such problems would be especially likely with the variable @code{SHELL},
|
||||||
which is normally present in the environment to specify the user's choice
|
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
|
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
|
usually not set. @xref{Execution, ,Special handling of SHELL on
|
||||||
MS-DOS}.)@refill
|
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
|
@node Target-specific, Pattern-specific, Environment, Using Variables
|
||||||
@section Target-specific Variable Values
|
@section Target-specific Variable Values
|
||||||
@cindex target-specific variables
|
@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}.
|
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
|
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
|
@item MAKESHELL
|
||||||
|
|
||||||
|
43
main.c
43
main.c
@ -264,6 +264,10 @@ int always_make_flag = 0;
|
|||||||
|
|
||||||
int rebuilding_makefiles = 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
|
/* The usage output. We write it this way to make life easier for the
|
||||||
translators, especially those trying to translate to right-to-left
|
translators, especially those trying to translate to right-to-left
|
||||||
@ -1045,11 +1049,8 @@ main (int argc, char **argv, char **envp)
|
|||||||
#ifndef _AMIGA
|
#ifndef _AMIGA
|
||||||
for (i = 0; envp[i] != 0; ++i)
|
for (i = 0; envp[i] != 0; ++i)
|
||||||
{
|
{
|
||||||
int do_not_define;
|
int do_not_define = 0;
|
||||||
register char *ep = envp[i];
|
char *ep = envp[i];
|
||||||
|
|
||||||
/* by default, everything gets defined and exported */
|
|
||||||
do_not_define = 0;
|
|
||||||
|
|
||||||
while (*ep != '=')
|
while (*ep != '=')
|
||||||
++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
|
machines where ptrdiff_t is a different size that doesn't widen
|
||||||
the same. */
|
the same. */
|
||||||
if (!do_not_define)
|
if (!do_not_define)
|
||||||
define_variable (envp[i], (unsigned int) (ep - envp[i]),
|
{
|
||||||
ep + 1, o_env, 1)
|
struct variable *v;
|
||||||
/* Force exportation of every variable culled from the environment.
|
|
||||||
We used to rely on target_environment's v_default code to do this.
|
v = define_variable (envp[i], (unsigned int) (ep - envp[i]),
|
||||||
But that does not work for the case where an environment variable
|
ep + 1, o_env, 1);
|
||||||
is redefined in a makefile with `override'; it should then still
|
/* Force exportation of every variable culled from the environment.
|
||||||
be exported, because it was originally in the environment.
|
We used to rely on target_environment's v_default code to do this.
|
||||||
Another wrinkle is that POSIX says the value of SHELL set in the
|
But that does not work for the case where an environment variable
|
||||||
makefile should not change the value of SHELL given to
|
is redefined in a makefile with `override'; it should then still
|
||||||
subprocesses, which seems silly to me but... */
|
be exported, because it was originally in the environment. */
|
||||||
->export = strncmp(envp[i], "SHELL=", 6) ? v_noexport : v_export;
|
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
|
#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 warn_undefined_variables_flag, posix_pedantic, not_parallel;
|
||||||
extern int clock_skew_detected, rebuilding_makefiles;
|
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? */
|
/* can we run commands via 'sh -c xxx' or must we use batch files? */
|
||||||
extern int batch_mode_shell;
|
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>
|
2004-10-21 Boris Kolpackov <boris@kolpackov.net>
|
||||||
|
|
||||||
* scripts/functions/word: Test $(firstword ) and $(lastword ).
|
* scripts/functions/word: Test $(firstword ) and $(lastword ).
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# -*-perl-mode-*-
|
# -*-perl-*-
|
||||||
|
|
||||||
$description = "The following test creates a makefile to test
|
$description = "The following test creates a makefile to test
|
||||||
makelevels in Make. It prints \$(MAKELEVEL) and then
|
makelevels in Make. It prints \$(MAKELEVEL) and then
|
||||||
@ -9,7 +9,6 @@ open(MAKEFILE,"> $makefile");
|
|||||||
# The Contents of the MAKEFILE ...
|
# The Contents of the MAKEFILE ...
|
||||||
|
|
||||||
print MAKEFILE <<EOF;
|
print MAKEFILE <<EOF;
|
||||||
SHELL = /bin/sh
|
|
||||||
all:
|
all:
|
||||||
\t\@echo MAKELEVEL is \$(MAKELEVEL)
|
\t\@echo MAKELEVEL is \$(MAKELEVEL)
|
||||||
\techo \$\$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
|
#endif
|
||||||
|
|
||||||
/* This won't override any definition, but it
|
/* This won't override any definition, but it will provide one if there
|
||||||
will provide one if there isn't one there. */
|
isn't one there. */
|
||||||
v = define_variable ("SHELL", 5, default_shell, o_default, 0);
|
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
|
/* On MSDOS we do use SHELL from environment, since it isn't a standard
|
||||||
it isn't a standard environment variable on MSDOS,
|
environment variable on MSDOS, so whoever sets it, does that on purpose.
|
||||||
so whoever sets it, does that on purpose.
|
On OS/2 we do not use SHELL from environment but we have already handled
|
||||||
On OS/2 we do not use SHELL from environment but
|
that problem above. */
|
||||||
we have already handled that problem above. */
|
|
||||||
#if !defined(__MSDOS__) && !defined(__EMX__)
|
#if !defined(__MSDOS__) && !defined(__EMX__)
|
||||||
/* Don't let SHELL come from the environment. */
|
/* Don't let SHELL come from the environment. */
|
||||||
if (*v->value == '\0' || v->origin == o_env || v->origin == o_env_override)
|
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;
|
struct variable makelevel_key;
|
||||||
char **result_0;
|
char **result_0;
|
||||||
char **result;
|
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)
|
if (file == 0)
|
||||||
set_list = current_variable_set_list;
|
set_list = current_variable_set_list;
|
||||||
@ -865,7 +868,12 @@ target_environment (struct file *file)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case v_noexport:
|
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:
|
case v_ifset:
|
||||||
if (v->origin == o_default)
|
if (v->origin == o_default)
|
||||||
|
Loading…
Reference in New Issue
Block a user