make/tests/scripts/variables/MAKEFLAGS
Paul Smith 16e14b4114 Disable the jobserver in non-recursive children
Savannah issues such as SV 57242 and SV 62397 show how passing
references to closed file descriptors via the --jobserver-auth option
in MAKEFLAGS can lead to problematic outcomes.

When computing the child environment for a non-recursive shell, add
an extra option to MAKEFLAGS to disable the file descriptors for the
jobserver.

Unfortunately this doesn't modify the value of the make variable
MAKEFLAGS, it only modifies the value of the sub-shell environment
variable MAKEFLAGS.  This can lead to confusion if the user is not
considering the distinction.

* src/makeint.h: Publish the jobserver-auth value.  Add a global
definition of the name of the command line option.
* src/os.h (jobserver_get_invalid_auth): New function to return a
string invalidating the jobserver-auth option.
* src/w32/w32os.c (jobserver_get_invaid_auth): Implement it.  On
Windows we use a semaphore so there's no need to invalidate.
* src/posixos.c (jobserver_parse_auth): If we parse the invalid
auth string, don't set up the jobserver.
(jobserver_get_invalid_auth): Return an invalid option.
* src/variable.h (target_environment): Specify if the target
environment is for a recursive shell or non-recursive shell.
* src/variable.c (target_environment): Move checking for MAKELEVEL
into the loop rather than doing it at the end.
Along with this, check for MAKEFLAGS and MFLAGS, and update them
based on whether we're invoking a recursive or non-recursive child,
and also on whether it's necessary to invalidate the jobserver.
* src/function.c (func_shell_base): Shell functions can never be
recursive to pass 0 to target_environment().
* src/job.c (start_job_command): Specify whether the child is
recursive when calling target_environment().
* src/main.c: Export jobserver_auth.  sync_mutex doesn't need to
be exported.  Use the global definition for the option name.
* tests/scripts/variables/MAKEFLAGS: Add tests for $MAKEFLAGS.
2022-07-30 18:40:28 -04:00

159 lines
4.8 KiB
Perl

# -*-perl-*-
$description = "Test proper behavior of MAKEFLAGS";
$details = "DETAILS";
# Normal flags aren't prefixed with "-"
run_make_test(q!
all: ; @echo /$(MAKEFLAGS)/
!,
'-e -r -R', '/erR/');
# Long arguments mean everything is prefixed with "-"
run_make_test(q!
all: ; @echo /$(MAKEFLAGS)/
!,
'--no-print-directory -e -r -R --trace', "#MAKEFILE#:2: update target 'all' due to: target does not exist
echo /erR --trace --no-print-directory/
/erR --trace --no-print-directory/");
# Recursive invocations of make should accumulate MAKEFLAGS values.
# Savannah bug #2216
run_make_test(q!
MSG = Fails
.RECIPEPREFIX = >
all:
> @echo '$@: MAKEFLAGS=$(MAKEFLAGS)'
> @MSG=Works $(MAKE) -e -f #MAKEFILE# jump
jump:
> @echo '$@ $(MSG): MAKEFLAGS=$(MAKEFLAGS)'
> @$(MAKE) -f #MAKEFILE# print
print:
> @echo '$@ $(MSG): MAKEFLAGS=$(MAKEFLAGS)'
.PHONY: all jump print
!,
'--no-print-directory',
'all: MAKEFLAGS= --no-print-directory
jump Works: MAKEFLAGS=e --no-print-directory
print Works: MAKEFLAGS=e --no-print-directory');
# Ensure MAKEFLAGS updates are handled immediately rather than later
mkdir('foo', 0777);
mkdir('bar', 0777);
run_make_test(q!
$(info MAKEFLAGS=$(MAKEFLAGS))
$(info INCLUDE_DIRS=$(.INCLUDE_DIRS))
MAKEFLAGS += -Ibar
$(info MAKEFLAGS=$(MAKEFLAGS))
$(info INCLUDE_DIRS=$(.INCLUDE_DIRS))
.PHONY: all
all: ; @echo 'MAKEFLAGS=$(MAKEFLAGS)' "\$$MAKEFLAGS=$$MAKEFLAGS"
!,
'-I- -Ifoo', 'MAKEFLAGS= -I- -Ifoo
INCLUDE_DIRS=foo
MAKEFLAGS= -I- -Ifoo -Ibar
INCLUDE_DIRS=foo bar
MAKEFLAGS= -I- -Ifoo -Ibar $MAKEFLAGS= -I- -Ifoo -Ibar');
rmdir('foo');
rmdir('bar');
# Test that command line switches are all present in MAKEFLAGS.
# sv 62514.
my @opts;
# Simple flags.
@opts = ('i', 'k', 'n', 'q', 'r', 's', 'w', 'd');
exists $FEATURES{'check-symlink'} and push @opts, 'L';
for my $opt (@opts) {
run_make_test(q!
MAKEFLAGS:=B
all:; $(info makeflags='$(MAKEFLAGS)')
!, "-$opt", "/makeflags='B$opt'/");
}
# Switches which carry arguments.
@opts = (' -I/tmp', ' -Onone', ' --debug=b', ' -l2.5');
for my $opt (@opts) {
run_make_test(q!
MAKEFLAGS:=B
all:; $(info makeflags='$(MAKEFLAGS)')
!, "$opt", "/makeflags='B$opt'/");
}
# Long options which take no arguments.
# sv 62514.
@opts = (' --no-print-directory', ' --warn-undefined-variables', ' --trace');
for my $opt (@opts) {
run_make_test(q!
MAKEFLAGS:=B
all:; $(info makeflags='$(MAKEFLAGS)')
!, "$opt", "/makeflags='B$opt'/");
}
# Test that make filters out duplicates.
# Each option is specified in the makefile, env and on the command line.
@opts = (' -I/tmp', ' -Onone', ' --debug=b', ' -l2.5');
$ENV{'MAKEFLAGS'} = $opt;
for my $opt (@opts) {
run_make_test("
MAKEFLAGS:=B $opt
all:; \$(info makeflags='\$(MAKEFLAGS)')
", "$opt", "/makeflags='B$opt'/");
}
# Test that make filters out duplicates.
# Each option is specified in the makefile, env and on the command line.
# decode_switches reallocates when the number of parameters in sl->list exceeds 5.
# This test exercises the realloc branch.
$ENV{'MAKEFLAGS'} = '-I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6 -I2 -I2';
run_make_test(q!
MAKEFLAGS:=B -I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6 -I2 -I2
all:; $(info makeflags='$(MAKEFLAGS)')
!,
'-I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6',
"/makeflags='B -I1 -I2 -I3 -I4 -I5 -I6 -l2.5 -Onone --debug=b'/");
# A mix of multiple flags from env, the makefile and command line.
# Skip -L since it's not available everywhere
$ENV{'MAKEFLAGS'} = 'ikB --no-print-directory --warn-undefined-variables --trace';
run_make_test(q!
MAKEFLAGS:=iknqrswd -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5
all:; $(info makeflags='$(MAKEFLAGS)')
!,
'-Onone -l2.5 -l2.5 -Onone -I/tmp -iknqrswd -i -n -s -k -I/tmp',
"/makeflags='Bdiknqrsw -I/tmp -l2.5 -Onone --trace --warn-undefined-variables'/");
# Verify MAKEFLAGS are all available to shell functions
$ENV{'MAKEFLAGS'} = 'ikB --no-print-directory --warn-undefined-variables';
run_make_test(q!
MAKEFLAGS := iknqrsw -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5 --no-print-directory
XX := $(shell echo "$$MAKEFLAGS")
all:; $(info makeflags='$(XX)')
!,
'-Onone -l2.5 -l2.5 -Onone -I/tmp -iknqrs -i -n -s -k -I/tmp',
"makeflags='iknqrsw -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5 --no-print-directory'");
# Verify that command line arguments are included in MAKEFLAGS
run_make_test(q!
all: ; @echo $(MAKEFLAGS)
!,
'-e FOO=bar -r -R', 'erR -- FOO=bar');
# Long arguments mean everything is prefixed with "-"
run_make_test(q!
all: ; @echo /$(MAKEFLAGS)/
!,
'--no-print-directory -e -r -R --trace FOO=bar',
"#MAKEFILE#:2: update target 'all' due to: target does not exist
echo /erR --trace --no-print-directory -- FOO=bar/
/erR --trace --no-print-directory -- FOO=bar/");
1;