dev/gnu-make, libs/freetype2: vendor as full-fork recipes (path=source, patches baked)

This commit is contained in:
2026-08-01 04:43:37 +03:00
parent e99f220c6a
commit cca1a820f0
1289 changed files with 927111 additions and 10 deletions
@@ -0,0 +1,242 @@
# -*-mode: perl-*-
$description = "Test GNU make's archive management features.";
$details = "\
This only works on systems that support it.";
# If this instance of make doesn't support archives, skip it
exists $FEATURES{archives} or return -1;
# In theory archive support exists on Windows but it doesn't use ar;
# someone will need to port this test.
$port_type eq 'W32' and return -1;
# Create some .o files to work with
if ($osname eq 'VMS') {
# VMS AR needs real object files at this time.
foreach $afile ('a1', 'a2', 'a3') {
# Use non-standard extension to prevent implicit rules from recreating
# objects when the test tampers with the timestamp.
1 while unlink "$afile.c1";
1 while unlink "$afile.o";
open (MYFILE, ">$afile.c1");
print MYFILE "int $afile(void) {return 1;}\n";
close MYFILE;
system("cc $afile.c1 /object=$afile.o");
}
} else {
utouch(-60, qw(a1.o a2.o a3.o));
}
# Fallback if configure did not find AR
my $ar = get_config('AR') || 'ar';
my $redir = '2>&1';
$redir = '' if $osname eq 'VMS';
# This is the value from src/default.c
my $arflags = $osname eq 'aix' ? '-Xany -rv' : '-rv';
my $arvar = "AR=$ar";
# Newer versions of binutils can be built with --enable-deterministic-archives
# which forces all timestamps (among other things) to always be 0, defeating
# GNU make's archive support. See if ar supports the U option to disable it.
unlink('libxx.a');
$_ = `$ar ${arflags}U libxx.a a1.o $redir`;
if ($? == 0) {
$arflags = "${arflags}U";
$arvar = "$arvar ARFLAGS=$arflags";
}
# Some versions of ar print different things on creation. Find out.
unlink('libxx.a');
my $created = `$ar $arflags libxx.a a1.o $redir`;
$created =~ s/a1\.o/#OBJECT#/g;
# Some versions of ar print different things on add. Find out.
my $add = `$ar $arflags libxx.a a2.o $redir`;
$add =~ s/a2\.o/#OBJECT#/g;
# Some versions of ar print different things on replacement. Find out.
my $repl = `$ar $arflags libxx.a a2.o $redir`;
$repl =~ s/a2\.o/#OBJECT#/g;
unlink('libxx.a');
# Very simple
($_ = $created) =~ s/#OBJECT#/a1.o/g;
my $answer = "$ar $arflags libxx.a a1.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a1.o';
}
run_make_test('all: libxx.a(a1.o)', $arvar, $answer);
# Multiple .o's. Add a new one to the existing library
($_ = $add) =~ s/#OBJECT#/a2.o/g;
$answer = "$ar $arflags libxx.a a2.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a2.o';
}
run_make_test('all: libxx.a(a1.o a2.o)', $arvar, $answer);
# Touch one of the .o's so it's rebuilt
if ($port_type eq 'VMS-DCL') {
# utouch is not changing what VMS library compare is testing for.
# So do a real change by regenerating the file.
1 while unlink('a1.o');
# Later time stamp than last insertion.
sleep(2);
system('cc a1.c1 /object=a1.o');
# Next insertion will have a later timestamp.
sleep(2);
} else {
utouch(-40, 'a1.o');
}
($_ = $repl) =~ s/#OBJECT#/a1.o/g;
$answer = "$ar $arflags libxx.a a1.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a1.o';
}
run_make_test(undef, $arvar, $answer);
# Use wildcards
$answer = "#MAKE#: Nothing to be done for 'all'.\n";
run_make_test('all: libxx.a(*.o)', $arvar, $answer);
# Touch one of the .o's so it's rebuilt
if ($port_type eq 'VMS-DCL') {
# utouch is not changing what VMS library compare is testing for.
# So do a real change by regenerating the file.
1 while unlink('a1.o');
# Make timestamp later than last insertion.
sleep(2);
system('cc a1.c1 /object=a1.o');
} else {
utouch(-30, 'a1.o');
}
($_ = $repl) =~ s/#OBJECT#/a1.o/g;
$answer = "$ar $arflags libxx.a a1.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a1.o';
}
run_make_test(undef, $arvar, $answer);
# Use both wildcards and simple names
if ($port_type eq 'VMS-DCL') {
# utouch is not changing what VMS library compare is testing for.
# So do a real change by regenerating the file.
1 while unlink('a2.o');
sleep(2);
system('cc a2.c1 /object=a2.o');
} else {
utouch(-50, 'a2.o');
}
($_ = $add) =~ s/#OBJECT#/a3.o/g;
$_ .= "$ar $arflags libxx.a a2.o\n";
($_ .= $repl) =~ s/#OBJECT#/a2.o/g;
$answer = "$ar $arflags libxx.a a3.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a3.o';
}
run_make_test('all: libxx.a(a3.o *.o)', $arvar, $answer);
# Check whitespace handling
if ($port_type eq 'VMS-DCL') {
# utouch is not changing what VMS library compare is testing for.
# So do a real change by regenerating the file.
1 while unlink('a2.o');
sleep(2);
system('cc a2.c1 /object=a2.o');
} else {
utouch(-40, 'a2.o');
}
($_ = $repl) =~ s/#OBJECT#/a2.o/g;
$answer = "$ar $arflags libxx.a a2.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a2.o';
}
run_make_test('all: libxx.a( a3.o *.o )', $arvar, $answer);
rmfiles(qw(a1.c1 a2.c1 a3.c1 a1.o a2.o a3.o libxx.a));
# Check non-archive targets
# See Savannah bug #37878
$mk_string = q!
all: foo(bar).baz
foo(bar).baz: ; @echo '$@'
!;
if ($port_type eq 'VMS-DCL') {
$mk_string =~ s/echo/write sys\$\$output/;
$mk_string =~ s/\'/\"/g;
}
run_make_test($mk_string, $arvar, "foo(bar).baz\n");
# Check renaming of archive targets.
# See Savannah bug #38442
mkdir('artest', 0777);
touch('foo.vhd');
$mk_string = q!
DIR = artest
vpath % $(DIR)
default: lib(foo)
(%): %.vhd ; @cd $(DIR) && touch $(*F) && $(AR) $(ARFLAGS) $@ $(*F) >/dev/null 2>&1 && rm $(*F)
.PHONY: default
!;
if ($port_type eq 'VMS-DCL') {
$mk_string =~ s#= artest#= sys\$\$disk:\[.artest\]#;
$mk_string =~ s#lib\(foo\)#lib.tlb\(foo\)#;
$mk_string =~ s#; \@cd#; pipe SET DEFAULT#;
$mk_string =~
s#touch \$\(\*F\)#touch \$\(\*F\) && library/create/text sys\$\$disk:\$\@#;
$mk_string =~
s#library#if f\$\$search(\"\$\@\") \.eqs\. \"\" then library#;
# VMS needs special handling for null extension
$mk_string =~ s#\@ \$\(\*F\)#\@ \$\(\*F\)\.#;
$mk_string =~ s#>/dev/null 2>&1 ##;
}
run_make_test($mk_string, $arvar, "");
run_make_test(undef, $arvar, "#MAKE#: Nothing to be done for 'default'.\n");
unlink('foo.vhd');
if ($osname eq 'VMS') {
remove_directory_tree("$cwdpath/artest");
} else {
remove_directory_tree('artest');
}
# Check long names for archive members.
# See Savannah bug #54395
if ($osname ne 'VMS') {
my $pre = '1234567890123456';
my $lib = 'libxx.a';
my $cr = $created;
$cr =~ s/#OBJECT#/${pre}a/g;
my $ad = $add;
$ad =~ s/#OBJECT#/${pre}b/g;
run_make_test(qq!
# Both member names > 16 characters long
default: $lib(${pre}a) $lib(${pre}b)
(%): % ; \$(AR) \$(ARFLAGS) \$@ \$%
$pre%: ; touch \$\@
!,
$arvar, "touch ${pre}a\n$ar $arflags $lib ${pre}a\n${cr}touch ${pre}b\n$ar $arflags $lib ${pre}b\n${ad}rm ${pre}a ${pre}b\n");
# Run it again; nothing should happen
run_make_test(undef, $arvar, "#MAKE#: Nothing to be done for 'default'.\n");
unlink($lib);
}
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,35 @@
$description = "The following test creates a makefile to test comments\n"
."and comment continuation to the next line using a \n"
."backslash within makefiles.";
$details = "To test comments within a makefile, a semi-colon was placed \n"
."after a comment was started. This should not be reported as\n"
."an error since it is within a comment. We then continue the \n"
."comment to the next line using a backslash. To test whether\n"
."the comment really continued, we place an echo command with some\n"
."text on the line which should never execute since it should be \n"
."within a comment\n";
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE <<\EOF;
# Test comment vs semicolon parsing and line continuation
target: # this ; is just a comment \
@echo This is within a comment.
@echo There should be no errors for this makefile.
EOF
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = "There should be no errors for this makefile.\n";
# COMPARE RESULTS
&compare_output($answer,&get_logfile(1))
@@ -0,0 +1,162 @@
# -*-perl-*-
$description = "Check GNU make conditionals.";
$details = "Attempt various different flavors of GNU make conditionals.";
run_make_test('
arg1 = first
arg2 = second
arg3 = third
arg4 = cc
arg5 = second
all:
ifeq ($(arg1),$(arg2))
@echo arg1 equals arg2
else
@echo arg1 NOT equal arg2
endif
ifeq \'$(arg2)\' "$(arg5)"
@echo arg2 equals arg5
else
@echo arg2 NOT equal arg5
endif
ifneq \'$(arg3)\' \'$(arg4)\'
@echo arg3 NOT equal arg4
else
@echo arg3 equal arg4
endif
ifndef undefined
@echo variable is undefined
else
@echo variable undefined is defined
endif
ifdef arg4
@echo arg4 is defined
else
@echo arg4 is NOT defined
endif',
'',
'arg1 NOT equal arg2
arg2 equals arg5
arg3 NOT equal arg4
variable is undefined
arg4 is defined');
# Test expansion of variables inside ifdef.
run_make_test('
foo = 1
FOO = foo
F = f
DEF = no
DEF2 = no
ifdef $(FOO)
DEF = yes
endif
ifdef $(F)oo
DEF2 = yes
endif
DEF3 = no
FUNC = $1
ifdef $(call FUNC,DEF)3
DEF3 = yes
endif
all:; @echo DEF=$(DEF) DEF2=$(DEF2) DEF3=$(DEF3)',
'',
'DEF=yes DEF2=yes DEF3=yes');
# Test all the different "else if..." constructs
run_make_test('
arg1 = first
arg2 = second
arg3 = third
arg4 = cc
arg5 = fifth
result =
ifeq ($(arg1),$(arg2))
result += arg1 equals arg2
else ifeq \'$(arg2)\' "$(arg5)"
result += arg2 equals arg5
else ifneq \'$(arg3)\' \'$(arg3)\'
result += arg3 NOT equal arg4
else ifndef arg5
result += variable is undefined
else ifdef undefined
result += arg4 is defined
else
result += success
endif
all: ; @echo $(result)',
'',
'success');
# Test some random "else if..." construct nesting
run_make_test('
arg1 = first
arg2 = second
arg3 = third
arg4 = cc
arg5 = second
ifeq ($(arg1),$(arg2))
$(info failed 1)
else ifeq \'$(arg2)\' "$(arg2)"
ifdef undefined
$(info failed 2)
else
$(info success)
endif
else ifneq \'$(arg3)\' \'$(arg3)\'
$(info failed 3)
else ifdef arg5
$(info failed 4)
else ifdef undefined
$(info failed 5)
else
$(info failed 6)
endif
.PHONY: all
all: ; @:',
'',
'success');
# SV 47960 : ensure variable assignments in non-taken legs don't cause problems
run_make_test('
ifneq ($(FOO),yes)
target:
else
BAR = bar
target:
endif
@echo one
',
'', "one\n");
# This tells the test driver that the perl test script executed properly.
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:
@@ -0,0 +1,44 @@
# -*-perl-*-
$description = "This script tests to make sure that Make looks for
default makefiles in the correct order (GNUmakefile,makefile,Makefile)";
# Create a makefile called "GNUmakefile"
$makefile = "GNUmakefile";
open(MAKEFILE,"> $makefile");
print MAKEFILE "FIRST: ; \@echo It chose GNUmakefile\n";
close(MAKEFILE);
# Create another makefile called "makefile"
open(MAKEFILE,"> makefile");
print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
close(MAKEFILE);
# DOS/W32/MacOSX platforms are case-insensitive / case-preserving, so
# Makefile is the same file as makefile. Just test what we can here.
my $case_sensitive = 0;
if (! -f 'Makefile') {
# Create another makefile called "Makefile"
$case_sensitive = 1;
open(MAKEFILE,"> Makefile");
print MAKEFILE "THIRD: ; \@echo It chose Makefile\n";
close(MAKEFILE);
}
run_make_with_options("","",&get_logfile);
compare_output("It chose GNUmakefile\n",&get_logfile(1));
unlink($makefile);
run_make_with_options("","",&get_logfile);
compare_output("It chose makefile\n",&get_logfile(1));
unlink("makefile");
if ($case_sensitive) {
run_make_with_options("","",&get_logfile);
compare_output("It chose Makefile\n",&get_logfile(1));
unlink("Makefile");
}
1;
@@ -0,0 +1,31 @@
# -*-mode: perl-*-
$description = "Test the directory cache behavior.";
# The first wildcard should bring the entire directory into the cache Then we
# create a new file "behind make's back" then see if the next wildcard detects
# it.
run_make_test(q!
_orig := $(wildcard ./*)
$(shell echo > anewfile)
_new := $(wildcard ./*)
$(info diff=$(filter-out $(_orig),$(_new)))
all:;@:
!,
'', "diff=./anewfile\n");
rmfiles('anewfile');
run_make_test(q!
_orig := $(wildcard ./*)
$(file >anewfile)
_new := $(wildcard ./*)
$(info diff=$(filter-out $(_orig),$(_new)))
all:;@:
!,
'', "diff=./anewfile\n");
rmfiles('anewfile');
1;
@@ -0,0 +1,230 @@
# -*-perl-*-
$description = "Test handling of double-colon rules.";
$details = "\
We test these features:
- Multiple commands for the same (double-colon) target
- Different prerequisites for targets: only out-of-date
ones are rebuilt.
- Double-colon targets that aren't the goal target.
Then we do the same thing for parallel builds: double-colon
targets should always be built serially.";
# TEST 0: A simple double-colon rule that isn't the goal target.
run_make_test(q!
all: baz
foo:: f1.h ; @echo foo FIRST
foo:: f2.h ; @echo foo SECOND
bar:: ; @echo aaa; sleep 1; echo aaa done
bar:: ; @echo bbb
baz:: ; @echo aaa
baz:: ; @echo bbb
biz:: ; @echo aaa
biz:: two ; @echo bbb
two: ; @echo two
f1.h f2.h: ; @echo $@
d :: ; @echo ok
d :: d ; @echo oops
!,
"all", "aaa\nbbb\n");
# TEST 1: As above, in parallel
if ($parallel_jobs) {
run_make_test(undef, "-j10 all", "aaa\nbbb\n");
}
# TEST 2: A simple double-colon rule that is the goal target
run_make_test(undef, "bar", "aaa\naaa done\nbbb\n");
# TEST 3: As above, in parallel
if ($parallel_jobs) {
run_make_test(undef, "-j10 bar", "aaa\naaa done\nbbb\n");
}
# TEST 4: Each double-colon rule is supposed to be run individually
&utouch(-5, 'f2.h');
&touch('foo');
run_make_test(undef, "foo", "f1.h\nfoo FIRST\n");
# TEST 5: Again, in parallel.
if ($parallel_jobs) {
run_make_test(undef, "-j10 foo", "f1.h\nfoo FIRST\n");
}
# TEST 6: Each double-colon rule is supposed to be run individually
&utouch(-5, 'f1.h');
unlink('f2.h');
&touch('foo');
run_make_test(undef, "foo", "f2.h\nfoo SECOND\n");
# TEST 7: Again, in parallel.
if ($parallel_jobs) {
run_make_test(undef, "-j10 foo", "f2.h\nfoo SECOND\n");
}
# TEST 8: Test circular dependency check; PR/1671
run_make_test(undef, "d", "ok\n$make_name: Circular d <- d dependency dropped.\noops\n");
# TEST 8: I don't grok why this is different than the above, but it is...
#
# Hmm... further testing indicates this might be timing-dependent?
#
#if ($parallel_jobs) {
# run_make_test(undef, "-j10 biz", "aaa\ntwo\nbbb\n");
#}
unlink('foo','f1.h','f2.h');
# TEST 9: make sure all rules in s double colon family get executed
# (Savannah bug #14334).
#
&touch('one');
&touch('two');
run_make_test('
.RECIPEPREFIX = >
.PHONY: all
all: result
result:: one
> @echo $^ >>$@
> @echo $^
result:: two
> @echo $^ >>$@
> @echo $^
',
'',
'one
two');
unlink('result','one','two');
# TEST 10: SV 33399 : check for proper backslash handling
run_make_test('
a\ xb :: ; @echo one
a\ xb :: ; @echo two
',
'', "one\ntwo\n");
# Test 11: SV 44742 : All double-colon rules should be run in parallel build.
run_make_test('
.RECIPEPREFIX = >
result :: 01
> @echo update
> @touch $@
result :: 02
> @echo update
> @touch $@
result :: 03
> @echo update
> @touch $@
result :: 04
> @echo update
> @touch $@
result :: 05
> @echo update
> @touch $@
01 02 03 04 05:
> @touch 01 02 03 04 05
',
'-j10 result', "update\nupdate\nupdate\nupdate\nupdate\n");
unlink('result', '01', '02', '03', '04', '05');
# Test 12: SV 44742 : Double-colon rules with parallelism
run_make_test('
root: all ; echo root
all:: ; echo all_one
all:: 3 ; echo all_two
%: ; sleep $*
',
'-rs -j2 1 2 root', "all_one\nall_two\nroot\n");
# SV 47995 : Parallel double-colon rules with FORCE
run_make_test('
all:: ; @echo one
all:: joe ; @echo four
joe: FORCE ; touch joe-is-forced
FORCE:
',
'-j5', "one\ntouch joe-is-forced\nfour\n");
unlink('joe-is-forced');
# sv 60188.
# Even though test.x is explicitly mentioned, terminal pattern rules still
# apply only if the prerequisite exists.
touch('hello.z');
# subtest 1. test.x is explicitly mentioned.
run_make_test(q!
all: hello.z
%.z:: test.x ; touch $@
%.x: ;
!,
'', "#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.z');
# subtest 2. hello.x is derived from the stem.
touch('hello.z');
run_make_test(q!
all: hello.z
%.z:: %.x; touch $@
%.x: ; touch $@
!,
'', "#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.z');
# subtest 3
# hello.x is explicitly mentioned on an unrelated rule and thus is not an
# intermediate file.
# Terminal pattern rules do not apply anyway and there is no rule to built
# 'hello.x'.
touch('hello.z');
run_make_test(q!
all: hello.z
%.z:: %.x; touch $@
%.x: ;
unrelated: hello.x
!,
'', "#MAKE#: *** No rule to make target 'hello.x', needed by 'hello.z'. Stop.\n", 512);
unlink('hello.z');
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,64 @@
# -*-perl-*-
$description = "The following test creates a makefile to test command
echoing. It tests that when a command line starts with
a '\@', the echoing of that line is suppressed. It also
tests the -n option which tells make to ONLY echo the
commands and no execution happens. In this case, even
the commands with '\@' are printed. Lastly, it tests the
-s flag which tells make to prevent all echoing, as if
all commands started with a '\@'.";
$details = "This test is similar to the 'clean' test except that a '\@' has
been placed in front of the delete command line. Four tests
are run here. First, make is run normally and the first echo
command should be executed. In this case there is no '\@' so
we should expect make to display the command AND display the
echoed message. Secondly, make is run with the clean target,
but since there is a '\@' at the beginning of the command, we
expect no output; just the deletion of a file which we check
for. Third, we give the clean target again except this time
we give make the -n option. We now expect the command to be
displayed but not to be executed. In this case we need only
to check the output since an error message would be displayed
if it actually tried to run the delete command again and the
file didn't exist. Lastly, we run the first test again with
the -s option and check that make did not echo the echo
command before printing the message.\n";
$example = "EXAMPLE_FILE";
touch($example);
# TEST #1
# -------
run_make_test("
all:
\techo This makefile did not clean the dir... good
clean:
\t\@$CMD_rmfile $example\n",
'', 'echo This makefile did not clean the dir... good
This makefile did not clean the dir... good');
# TEST #2
# -------
run_make_test(undef, 'clean', '');
if (-f $example) {
$test_passed = 0;
unlink($example);
}
# TEST #3
# -------
run_make_test(undef, '-n clean', "$CMD_rmfile $example\n");
# TEST #4
# -------
run_make_test(undef, '-s', "This makefile did not clean the dir... good\n");
1;
@@ -0,0 +1,118 @@
# -*-perl-*-
$description = "Test ignored failures in recipe command lines";
run_make_test(qq!
one:
\t-exit 1
\texit 0
two:
\texit 1
\texit 0
!,
"one", "exit 1\n#MAKE#: [#MAKEFILE#:3: one] Error 1 (ignored)\nexit 0\n");
# TEST #1
# -------
run_make_test(undef, " -i two",
"exit 1\n#MAKE#: [#MAKEFILE#:6: two] Error 1 (ignored)\nexit 0\n");
# TEST #2
# -------
# Test that error line offset works
run_make_test(qq!
all:
\t\@echo hi
\t\@echo there
\t\@exit 1
!,
'', "hi\nthere\n#MAKE#: *** [#MAKEFILE#:5: all] Error 1", 512);
# Windows error look completely different :-/
sub errors_getinfo
{
my ($cmd, $args) = @_;
if ($port_type eq 'W32') {
return (2, "process_begin: CreateProcess(NULL, $cmd $args, ...) failed.\nmake (e=2): The system cannot find the file specified.");
}
return (127, "#MAKE#: $cmd: $ERR_no_such_file");
}
# TEST #3
# -------
# Try failing due to unknown command
my $unk = './foobarbazbozblat';
unlink($unk);
my ($ernum, $erstr) = errors_getinfo($unk, "xx yy");
run_make_test(qq!
one: ; -$unk xx yy
!, 'one',
"$unk xx yy\n$erstr\n#MAKE#: [#MAKEFILE#:2: one] Error $ernum (ignored)\n");
# TEST #4
# -------
($ernum, $erstr) = errors_getinfo($unk, "aa bb");
run_make_test(qq!
two: ; $unk aa bb
!, 'two -i',
"$unk aa bb\n$erstr\n#MAKE#: [#MAKEFILE#:2: two] Error $ernum (ignored)\n");
# TEST #5
# -------
run_make_test(undef, 'two',
"$unk aa bb\n$erstr\n#MAKE#: *** [#MAKEFILE#:2: two] Error $ernum\n", 512);
# SV #56918 : Test the unknown command as the second recipe line
($ernum, $erstr) = errors_getinfo($unk, "qq rr");
run_make_test(qq!
three:
\t\@echo one
\t$unk qq rr
!, 'three',
"one\n$unk qq rr\n$erstr\n#MAKE#: *** [#MAKEFILE#:4: three] Error $ernum\n", 512);
# Try failing due to non-executable file
if ($ERR_nonexe_file) {
my $noexe = './barfooblatboz';
touch($noexe);
run_make_test(qq!
one: ; -$noexe xx yy
two: ; $noexe aa bb
!,
'one', "$noexe xx yy\n#MAKE#: $noexe: $ERR_nonexe_file\n#MAKE#: [#MAKEFILE#:2: one] Error 127 (ignored)\n");
unlink($noexe);
}
# Try failing by "running" a directory
if ($ERR_exe_dir) {
mkdir('sd', 0775) or print "mkdir: sd: $!\n";
run_make_test(q!
PATH := .
all: ; sd
!,
'', "sd\n#MAKE#: sd: $ERR_exe_dir\n#MAKE#: *** [#MAKEFILE#:3: all] Error 127", 512);
run_make_test(q!
all: ; ./sd
!,
'', "./sd\n#MAKE#: ./sd: $ERR_exe_dir\n#MAKE#: *** [#MAKEFILE#:2: all] Error 127", 512);
rmdir('sd');
}
1;
@@ -0,0 +1,103 @@
# -*-perl-*-
$description = "Test various types of escaping in makefiles.";
$details = "\
Make sure that escaping of ':' works in target names.
Make sure escaping of whitespace works in target names.
Make sure that escaping of '#' works.
Make sure that backslash before non-special characters are kept.";
# TEST 1
run_make_test(q!
ifdef NOESC
path = pre:
endif
ifdef ONEESC
path = pre\:
endif
ifdef TWOESC
path = pre\\\\:
endif
$(path)foo : ; @echo "touch ($@)"
foo\ bar: ; @echo "touch ($@)"
sharp: foo\#bar.ext
foo\#bar.ext: ; @echo "foo#bar.ext = ($@)"
!,
'',
'touch (foo)');
# TEST 2: This one should fail, since the ":" is unquoted.
run_make_test(undef,
'NOESC=1',
"#MAKEFILE#:12: *** target pattern contains no '%'. Stop.",
512);
# TEST 3: This one should work, since we escape the ":".
run_make_test(undef,
'ONEESC=1',
'touch (pre:foo)');
# TEST 4: This one should fail, since the escape char is escaped.
run_make_test(undef,
'TWOESC=1',
"#MAKEFILE#:12: *** target pattern contains no '%'. Stop.",
512);
# TEST 5: This one should work
run_make_test(undef,
['foo bar'],
'touch (foo bar)');
# TEST 6: Test escaped comments
run_make_test(undef,
'sharp',
'foo#bar.ext = (foo#bar.ext)');
# Test escaped colons in prerequisites
# Quoting of backslashes in q!! is kind of messy.
# Solaris sh does not properly handle backslashes even in '' so just
# check the output make prints, not what the shell interprets.
run_make_test(q!
foo: foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar
foo foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar: ; : '$@'
!,
'', ": 'foo:bar'\n: 'foo\\:bar'\n: 'foo\\\\:bar'\n: 'foo'\n");
# Test backslash before non-special chars: should be kept as-is
run_make_test(q!
all: ..\foo
.DEFAULT: ; : '$@'
!,
'', ": '..\\foo'\n");
# Test escaped comments in variable assignments
run_make_test(q!
self = $1
foo := $(call self,#foo#)#foo
bar := $(call self,\#bar\#)#bar
all:;@echo '$(foo) $(bar)'
!,
'',"#foo# \\#bar\\#");
# Test escaped comments in variable assignments in a variable
run_make_test(q!
C = \#
self = $1
foo := $(call self,$Cfoo$C)#foo
all:;@echo '$(foo)'
!,
'',"#foo#");
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,72 @@
# -*-perl-*-
use warnings;
my $description = "Test that make can execute binaries as well as scripts with"
." various shabangs and without a shbang";
my $details = "The various shells that this test uses are the default"
." /bin/sh, \$SHELL and the perl interpreter that is"
." executing this test program. The shells are used for the value"
." of SHELL inside the test makefile and also as a shbang in the"
." executed script. There is also a test which executes a script"
." that has no shbang.";
# Only bother with this on UNIX systems
$port_type eq 'UNIX' or return -1;
$^O =~ /cygwin/ and return -1;
my @shbangs = ('', '#!/bin/sh', "#!$perl_name");
my @shells = ('', 'SHELL=/bin/sh');
# Try whatever shell the user has, as long as it's not a C shell.
# The C shell is not usable with make, due to not correctly handling
# file descriptors and possibly other issues.
my $usersh = $origENV{SHELL};
if ($usersh !~ /csh/) {
push @shbangs, ("#!$usersh");
push @shells, ("SHELL=$usersh");
}
my $answer = 'hello, world';
# tests [0-11]
# Have a makefile with various SHELL= exec a shell program with varios
# shbangs or without a shbang at all.
my $stem = './exec.cmd';
my $k = 0;
for my $shbang (@shbangs) {
for my $shell (@shells) {
my $cmd = $k ? "$stem.$k" : $stem;
++$k;
unlink $cmd;
open(CMD,"> $cmd");
print CMD "$shbang\n";
print CMD "printf \"$answer\\n\";\n";
close(CMD);
chmod 0700, $cmd;
run_make_test("# shbang=$shbang\n# shell=$shell" . q!
all:; @$(CMD)
!, "$shell CMD=$cmd", "$answer\n");
rmfiles($cmd);
}
}
# tests [12-14]
# Exec a binary from a makefile that has SHELL=.
for my $shell (@shells) {
run_make_test(q!
all:; @#PERL# -e 'printf "$(ANSWER)\n"';
!, "$shell ANSWER='$answer'", "$answer\n");
}
# test 15
# Use perl as a shell.
run_make_test(q!
SHELL = #PERL#
.SHELLFLAGS = -e
all:; @printf "$(ANSWER)\n";
!, "ANSWER='$answer'", "$answer\n");
1;
@@ -0,0 +1,210 @@
# -*-perl-*-
$description = "Check GNU make export/unexport commands.";
$details = "";
# The test driver cleans out our environment for us so we don't have to worry
# about that here.
&run_make_test('
FOO = foo
BAR = bar
BOZ = boz
export BAZ = baz
export BOZ
BITZ = bitz
BOTZ = botz
export BITZ BOTZ
unexport BOTZ
ifdef EXPORT_ALL
export
endif
ifdef UNEXPORT_ALL
unexport
endif
ifdef EXPORT_ALL_PSEUDO
.EXPORT_ALL_VARIABLES:
endif
.RECIPEPREFIX := >
all:
> @echo "FOO=$(FOO) BAR=$(BAR) BAZ=$(BAZ) BOZ=$(BOZ) BITZ=$(BITZ) BOTZ=$(BOTZ)"
> @echo "FOO=$$FOO BAR=$$BAR BAZ=$$BAZ BOZ=$$BOZ BITZ=$$BITZ BOTZ=$$BOTZ"
',
'', "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
# TEST 1: make sure vars inherited from the parent are exported
$ENV{FOO} = 1;
&run_make_test(undef, '', "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
FOO=foo BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
# TEST 2: global export. Explicit unexport takes precedence.
run_make_test(undef, "EXPORT_ALL=1" ,
"FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
# TEST 3: global unexport. Explicit export takes precedence.
&run_make_test(undef, "UNEXPORT_ALL=1",
"FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
# TEST 4: both: in the above makefile the unexport comes last so that rules.
&run_make_test(undef, "EXPORT_ALL=1 UNEXPORT_ALL=1",
"FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
# TEST 5: test the pseudo target.
&run_make_test(undef, "EXPORT_ALL_PSEUDO=1",
"FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
# TEST 6: Test the expansion of variables inside export
&run_make_test('
foo = f-ok
bar = b-ok
FOO = foo
F = f
BAR = bar
B = b
export $(FOO)
export $(B)ar
.RECIPEPREFIX := >
all:
> @echo foo=$(foo) bar=$(bar)
> @echo foo=$$foo bar=$$bar
',
"", "foo=f-ok bar=b-ok\nfoo=f-ok bar=b-ok\n");
# TEST 7: Test the expansion of variables inside unexport
&run_make_test('
foo = f-ok
bar = b-ok
FOO = foo
F = f
BAR = bar
B = b
export foo bar
unexport $(FOO)
unexport $(B)ar
.RECIPEPREFIX := >
all:
> @echo foo=$(foo) bar=$(bar)
> @echo foo=$$foo bar=$$bar
',
'', "foo=f-ok bar=b-ok\nfoo= bar=\n");
# TEST 7: Test exporting multiple variables on the same line
&run_make_test('
A = a
B = b
C = c
D = d
E = e
F = f
G = g
H = h
I = i
J = j
SOME = A B C
export F G H I J
export D E $(SOME)
all: ; @echo A=$$A B=$$B C=$$C D=$$D E=$$E F=$$F G=$$G H=$$H I=$$I J=$$J
',
'', "A=a B=b C=c D=d E=e F=f G=g H=h I=i J=j\n");
# TEST 8: Test unexporting multiple variables on the same line
@args{qw(A B C D E F G H I J)} = qw(1 2 3 4 5 6 7 8 9 10);
%ENV = (%ENV, %args);
&run_make_test('
A = a
B = b
C = c
D = d
E = e
F = f
G = g
H = h
I = i
J = j
SOME = A B C
unexport F G H I J
unexport D E $(SOME)
all: ; @echo A=$$A B=$$B C=$$C D=$$D E=$$E F=$$F G=$$G H=$$H I=$$I J=$$J
',
'', "A= B= C= D= E= F= G= H= I= J=\n");
# TEST 9: Check setting a variable named "export"
&run_make_test('
export = 123
export export
export export = 456
a: ; @echo "\$$(export)=$(export) / \$$export=$$export"
',
'', "\$(export)=456 / \$export=456\n");
# TEST 10: Check "export" as a target
&run_make_test('
a: export
export: ; @echo "$@"
',
'', "export\n");
# Check export and assignment of a variable on the same line
$ENV{hello} = 'moon';
run_make_test(q!
all: ; @echo hello=$(hello) hello=$$hello
export hello=sun
!,
'', "hello=sun hello=sun\n");
# Check unexport and assignment of a variable on the same line
$ENV{hello} = 'moon';
run_make_test(q!
all: ; @echo hello=$(hello) hello=$$hello
unexport hello=sun
!,
'', "hello=sun hello=\n");
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,207 @@
# -*-perl-*-
$description = "This test is about grouped multiple targets indicated by &:";
$details = "Here we test for requirements like\n"
."- if multiple such targets are updated, the recipe is run once\n"
."- parsing issues related to the &: syntax itself\n";
# Parsing: &: allowed without any targets.
run_make_test(q{
.PHONY: all
&:;
all: ;@printf ''
},
'', "");
# Parsing: &: works not preceded by whitespace.
run_make_test(q{
foo&:;@echo foo
},
'foo', "foo");
# Ordinary rule runs recipe four times for t1 t2 t3 t4.
# Grouped target rule runs recipe once; others are considered updated.
run_make_test(q{
.PHONY: t1 t2 t3 t4 g1 g2 g3 g4
t1 t2 t3 t4: ; @echo $@
g1 g2 g3 g4 &: ; @echo $@
},
't1 t2 t3 t4 g1 g2 g3 g4',
"t1\n"
."t2\n"
."t3\n"
."t4\n"
."g1\n"
."#MAKE#: Nothing to be done for 'g2'.\n"
."#MAKE#: Nothing to be done for 'g3'.\n"
."#MAKE#: Nothing to be done for 'g4'.");
# Similar to previous test, but targets come from m1 phony
# rather than from the command line. We don't see "Nothing to
# be done for" messages. Also, note reversed order g4 g3 ...
# Thus the auto variable $@ is "g4" when that rule fires.
run_make_test(q{
.PHONY: m1 t1 t2 t3 t4 g1 g2 g3 g4
m1: t1 t2 t3 t4 g4 g3 g2 g1
t1 t2 t3 t4: ; @echo $@
g1 g2 g3 g4&: ; @echo $@
},
'',
"t1\nt2\nt3\nt4\ng4");
# Set a grouped target recipe for existing targets
run_make_test(q{
.PHONY: M a b
M: a b
a:
a b&: ; @echo Y
b:
},
'',
"Y");
# grouped targets require a recipe
run_make_test(q{
.PHONY: M a b
M: a b
a b&:
},
'',
"#MAKEFILE#:4: *** grouped targets must provide a recipe. Stop.", 512);
# Pattern rules use grouped targets anyway so it's a no-op
run_make_test(q{
.PHONY: M
M: a.q b.q
a.% b.%&: ; @echo Y
},
'',
"Y");
# Double-colon grouped target rules.
run_make_test(q{
.PHONY: M a b c d e f g h
M: a b
a b c&:: ; @echo X
c d e&:: ; @echo Y
f g h&:: ; @echo Z
},
'',
"X");
run_make_test(q{
.PHONY: M a b c d e f g h
M: c
a b c&:: ; @echo X
c d e&:: ; @echo Y
f g h&:: ; @echo Z
},
'',
"X\nY");
run_make_test(q{
.PHONY: M a b c d e f g h
M: a b c d e
a b c&:: ; @echo X
c d e&:: ; @echo Y
f g h&:: ; @echo Z
},
'',
"X\nY");
run_make_test(q{
.PHONY: M a b c d e f g h
M: d e
a b c&:: ; @echo X
c d e&:: ; @echo Y
f g h&:: ; @echo Z
},
'',
"Y");
run_make_test(q{
.PHONY: M a b c d e f g h
M: f g h
a b c&:: ; @echo X
c d e&:: ; @echo Y
f g h&:: ; @echo Z
},
'',
"Z");
# sv 60188.
# Test that a file explicitly mentioned by the user and made by an implicit
# rule is not considered intermediate.
touch('hello.z');
touch('hello.q');
# subtest 1
# hello.x is not explicitly mentioned and thus is an intermediate file.
run_make_test(q!
all: hello.z
%.z %.q: %.x ; touch $*.z $*.q
%.x: ;
!, '', "#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2
# test.x is explicitly mentioned and thus is not an intermediate file.
run_make_test(q!
all: hello.z
%.z %.q: %.x test.x ; @echo $*.z $*.q
%.x: ;
!, '', "hello.z hello.q\n");
# subtest 3
# hello.x is explicitly mentioned on an unrelated rule and thus is not an
# intermediate file.
run_make_test(q!
all: hello.z
%.z %.q: %.x; @echo $*.z $*.q
%.x: ;
unrelated: hello.x
!, '', "hello.z hello.q\n");
unlink('hello.z');
unlink('hello.q');
# SV 62809: Missing grouped target peer causes remake regardless of which
# target caused the rule to run.
touch(qw(gta)); # but not gtb
run_make_test(q!
gta gtb &: ; touch gta gtb
!,
'gta', "touch gta gtb\n");
unlink(qw(gta gtb));
# Ensure both goal targets are built if they depend on a grouped prereq
touch(qw(gta)); # but not gtb
run_make_test(q!
x1 x2: ; touch $@
x1: gta
x2: gtb
gta gtb &: ; touch gta gtb
!,
'x1 x2', "touch gta gtb\ntouch x1\ntouch x2\n");
# Now everything should be up to date
run_make_test(undef, 'x1 x2',
"#MAKE#: 'x1' is up to date.\n#MAKE#: 'x2' is up to date.");
unlink(qw(x1 x2 gta gtb));
# If an also-make file is older than a prerequisite build both
utouch(-20, 'gtb');
utouch(-10, 'pre');
touch(qw(gta));
run_make_test(q!
gta gtb &: pre ; touch gta gtb
!,
'gta', "touch gta gtb\n");
unlink(qw(pre gta gtb));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,483 @@
# -*-perl-*-
$description = "Test implicit rule search.";
$details = "";
# sv 48643
# Each test has a %.c rule ahead of %.f rule.
# hello.f exists and hello.c is missing.
unlink('hello.c', 'hello.tsk', 'hello.o', 'hello.x');
# Run every test with and without a suffix.
my @suffixes = ('', '.o');
# Run every test with single and double colon rules.
my @rules = ('', ':');
for my $s (@suffixes) {
for my $r (@rules) {
touch('hello.f');
# Test that make finds the intended implicit rule based on existence of a
# prerequisite in the filesystem.
#
# '%.o: %.c' rule is skipped and '%.o: %.f' rule is chosen.
run_make_test("
all: hello$s
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
", '-r', "hello.f\n#MAKE#: Nothing to be done for 'all'.");
# Test that make finds the intended implicit rule based on the explicit
# prerequisite of the top goal and despite the existence of a
# prerequisite in the filesystem.
#
# hello.c is an explicit prerequisite of the top target (hello.o or hello).
# hello.c ought to exist.
# hello.c prerequisite causes '%.o: %.c' rule to be chosen.
run_make_test("
hello$s: hello.c
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
", '-r',
"#MAKE#: *** No rule to make target 'hello.c', needed by 'hello$s'. Stop.\n",
512);
# Test that make finds the intended implicit rule when the implicit
# prerequisite matches a target of an unrelated rule and despite the existence
# of a prerequisite of the other rule candidate in the filesystem.
#
# hello.c matches 'hello.c:' rule. This makes hello.c a target and thus ought
# to exist.
# hello.c prerequisite causes '%.o: %.c' rule to be chosen.
run_make_test("
all: hello$s
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
hello.c:; @#HELPER# fail 1
", '-r', "fail 1\n#MAKE#: *** [#MAKEFILE#:5: hello.c] Error 1\n", 512);
# Test that make finds the intended implicit rule based on existence of a
# prerequisite in the filesystem, even when the prerequisite of another
# candidate rule is mentioned explicitly on an unrelated rule.
#
# '%.o: %.c' rule is skipped and '%.o: %.f' rule is chosen, even though hello.c
# is mentioned explicitly on 'unrelated: hello.c'.
# ought-to-exist does not apply to hello.c.
run_make_test("
all: hello$s
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
unrelated: hello.c
", '-r', "hello.f\n#MAKE#: Nothing to be done for 'all'.");
# Test that make finds the intended implicit rule based on existence of a
# prerequisite in the filesystem.
#
# '%.o: %.c' rule is skipped and '%.o: %.f' rule is chosen.
# Despite '%.o: %.c hello.c' rule having explicit prerequisite hello.c.
# ought-to-exist does not apply to hello.c.
run_make_test("
all: hello$s
%$s:$r %.c hello.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
", '-r', "hello.f\n#MAKE#: Nothing to be done for 'all'.");
# '%.o: %.c' rule is skipped and '%.o: %.f' rule is chosen.
# '%.o: %.f hello.f' rule has explicit prerequisite hello.f.
# ought-to-exist does not apply to hello.c.
run_make_test("
all: hello$s
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f hello.f; \$(info hello.f)
", '-r', "hello.f\n#MAKE#: Nothing to be done for 'all'.");
# Rule '%: %.f' is chosen, because '%: %.f' requires no intermediates.
# '%: %.c', on the other hand, requires intemediate hello.c to be built by the
# default rule.
run_make_test("
all: hello$s
%$s:$r %.c; \$(info \$<)
%$s:$r %.f; \$(info \$<)
.DEFAULT:; \$(info \$\@) true
unrelated: hello.c
", '-r', "hello.f\n#MAKE#: Nothing to be done for 'all'.");
# hello.f is missing.
# This time both hello.c and hello.f are missing and both '%: %.c' and '%: %.f'
# require an intermediate.
# The default rule builds intemerdiate hello.c.
# '%: %.c' rule is chosen to build hello.
unlink('hello.f');
run_make_test("
all: hello$s
%$s:$r %.c; \$(info \$<)
%$s:$r %.f; \$(info \$<)
.DEFAULT:; \@\$(info \$\@) #HELPER# fail 1
unrelated: hello.c
", '-r', "hello.c\nfail 1\n#MAKE#: *** [#MAKEFILE#:5: hello.c] Error 1\n", 512);
# hello.f is missing.
# No rule is found, because hello.c is not mentioned explicitly.
run_make_test("
all: hello$s
%$s:$r %.c; \$(info \$<)
%$s:$r %.f; \$(info \$<)
.DEFAULT:; \@\$(info \$\@) #HELPER# fail 1
", '-r', "hello$s\nfail 1\n#MAKE#: *** [#MAKEFILE#:5: hello$s] Error 1\n", 512);
}
}
# Almost the same tests as above, but this time an intermediate is built.
touch('hello.f');
for my $s (@suffixes) {
for my $r (@rules) {
my $result = "#MAKE#: *** No rule to make target 'hello.tsk', needed by 'all'. Stop.\n";
my $rcode = 512;
if ($s or $r) {
$result = "hello.f\nhello.tsk\n#MAKE#: Nothing to be done for 'all'.";
$rcode = 0;
}
run_make_test("
all: hello.tsk
%.tsk: %$s; \$(info hello.tsk)
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
", '-r', "$result", $rcode);
run_make_test("
all: hello.tsk
%.tsk: %$s hello$s; \$(info hello.tsk)
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
", '-r', $result, $rcode);
run_make_test("
all: hello.tsk
%.tsk: %$s; \$(info hello.tsk)
%$s:$r %.c hello$s; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
", '-r', $result, $rcode);
}
}
for my $r (@rules) {
# Circular dependency hello.o <- hello.tsk is dropped.
run_make_test("
all: hello.tsk
%.tsk: %.o; \$(info hello.tsk)
%.o:$r %.c; \$(info hello.c)
%.o:$r %.f %.tsk; \$(info hello.f)
", '-r',
"#MAKE#: Circular hello.o <- hello.tsk dependency dropped.\nhello.f\nhello.tsk\n#MAKE#: Nothing to be done for 'all'.");
}
for my $s (@suffixes) {
for my $r (@rules) {
run_make_test("
all: hello.tsk
hello$s: hello.c
%.tsk: %$s; \$(info hello.tsk)
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
", '-r',
"#MAKE#: *** No rule to make target 'hello.c', needed by 'hello$s'. Stop.\n",
512);
}
}
for my $s (@suffixes) {
for my $r (@rules) {
my $result = "#MAKE#: *** No rule to make target 'hello.tsk', needed by 'all'. Stop.\n";
if ($s or $r) {
$result = "fail 1\n#MAKE#: *** [#MAKEFILE#:6: hello.c] Error 1\n";
}
run_make_test("
all: hello.tsk
%.tsk: %$s; \$(info hello.tsk)
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
hello.c:; @#HELPER# fail 1
", '-r', $result, 512);
}
}
for my $s (@suffixes) {
for my $r (@rules) {
run_make_test("
all: hello.tsk
%.tsk: %$s; \$(info hello.tsk)
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
unrelated: hello$s
", '-r', "hello.f\nhello.tsk\n#MAKE#: Nothing to be done for 'all'.");
}
}
for my $s (@suffixes) {
for my $r (@rules) {
my $result = "#MAKE#: *** No rule to make target 'hello.tsk', needed by 'all'. Stop.\n";
my $rcode = 512;
if ($s or $r) {
$result = "hello.f\nhello.tsk\n#MAKE#: Nothing to be done for 'all'.";
$rcode = 0;
}
run_make_test("
all: hello.tsk
%.tsk: %$s; \$(info hello.tsk)
%$s:$r %.c; \$(info hello.c)
%$s:$r %.f hello.f; \$(info hello.f)
", '-r', $result, $rcode);
}
}
# One of the implicit rules has two prerequisites, hello.c and hello.x
# hello.c does not qualify as ought to exit.
# hello.x can be made from hello.z.
# This test exersizes the break, which prevents making hello.x as an
# intermediate from hello.z during compatibility search.
unlink('hello.f');
touch('hello.z');
for my $s (@suffixes) {
for my $r (@rules) {
run_make_test("
all: hello.tsk
%.tsk: %$s; \$(info hello.tsk)
%$s:$r %.c %.x; \$(info hello.c)
%$s:$r %.f; \$(info hello.f)
unrelated: hello$s
%.x:$r %.z; \$(info hello.z)
", '-r',
"#MAKE#: *** No rule to make target 'hello$s', needed by 'hello.tsk'. Stop.\n",
512);
}
}
# Test that prerequisite 'hello.x' mentioned explicitly on an unrelated rule is
# not considered intermediate.
touch('hello.tsk');
unlink('hello.x');
run_make_test("
all: hello.tsk
%.tsk: %.x; touch hello.tsk
%.x: ;
unrelated: hello.x
", '-r', "touch hello.tsk\n");
unlink('hello.tsk');
touch ('hello.f');
# Test implicit search of builtin rules.
# %: %.c (and other builtin rules) are skipped.
# %: %.f is chosen.
run_make_test(q!
all: hello
!, 'FC="@echo f77" OUTPUT_OPTION=', "f77 hello.f -o hello\n");
# %.o: %.c (and other builtin rules) are skipped.
# %.o: %.f is chosen.
run_make_test(q!
all: hello.o
!, 'FC="@echo f77" OUTPUT_OPTION=', "f77 -c hello.f\n");
# %: %.c is chosen.
# hello.c is an explicit prerequisite of the top target hello.
# hello.c ought to exist.
# hello.c prerequisite causes '%: %.c' rule to be chosen.
run_make_test(q!
hello: hello.c
!, 'FC="@echo f77" OUTPUT_OPTION=',
"#MAKE#: *** No rule to make target 'hello.c', needed by 'hello'. Stop.\n",
512);
# %.o: %.c is chosen.
# hello.c is an explicit prerequisite of the top target hello.o.
# hello.c ought to exist.
# hello.c prerequisite causes '%.o: %.c' rule to be chosen.
run_make_test(q!
hello.o: hello.c
!, 'FC="@echo f77" OUTPUT_OPTION=',
"#MAKE#: *** No rule to make target 'hello.c', needed by 'hello.o'. Stop.\n",
512);
# %: %.c (and other builtin rules) are skipped.
# %: %.f is chosen.
# ought-to-exist does not apply to hello.c.
run_make_test(q!
all: hello
unrelated: hello.c
!, 'FC="@echo f77" OUTPUT_OPTION=', "f77 hello.f -o hello\n");
# %.o: %.c (and other builtin rules) are skipped.
# %.o: %.f is chosen.
# ought-to-exist does not apply to hello.c.
run_make_test(q!
all: hello.o
unrelated: hello.c
!, 'FC="@echo f77" OUTPUT_OPTION=', "f77 -c hello.f\n");
# builtin rule %.o: %.f is removed.
# %.o: %.c (and other builtin rules) are skipped, because hello.c is missing.
# ought-to-exist does not apply to hello.c.
# %.o: %.c is chosen as a compatibility rule, because of hello.c.
run_make_test(q!
all: hello.o
unrelated: hello.c
%.o: %.f
!, '',
"#MAKE#: *** No rule to make target 'hello.c', needed by 'hello.o'. Stop.\n",
512);
# sv 17752.
# In this test the builtin match-anything rule '%: %.f' is used to build
# intermediate hello from hello.f, because hello is mentioned explicitly in
# the makefile.
run_make_test(q!
all: hello.tsk
%.tsk: %; $(info $@ from $<)
unrelated: hello
!, 'FC="@echo f77" OUTPUT_OPTION=',
"f77 hello.f -o hello\nhello.tsk from hello\n");
# In this test the builtin match-anything rule %: %.f cannot be used to build
# intermediate hello from hello.f, because hello is not mentioned explicitly in
# the makefile.
run_make_test(q!
all: hello.tsk
%.tsk: %; $(info $@ from $<)
!, 'FC="@echo f77" OUTPUT_OPTION=',
"#MAKE#: *** No rule to make target 'hello.tsk', needed by 'all'. Stop.\n",
512);
# This is just like the one above, but compatibility rule '%.tsk: % %.x' has 2
# prerequisites, '%' and '%.x'.
# '%' expands to 'hello' and matches the explicit 'hello' on the unrelated rule.
# '%.x' is an intermediate built from 'hello.xx' by rule '%.x: %.xx' during the
# second pass (intermed_ok == 1) of compatibility search.
# This test validates that compatibility search performs both intermed_ok == 0
# and intermed_ok == 1 passes.
unlink('hello.x');
touch('hello.xx');
run_make_test(q!
all: hello.tsk
%.tsk: % %.x; $(info $@ from $^)
unrelated: hello
%.x: %.xx; $(info $@ from $<)
!, 'FC="@echo f77" OUTPUT_OPTION=',
"f77 hello.f -o hello\nhello.x from hello.xx\nhello.tsk from hello hello.x\n");
unlink('bye.o', 'bye.tsk', 'bye.x');
# sv 21670.
# Default recipe is used to build bye.o.
run_make_test(q!
all: bye.tsk
%.tsk: %.o; $(info $@ from $<)
.DEFAULT:; $(info bye.o)
unrelated: bye.o
!, '-r', "bye.o\nbye.tsk from bye.o\n#MAKE#: Nothing to be done for 'all'.");
touch('bye.xx');
# This is just like the one above, but compatibility rule '%.tsk: %.o %.x' has 2
# prerequisites, '%.o' and '%.x'.
# '%.o' expands to 'bye.o' and matches the explicit 'bye.o' on the unrelated rule.
# '%.x' is an intermediate built from 'bye.xx' by rule '%.x: %.xx' during the
# second pass (intermed_ok == 1) of compatibility search.
# This test validates that compatibility search performs both intermed_ok == 0
# and intermed_ok == 1 passes.
run_make_test(q!
all: bye.tsk
%.tsk: %.o %.x; $(info $@ from $^)
.DEFAULT:; $(info bye.o)
unrelated: bye.o
%.x: %.xx; $(info $@ from $<)
!, '-r',
"bye.o\nbye.x from bye.xx\nbye.tsk from bye.o bye.x\n#MAKE#: Nothing to be done for 'all'.");
unlink('hello.f', 'hello.z', 'hello.xx', 'bye.xx');
# A target specific variable causes the file to be entered to the database as a
# prerequisite. Implicit search then treats this file as explicitly mentioned.
# Test that implicit search keeps target specific variables of this file intact.
# In this series of tests prerequisite 'hello.x' has a target specific variable
# and is built as an intermediate. Implicit search treats 'hello.x' as
# explicitly mentioned, but 'hello.x' does not qualify as ought-to-exist.
unlink('hello.x', 'hello.tsk');
# 'hello.x' is mentioned explicitly on the same implicit rule.
run_make_test(q!
all: hello.tsk
%.tsk: hello.x; $(info $@)
%.x:; $(flags)
hello.x: flags:=true
!, '-r', "true\nhello.tsk\n");
# Similar to the one above, but this time 'hello.x' is derived from the stem.
run_make_test(q!
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x:; $(flags)
hello.x: flags:=true
!, '-r', "true\nhello.tsk\n");
# Similar to the one above, this time 'hello.x' is also mentioned explicitly on
# an unrelated rule.
run_make_test(q!
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x:; $(flags)
hello.x: flags:=true
unrelated: hello.x
!, '-r', "true\nhello.tsk\n");
# 'hello.x' has a pattern specific variable.
run_make_test(q!
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x:; $(flags)
%.x: flags:=true
!, '-r', "true\nhello.tsk\n");
# 'hello.x' has a target specific variable and a pattern specific variable.
run_make_test(q!
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x:; $(flags)
hello.x: flags+=good
%.x: flags:=true
!, '-r', "true good\nhello.tsk\n");
# Intermediate prerequisite 'hello.x' has a target specific variable, a pattern
# specfic variable, matches on both rules '%.tsk: %.x' and 'big_%.tsk: %.x'.
run_make_test(q!
all: hello.tsk big_hello.tsk
%.tsk: %.x; $(info $@)
big_%.tsk: %.x; $(info $@)
%.x:; $(flags)
hello.x: flags+=good
%.x: flags:=true
!, '-r', "true good\nhello.tsk\nbig_hello.tsk\n");
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,465 @@
# -*-mode: perl; rm-trailing-spaces: nil-*-
$description = "Test various forms of the GNU make 'include' command.";
$details = "\
Test include, -include, sinclude and various regressions involving them.
Test extra whitespace at the end of the include, multiple -includes and
sincludes (should not give an error) and make sure that errors are reported
for targets that were also -included.";
create_file('incl.mk', "ANOTHER: ; \@echo This is another included makefile\n");
run_make_test(qq!#Extra space at the end of the following file name
include incl.mk ! . q!
all: ; @echo There should be no errors for this makefile.
-include nonexistent.mk
-include nonexistent.mk
sinclude nonexistent.mk
sinclude nonexistent-2.mk
-include makeit.mk
sinclude makeit.mk
error: makeit.mk
!,
"all", "There should be no errors for this makefile.\n");
run_make_test(undef, "ANOTHER", "This is another included makefile\n");
unlink('incl.mk');
# Try to build the "error" target; this will fail since we don't know
# how to create makeit.mk, but we should also get a message (even though
# the -include suppressed it during the makefile read phase, we should
# see one during the makefile run phase).
run_make_test
('
-include foo.mk
error: foo.mk ; @echo $@
',
'',
"#MAKE#: *** No rule to make target 'foo.mk', needed by 'error'. Stop.\n",
512
);
# The same as above with an additional include directory.
mkdir('hellod', 0777);
run_make_test
('
-include foo.mk
error: foo.mk ; @echo $@
',
'-Ihellod',
"#MAKE#: *** No rule to make target 'foo.mk', needed by 'error'. Stop.\n",
512
);
rmdir('hellod');
# Make sure that target-specific variables don't impact things. This could
# happen because a file record is created when a target-specific variable is
# set.
run_make_test
('
bar.mk: foo := baz
-include bar.mk
hello: ; @echo hello
',
'',
"hello\n"
);
# Test inheritance of dontcare flag when rebuilding makefiles.
#
run_make_test('
.PHONY: all
all: ; @:
-include foo
foo: bar; @:
', '', '');
# Make sure that we don't die when the command fails but we dontcare.
# (Savannah bug #13216).
#
run_make_test('
.PHONY: all
all:; @:
-include foo
foo: bar; @:
bar:; @exit 1
', '', '');
# Check include, sinclude, -include with no filenames.
# (Savannah bug #1761).
run_make_test('
.PHONY: all
all:; @:
include
-include
sinclude', '', '');
# Test that the diagnostics is issued even if the target has been
# tried before with the dontcare flag (direct dependency case).
#
run_make_test('
-include foo
all: bar
foo: baz
bar: baz
',
'',
"#MAKE#: *** No rule to make target 'baz', needed by 'bar'. Stop.\n",
512);
# Test that the diagnostics is issued even if the target has been
# tried before with the dontcare flag (indirect dependency case).
#
run_make_test('
-include foo
all: bar
foo: baz
bar: baz
baz: end
',
'',
"#MAKE#: *** No rule to make target 'end', needed by 'baz'. Stop.\n",
512);
# Test include of make-able file doesn't show an error (Savannah #102)
run_make_test(q!
.PHONY: default
default:; @echo DONE
inc1:; echo > $@
include inc1
include inc2
inc2:; echo > $@
!,
'', "echo > inc1\necho > inc2\nDONE\n");
rmfiles('inc1', 'inc2');
# Test include of make-able file doesn't show an error.
# Specify an additional include directory.
mkdir('hellod', 0777);
run_make_test(q!
.PHONY: default
default:; @echo DONE
inc1:; echo > $@
include inc1
include inc2
inc2:; echo > $@
!,
'-Ihellod', "echo > inc1\necho > inc2\nDONE\n");
rmfiles('inc1', 'inc2');
# Test include of make-able file doesn't show an error.
# inc1 and inc2 are present in the specified include directory.
touch('hellod/inc1');
touch('hellod/inc2');
run_make_test(q!
.PHONY: default
default:; @echo DONE
inc1:; echo > $@
include inc1
include inc2
inc2:; echo > $@
!,
'-Ihellod', "DONE\n");
rmfiles('inc1', 'inc2', 'hellod/inc1', 'hellod/inc2');
rmdir('hellod');
# No target gets correct error
run_make_test("\n", '', '#MAKE#: *** No targets. Stop.', 512);
# No target in included file either, still gets correct error.
touch('inc1.mk');
run_make_test('include inc1.mk', '', '#MAKE#: *** No targets. Stop.', 512);
rmfiles('inc1.mk');
# Include same file multiple times
run_make_test(q!
default:; @echo DEFAULT
include inc1
inc1:; echo > $@
include inc1
!,
'', "echo > inc1\nDEFAULT\n");
rmfiles('inc1');
if (defined $ERR_no_such_file) {
# Test that the diagnostics is issued even if the target has been
# tried before with the dontcare flag (include/-include case).
#
run_make_test('
include bar
-include foo
all:
foo: baz
bar: baz
baz: end
',
'',
"#MAKEFILE#:2: bar: $ERR_no_such_file\n#MAKE#: *** No rule to make target 'end', needed by 'baz'. Stop.\n",
512);
# Test include of non-make-able file does show an error (Savannah #102)
run_make_test(q!
.PHONY: default
default:; @echo DONE
inc1:; echo > $@
include inc1
include inc2
!,
'', "echo > inc1\n#MAKEFILE#:7: inc2: $ERR_no_such_file\n#MAKE#: *** No rule to make target 'inc2'. Stop.\n", 512);
rmfiles('inc1');
# Included file has a prerequisite that fails to build
run_make_test(q!
default:; @echo DEFAULT
include inc1
inc1: foo; echo > $@
foo:; exit 1
!,
'', "exit 1\n#MAKEFILE#:3: inc1: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:5: foo] Error 1\n", 512);
rmfiles('inc1');
# Included file has a prerequisite we don't know how to build
run_make_test(q!
default:; @echo DEFAULT
include inc1
inc1: foo; echo > $@
!,
'', "#MAKEFILE#:3: inc1: $ERR_no_such_file\n#MAKE#: *** No rule to make target 'foo', needed by 'inc1'. Stop.\n", 512);
rmfiles('inc1');
# Check that included double-colon targets with no prerequisites aren't
# built. This should fail as hello.mk doesn't exist
run_make_test(q!
.PHONY: default
default:;@echo 'FOO=$(FOO)'
include hello.mk
hello.mk:: ; echo 'FOO=bar' > $@
!,
'', "#MAKEFILE#:4: hello.mk: $ERR_no_such_file", 512);
# Check that included phony targets aren't built.
# This should fail as hello.mk doesn't exist
run_make_test(q!
.PHONY: default
default:;@echo 'FOO=$(FOO)'
include hello.mk
hello.mk: ; echo 'FOO=bar' > $@
.PHONY: hello.mk
!,
'', "#MAKEFILE#:4: hello.mk: $ERR_no_such_file", 512);
}
if (defined $ERR_unreadable_file) {
# Including files that can't be read should show an error
unlink('inc1');
create_file('inc1', 'FOO := foo');
chmod 0000, 'inc1';
run_make_test(q!
include inc1
all:;@echo $(FOO)
!,
'', "#MAKEFILE#:2: inc1: $ERR_unreadable_file\n#MAKE#: *** No rule to make target 'inc1'. Stop.", 512);
# Including files that can't be read should show an error, even when there
# is a readable file in a subsequent include directory.
mkdir('hellod', 0777);
touch("hellod/inc1");
run_make_test(q!
include inc1
all:;@echo $(FOO)
!,
'-Ihellod', "#MAKEFILE#:2: inc1: $ERR_unreadable_file\n#MAKE#: *** No rule to make target 'inc1'. Stop.", 512);
# Unreadable files that we know how to successfully recreate should work
run_make_test(sprintf(q!
all:;@echo $(FOO)
include inc1
inc1:; @%s $@ && echo FOO := bar > $@
!, $CMD_rmfile),
'', "bar");
# Unreadable files that we know how to successfully recreate should work.
# Even when there is a readable file in an additional include directory.
unlink('inc1');
create_file('inc1', 'FOO := foo');
chmod 0000, 'inc1';
run_make_test(sprintf(q!
all:;@echo $(FOO)
include inc1
inc1:; @%s $@ && echo FOO := bar > $@
!, $CMD_rmfile),
'-Ihellod', "bar");
rmfiles('inc1', 'hellod/inc1');
rmdir('hellod');
}
# Check that the order of remaking include files is correct: should remake
# them in the same order they were encountered in the makefile. SV 58735
run_make_test(q!
-include i1 i2
-include i3
-include i4
%:;@echo $@
all:;
!,
'', "i1\ni2\ni3\ni4\n#MAKE#: 'all' is up to date.\n");
# Check that included files work if created after the first include failed
# https://savannah.gnu.org/bugs/?57676
run_make_test(q!
default:; @echo $(hello)
-include hello.mk
$(shell echo hello=world >hello.mk)
include hello.mk
!,
'', "world\n");
unlink('hello.mk');
# Check that included double-colon targets with no prerequisites aren't built.
# This should succeed since hello.mk already exists
touch('hello.mk');
run_make_test(q!
.PHONY: default
default:;@echo 'FOO=$(FOO)'
include hello.mk
hello.mk:: ; echo 'FOO=bar' > $@
!,
'', 'FOO=');
unlink('hello.mk');
# Check that included double-colon targets with no prerequisites aren't built.
# This should succeed due to -include
run_make_test(q!
.PHONY: default
default:;@echo 'FOO=$(FOO)'
-include hello.mk
hello.mk:: ; echo 'FOO=bar' > $@
!,
'', 'FOO=');
# Check that phony targets aren't built.
# This should succeed since hello.mk already exists
touch('hello.mk');
run_make_test(q!
.PHONY: default
default:;@echo 'FOO=$(FOO)'
include hello.mk
hello.mk: ; echo 'FOO=bar' > $@
.PHONY: hello.mk
!,
'', 'FOO=');
unlink('hello.mk');
# Check that included double-colon targets with no prerequisites aren't built.
# This should succeed due to -include
run_make_test(q!
.PHONY: default
default:;@echo 'FOO=$(FOO)'
-include hello.mk
hello.mk: ; echo 'FOO=bar' > $@
.PHONY: hello.mk
!,
'', 'FOO=');
# SV 56301 Verify pattern rules creating optional includes.
# -k shouldn't matter when creating include files.
run_make_test(q!
all:; @echo hello
-include inc_a.mk
include inc_b.mk
%_a.mk %_b.mk:; exit 1
!,
'', "exit 1\n#MAKEFILE#:4: Failed to remake makefile 'inc_b.mk'.\n", 512);
run_make_test(undef, '-k', "exit 1\n#MAKEFILE#:4: Failed to remake makefile 'inc_b.mk'.\n", 512);
# It seems wrong to me that this gives a different error message, but at
# least it doesn't keep going.
run_make_test(q!
all:; @echo hello
include inc_a.mk
-include inc_b.mk
%_a.mk %_b.mk:; exit 1
!,
'', "exit 1\n#MAKEFILE#:3: inc_a.mk: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:5: inc_a.mk] Error 1\n", 512);
run_make_test(undef, '-k', "exit 1\n#MAKEFILE#:3: inc_a.mk: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:5: inc_a.mk] Error 1\n#MAKEFILE#:3: Failed to remake makefile 'inc_a.mk'.\n", 512);
# Check the default makefiles... this requires us to invoke make with no
# arguments. Also check MAKEFILES
if ($port_type eq 'W32') {
$defaults = "GNUmakefile\nmakefile\nMakefile\nmakefile.mak";
} else {
$defaults = "GNUmakefile\nmakefile\nMakefile";
}
$ENV{MAKEFILES} = 'foobar barfoo';
run_make_with_options(undef, ['-E', '%:;@echo $@', '-E', 'all:;', '-E', '-include bizbaz', '-E', '-include bazbiz'], get_logfile(0));
$answer = "bizbaz\nbazbiz\nfoobar\nbarfoo\n$defaults\n#MAKE#: 'all' is up to date.\n";
&compare_output(subst_make_string($answer), &get_logfile(1));
1;
@@ -0,0 +1,160 @@
# -*-perl-*-
$description = "Test jobserver.";
$details = "These tests are ones that specifically are different when the
jobserver feature is available. Most -j tests are the same whether or not
jobserver is available, and those appear in the 'parallelism' test suite.";
exists $FEATURES{'jobserver'} or return -1;
if (!$parallel_jobs) {
return -1;
}
# Shorthand
my $np = '--no-print-directory';
# Simple test of MAKEFLAGS settings
run_make_test(q!
SHOW = $(patsubst --jobserver-auth=%,--jobserver-auth=<auth>,$(MAKEFLAGS))
recurse: ; @echo $@: "/$(SHOW)/"; $(MAKE) -f #MAKEFILE# all
all:;@echo $@: "/$(SHOW)/"
!,
"-j2 $np", "recurse: /-j2 --jobserver-auth=<auth> $np/\nall: /-j2 --jobserver-auth=<auth> $np/\n");
# Setting parallelism with the environment
# Command line should take precedence over the environment
$ENV{MAKEFLAGS} = "-j2 $np";
run_make_test(q!
SHOW = $(patsubst --jobserver-auth=%,--jobserver-auth=<auth>,$(MAKEFLAGS))
recurse: ; @echo $@: "/$(SHOW)/"; $(MAKE) -f #MAKEFILE# all
all:;@echo $@: "/$(SHOW)/"
!,
'', "recurse: /-j2 --jobserver-auth=<auth> $np/\nall: /-j2 --jobserver-auth=<auth> $np/\n");
# Test override of -jN
$ENV{MAKEFLAGS} = "-j9 $np";
run_make_test(q!
SHOW = $(patsubst --jobserver-auth=%,--jobserver-auth=<auth>,$(MAKEFLAGS))
recurse: ; @echo $@: "/$(SHOW)/"; $(MAKE) -j3 -f #MAKEFILE# recurse2
recurse2: ; @echo $@: "/$(SHOW)/"; $(MAKE) -f #MAKEFILE# all
all:;@echo $@: "/$(SHOW)/"
!,
"-j2 $np", "recurse: /-j2 --jobserver-auth=<auth> $np/\n#MAKE#[1]: warning: -j3 forced in submake: resetting jobserver mode.\nrecurse2: /-j3 --jobserver-auth=<auth> $np/\nall: /-j3 --jobserver-auth=<auth> $np/\n");
# Test override of -jN with -j
run_make_test(q!
SHOW = $(patsubst --jobserver-auth=%,--jobserver-auth=<auth>,$(MAKEFLAGS))
recurse: ; @echo $@: "/$(SHOW)/"; $(MAKE) -j -f #MAKEFILE# recurse2
recurse2: ; @echo $@: "/$(SHOW)/"; $(MAKE) -f #MAKEFILE# all
all:;@echo $@: "/$(SHOW)/"
!,
"-j2 $np", "recurse: /-j2 --jobserver-auth=<auth> $np/\n#MAKE#[1]: warning: -j0 forced in submake: resetting jobserver mode.\nrecurse2: /-j $np/\nall: /-j $np/\n");
# Don't put --jobserver-auth into a re-exec'd MAKEFLAGS.
# We can't test this directly because there's no way a makefile can
# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it
# by looking for "disabling jobserver mode" warnings; we should only
# get one from the original invocation and none from the re-exec.
# See Savannah bug #18124
unlink('inc.mk');
run_make_test(q!
.RECIPEPREFIX = >
-include inc.mk
recur:
#> @echo 'MAKEFLAGS = $(MAKEFLAGS)'
> @rm -f inc.mk
> @$(MAKE) -j2 -f #MAKEFILE# all
all:
#> @echo 'MAKEFLAGS = $(MAKEFLAGS)'
> @echo $@
inc.mk:
#> @echo 'MAKEFLAGS = $(MAKEFLAGS)'
> @echo 'FOO = bar' > $@
!,
"$np -j2", "#MAKE#[1]: warning: -j2 forced in submake: resetting jobserver mode.\nall\n");
unlink('inc.mk');
# Test recursion which is hidden from make.
# See Savannah bug #39934
# Or Red Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=885474
# Environments that don't use a pipe won't close access, so this won't happen.
if ($port_type ne 'W32') {
create_file('Makefile2', "vpath %.c ../\n", "foo:\n");
run_make_test(q!
default: ; @ #MAKEPATH# -f Makefile2
!,
"--jobserver-style=pipe -j2 $np",
"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
#MAKE#[1]: Nothing to be done for 'foo'.");
rmfiles('Makefile2');
}
# For Windows and named pipes, we don't need to worry about recursion
if ($port_type eq 'W32' || exists $FEATURES{'jobserver-fifo'}) {
create_file('Makefile2', "vpath %.c ../\n", "foo:\n");
run_make_test(q!
default: ; @ #MAKEPATH# -f Makefile2
!,
"-j2 $np",
"#MAKE#[1]: Nothing to be done for 'foo'.");
rmfiles('Makefile2');
}
# Ensure enter/leave directory messages appear before jobserver warnings
run_make_test(q!
all: ; @$(MAKE) -C . -f #MAKEFILE# recurse -j1
recurse: ; @echo hi
!,
'-w -j2', "#MAKE#: Entering directory '#PWD#'
#MAKE#[1]: Entering directory '#PWD#'
#MAKE#[1]: warning: -j1 forced in submake: resetting jobserver mode.
hi
#MAKE#[1]: Leaving directory '#PWD#'
#MAKE#: Leaving directory '#PWD#'\n");
# Check for invalid jobserver-style options
run_make_test(q!
all: a
all a: ; @echo $@
!,
'--jobserver-style=foo -j8',
"#MAKE#: *** Unknown jobserver auth style 'foo'. Stop.", 512);
# sv 62908.
# Test that when mkfifo fails, make switches to pipe and succeeds.
# Force mkfifo to fail by attempting to create a fifo in a non existent
# directory.
# run_make_test does not allow matching a multiline pattern, therefore run the
# test twice.
# First time look for /$ERR_no_such_file/ to ensure mkfifo failed.
# Second time look for /Nothing to be done/ to ensure make succeeded.
if (exists $FEATURES{'jobserver-fifo'}) {
$ENV{TMPDIR} = "nosuchdir";
run_make_test("all:\n", '-j2', "/$ERR_no_such_file/");
$ENV{TMPDIR} = "nosuchdir";
run_make_test(undef, '-j2', "/Nothing to be done/");
# Verify that MAKE_TMPDIR is preferred if provided
$ENV{MAKE_TMPDIR} = '.';
$ENV{TMPDIR} = 'nosuchdir';
run_make_test(q!
recurse: ; @$(MAKE) -f #MAKEFILE# all
all:;@echo "$$MAKEFLAGS"
!,
"-j2 --no-print-directory", "/--jobserver-auth=fifo:\\./");
}
1;
@@ -0,0 +1,150 @@
# -*-perl-*-
$description = "Test the load operator.";
$details = "Test dynamic loading of modules.";
# Don't do anything if this system doesn't support "load"
exists $FEATURES{'load'} or return -1;
my $cc = get_config('CC');
if (! $cc) {
$verbose and print "Skipping load test: no CC defined\n";
return -1;
}
# First build a shared object
# Provide both a default and non-default load symbol
unlink(qw(testload.c testload.so));
open(my $F, '> testload.c') or die "open: testload.c: $!\n";
print $F <<'EOF' ;
#include "gnumake.h"
char* getenv (const char*);
int plugin_is_GPL_compatible;
int testload_gmk_setup (gmk_floc *);
int explicit_setup (gmk_floc *);
int
testload_gmk_setup (gmk_floc *pos)
{
(void)pos;
gmk_eval ("TESTLOAD = implicit", 0);
if (getenv("TESTAPI_KEEP"))
return -1;
return 1;
}
int
explicit_setup (gmk_floc *pos)
{
(void)pos;
gmk_eval ("TESTLOAD = explicit", 0);
if (getenv("TESTAPI_KEEP"))
return -1;
return 1;
}
EOF
close($F) or die "close: testload.c: $!\n";
# Make sure we can compile
my $cppflags = get_config('CPPFLAGS') . ($srcdir ? " -I$srcdir/src" : '');
my $cflags = get_config('CFLAGS') . ' -fPIC';
my $ldflags = get_config('LDFLAGS') . ' -shared';
my $sobuild = "$cc $cppflags $cflags $ldflags -o testload.so testload.c";
my $clog = `$sobuild 2>&1`;
if ($? != 0) {
$verbose and print "Failed to build testload.so:\n$sobuild\n$clog";
return -1;
}
# TEST 1
run_make_test(q!
PRE := $(.LOADED)
load testload.so
POST := $(.LOADED)
all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
!,
'--warn-undefined-variables', "pre= post=testload.so implicit\n");
# TEST 2
# Load using an explicit function
run_make_test(q!
PRE := $(.LOADED)
load ./testload.so(explicit_setup)
POST := $(.LOADED)
all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
!,
'', "pre= post=testload.so explicit\n");
# TEST 3
# Check multiple loads
run_make_test(q!
PRE := $(.LOADED)
load ./testload.so
load testload.so(explicit_setup)
POST := $(.LOADED)
all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
!,
'', "pre= post=testload.so implicit\n");
# TEST 4
# Check auto-rebuild of loaded file that's out of date
utouch(-10, 'testload.so');
touch('testload.c');
run_make_test(q!
PRE := $(.LOADED)
load ./testload.so
POST := $(.LOADED)
all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
testload.so: testload.c ; @echo "rebuilding $@"; !.$sobuild,
'', "rebuilding testload.so\npre= post=testload.so implicit\n");
# TEST 5
# Check auto-rebuild of loaded file when it doesn't exist
unlink('testload.so');
run_make_test(q!
PRE := $(.LOADED)
-load ./testload.so(explicit_setup)
POST := $(.LOADED)
all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
%.so: %.c ; @echo "rebuilding $@"; !.$sobuild,
'', "rebuilding testload.so\npre= post=testload.so explicit\n");
# sv 63044.
# Test that the loaded shared object is present in .LOADED when the setup
# routine returns -1.
$ENV{TESTAPI_KEEP} = 1;
run_make_test(q!
PRE := $(.LOADED)
load testload.so
POST := $(.LOADED)
all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
!,
'--warn-undefined-variables', "pre= post=testload.so implicit\n");
# Check that we don't auto-rebuild of loaded file that's out of date
# if we return -1 from the setup
utouch(-10, 'testload.so');
touch('testload.c');
$ENV{TESTAPI_KEEP} = 1;
run_make_test(q!
PRE := $(.LOADED)
load ./testload.so
POST := $(.LOADED)
all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
testload.so: testload.c ; @echo "rebuilding $@"; !.$sobuild,
'', "pre= post=testload.so implicit\n");
unlink(qw(testload.c testload.so)) unless $keep;
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,228 @@
# -*-perl-*-
$description = "Test the shared object load API.";
$details = "Verify the different aspects of the shared object API.";
# Don't do anything if this system doesn't support "load"
exists $FEATURES{load} or return -1;
my $cc = get_config('CC');
if (! $cc) {
$verbose and print "Skipping load test: no CC defined\n";
return -1;
}
# First build a shared object
# Provide both a default and non-default load symbol
unlink(qw(testapi.c testapi.so));
open(my $F, '> testapi.c') or die "open: testapi.c: $!\n";
print $F <<'EOF' ;
#include <string.h>
#include <stdio.h>
#include "gnumake.h"
char *getenv (const char*);
int plugin_is_GPL_compatible;
int testapi_gmk_setup ();
static char *
test_eval (const char *buf)
{
gmk_eval (buf, 0);
return NULL;
}
static char *
test_expand (const char *val)
{
return gmk_expand (val);
}
static char *
test_noexpand (const char *val)
{
char *str = gmk_alloc (strlen (val) + 1);
strcpy (str, val);
return str;
}
static char *
func_test (const char *funcname, unsigned int argc, char **argv)
{
char *mem;
if (strcmp (funcname, "test-expand") == 0)
return test_expand (argv[0]);
if (strcmp (funcname, "test-eval") == 0)
return test_eval (argv[0]);
if (strcmp (funcname, "test-noexpand") == 0)
return test_noexpand (argv[0]);
mem = gmk_alloc (sizeof ("unknown"));
strcpy (mem, "unknown");
return mem;
}
int
testapi_gmk_setup (const gmk_floc *floc)
{
const char *verbose = getenv ("TESTAPI_VERBOSE");
gmk_add_function ("test-expand", func_test, 1, 1, GMK_FUNC_DEFAULT);
gmk_add_function ("test-noexpand", func_test, 1, 1, GMK_FUNC_NOEXPAND);
gmk_add_function ("test-eval", func_test, 1, 1, GMK_FUNC_DEFAULT);
gmk_add_function ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.", func_test, 0, 0, 0);
if (verbose)
{
printf ("testapi_gmk_setup\n");
if (verbose[0] == '2')
printf ("%s:%lu\n", floc->filenm, floc->lineno);
}
if (getenv ("TESTAPI_KEEP"))
return -1;
return 1;
}
EOF
close($F) or die "close: testapi.c: $!\n";
# Make sure we can compile
my $cflags = get_config('CFLAGS');
my $cppflags = get_config('CPPFLAGS');
my $ldflags = get_config('LDFLAGS');
my $sobuild = "$cc ".($srcdir? "-I$srcdir/src":'')." $cppflags $cflags -shared -fPIC $ldflags -o testapi.so testapi.c";
my $clog = `$sobuild 2>&1`;
if ($? != 0) {
$verbose and print "Failed to build testapi.so:\n$sobuild\n$_";
return -1;
}
# TEST 1
# Check the gmk_expand() function
run_make_test(q!
EXPAND = expansion
all: ; @echo $(test-expand $$(EXPAND))
load testapi.so
!,
'', "expansion\n");
# TEST 2
# Check the eval operation. Prove that the argument is expanded only once
run_make_test(q!
load testapi.so
TEST = bye
ASSIGN = VAR = $(TEST) $(shell echo there)
$(test-eval $(value ASSIGN))
TEST = hi
all:;@echo '$(VAR)'
!,
'', "hi there\n");
# TEST 2
# Check the no-expand capability
run_make_test(q!
load testapi.so
TEST = hi
all:;@echo '$(test-noexpand $(TEST))'
!,
'', "\$(TEST)\n");
# During all subsequent tests testapi.so exists.
#
my @loads = ('', q!
load testapi.so
load testapi.so
-load testapi.so
-load testapi.so
$(eval load testapi.so)
$(eval -load testapi.so)
!);
for my $extra_loads (@loads) {
my $n = 5;
if ($extra_loads) {
$n = 12;
}
# sv 63045.
# Test that having unloaded a shared object make loads it again, even if the
# shared object is not updated.
$ENV{TESTAPI_VERBOSE} = 1;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; \$(info \$@)
force:;
.PHONY: force
", '', "testapi_gmk_setup\ntestapi.so\ntestapi_gmk_setup\nhello\n#MAKE#: 'all' is up to date.\n");
# sv 63045.
# Same as above, but testapi_gmk_setup returned -1.
$ENV{TESTAPI_KEEP} = 1;
$ENV{TESTAPI_VERBOSE} = 1;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; \$(info \$@)
force:;
.PHONY: force
", '', "testapi_gmk_setup\nhello\n#MAKE#: 'all' is up to date.\n");
# sv 63045.
# Test that make exits, unless make can successfully update an unloaded shared
# object.
$ENV{TESTAPI_VERBOSE} = 1;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; @#HELPER# fail 1
force:;
.PHONY: force
", '', "testapi_gmk_setup\nfail 1\n#MAKE#: *** [#MAKEFILE#:$n: testapi.so] Error 1\n", 512);
# sv 63045.
# Same as above, but testapi_gmk_setup returned -1.
$ENV{TESTAPI_KEEP} = 1;
$ENV{TESTAPI_VERBOSE} = 1;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; @#HELPER# fail 1
force:;
.PHONY: force
", '', "testapi_gmk_setup\nhello\n#MAKE#: 'all' is up to date.\n");
# sv 63100.
# Test that make supplies the correct floc when the shared object is loaded
# again.
$ENV{TESTAPI_VERBOSE} = 2;
run_make_test("
load testapi.so
$extra_loads
all:; \$(info \$(test-expand hello))
testapi.so: force; \$(info \$@)
force:;
.PHONY: force
", '', "testapi_gmk_setup\n#MAKEFILE#:2\ntestapi.so\ntestapi_gmk_setup\n#MAKEFILE#:2\nhello\n#MAKE#: 'all' is up to date.\n");
}
unlink(qw(testapi.c testapi.so)) unless $keep;
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,88 @@
$description = "\
The following test creates a makefile to test the presence
of multiple rules for one target. One file can be the
target of several rules if at most one rule has commands;
the other rules can only have dependencies.";
$details = "\
The makefile created in this test contains two hardcoded rules
for foo.o and bar.o. It then gives another multiple target rule
with the same names as above but adding more dependencies.
Additionally, another variable extradeps is listed as a
dependency but is defined to be null. It can however be defined
on the make command line as extradeps=extra.h which adds yet
another dependency to the targets.";
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE <<EOF;
objects = foo.o bar.o
foo.o : defs.h
bar.o : defs.h test.h
extradeps =
\$(objects) : config.h \$(extradeps)
\t\@echo EXTRA EXTRA
EOF
# END of Contents of MAKEFILE
close(MAKEFILE);
&touch("defs.h","test.h","config.h");
if ($vos)
{
$error_code = 3307;
}
else
{
$error_code = 512;
}
&run_make_with_options($makefile,
"extradeps=extra.h",
&get_logfile,
$error_code);
# Create the answer to what should be produced by this Makefile
$answer = "$make_name: *** No rule to make target 'extra.h', needed by 'foo.o'. Stop.\n";
&compare_output($answer,&get_logfile(1));
# TEST #2
# -------
&touch("extra.h");
&run_make_with_options($makefile,
"extradeps=extra.h",
&get_logfile,
0);
# Create the answer to what should be produced by this Makefile
$answer = "EXTRA EXTRA\n";
&compare_output($answer,&get_logfile(1));
unlink("defs.h","test.h","config.h","extra.h");
# sv 62650.
# Test the message that make prints when a file found by directory search
# is preferred over the local one.
run_make_test(q!
vpath hello.c src
all: hello.c; $(info $@ from $^)
hello.c: ; $(info 1 $@)
src/hello.c: ; $(info 2 $@)
!, '',
"#MAKEFILE#:4: Recipe was specified for file 'hello.c' at #MAKEFILE#:4,
#MAKEFILE#:4: but 'hello.c' is now considered the same file as 'src/hello.c'.
#MAKEFILE#:4: Recipe for 'hello.c' will be ignored in favor of the one for 'src/hello.c'.
2 src/hello.c
all from src/hello.c
#MAKE#: 'all' is up to date.\n");
1;
@@ -0,0 +1,46 @@
$description = "The following test creates a makefile to test that a \n "
."rule with multiple targets is equivalent to writing \n"
."many rules, each with one target, and all identical aside\n"
."from that.";
$details = "A makefile is created with one rule and two targets. Make \n"
."is called twice, once for each target, and the output which \n"
."contains the target name with \$@ is looked at for the changes.\n"
."This test also tests the substitute function by replacing \n"
."the word output with nothing in the target name giving either\n"
."an output of \"I am little\" or \"I am big\"";
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "bigoutput littleoutput: test.h\n";
print MAKEFILE "\t\@echo I am \$(subst output,,\$@)\n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&touch("test.h");
&run_make_with_options($makefile,"bigoutput",&get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = "I am big\n";
&compare_output($answer,&get_logfile(1));
&run_make_with_options($makefile,"littleoutput",&get_logfile);
$answer = "I am little\n";
&compare_output($answer,&get_logfile(1));
unlink "test.h";
1;
@@ -0,0 +1,118 @@
# -*-perl-*-
$description = "Test order-only prerequisites.";
$details = "\
Create makefiles with various combinations of normal and order-only
prerequisites and ensure they behave properly. Test the \$| variable.";
# TEST #0 -- Basics
run_make_test('
%r: | baz ; @echo $< $^ $|
bar: foo
foo:;@:
baz:;@:',
'', "foo foo baz\n");
# TEST #1 -- First try: the order-only prereqs need to be built.
run_make_test(q!
foo: bar | baz
@echo '$$^ = $^'
@echo '$$| = $|'
touch $@
.PHONY: baz
bar baz:
touch $@!,
'', "touch bar\ntouch baz\n\$^ = bar\n\$| = baz\ntouch foo\n");
# TEST #2 -- now we do it again: baz is PHONY but foo should _NOT_ be updated
run_make_test(undef, '', "touch baz\n");
unlink(qw(foo bar baz));
# TEST #3 -- Make sure the order-only prereq was promoted to normal.
run_make_test(q!
foo: bar | baz
@echo '$$^ = $^'
@echo '$$| = $|'
touch $@
foo: baz
.PHONY: baz
bar baz:
touch $@!,
'', "touch bar\ntouch baz\n\$^ = bar baz\n\$| = \ntouch foo\n");
# TEST #4 -- now we do it again
run_make_test(undef, '', "touch baz\n\$^ = bar baz\n\$| = \ntouch foo\n");
unlink(qw(foo bar baz));
# Test empty normal prereqs
# TEST #5 -- make sure the parser was correct.
run_make_test(q!
foo:| baz
@echo '$$^ = $^'
@echo '$$| = $|'
touch $@
.PHONY: baz
baz:
touch $@!,
'', "touch baz\n\$^ = \n\$| = baz\ntouch foo\n");
# TEST #6 -- now we do it again: this time foo won't be built
run_make_test(undef, '', "touch baz\n");
unlink(qw(foo baz));
# Test order-only in pattern rules
# TEST #7 -- make sure the parser was correct.
run_make_test(q!
%.w : %.x | baz
@echo '$$^ = $^'
@echo '$$| = $|'
touch $@
all: foo.w
.PHONY: baz
foo.x baz:
touch $@!,
'',
"touch foo.x\ntouch baz\n\$^ = foo.x\n\$| = baz\ntouch foo.w\n");
# TEST #8 -- now we do it again: this time foo.w won't be built
run_make_test(undef, '', "touch baz\n");
unlink(qw(foo.w foo.x baz));
# TEST #9 -- make sure that $< is set correctly in the face of order-only
# prerequisites in pattern rules.
run_make_test('
%r: | baz ; @echo $< $^ $|
bar: foo
foo:;@:
baz:;@:',
'', "foo foo baz\n");
1;
@@ -0,0 +1,371 @@
# -*-perl-*-
$description = "Test --output-sync (-O) option.";
$details = "Test the synchronization of output from parallel jobs.";
# If we don't have output sync support, never mind.
exists $FEATURES{'output-sync'} or return -1;
# Output sync can't be tested without parallelization
$parallel_jobs or return -1;
# The following subdirectories with Makefiles are used in several
# of the following tests. The model is:
# foo/Makefile - has a "foo" target that waits for the bar target
# bar/Makefile - has a "bar" target that runs immediately
# - has a "baz" target that waits for the foo target
#
# So, you start the two sub-makes in parallel and first the "bar" target is
# built, followed by "foo", followed by "baz". The trick is that first each
# target prints a "start" statement, then waits (if appropriate), then prints
# an end statement. Thus we can tell if the -O flag is working, since
# otherwise these statements would be mixed together.
@syncfiles = ();
sub output_sync_clean {
rmfiles('foo/Makefile', 'bar/Makefile', @syncfiles);
rmdir('foo');
rmdir('bar');
}
# We synchronize the different jobs by having them wait for a sentinel file to
# be created, instead of relying on a certain amount of time passing.
# Unfortunately in this test we have to sleep after we see the sync file,
# since we also want to make the obtaining of the write synchronization lock
# reliable. If things are too fast, then sometimes a different job will steal
# the output sync lock and the output is mis-ordered from what we expect.
sub output_sync_wait {
return subst_make_string("#HELPER# -q wait ../mksync.$_[0] sleep 1");
}
sub output_sync_set {
return subst_make_string("#HELPER# -q file ../mksync.$_[0]");
}
@syncfiles = qw(mksync.foo mksync.foo_start mksync.bar mksync.bar_start);
$tmout = 30;
output_sync_clean();
mkdir('foo', 0777);
mkdir('bar', 0777);
$set_foo = output_sync_set('foo');
$set_bar = output_sync_set('bar');
$set_foo_start = output_sync_set('foo_start');
$set_bar_start = output_sync_set('bar_start');
$wait_foo = output_sync_wait('foo');
$wait_bar = output_sync_wait('bar');
$wait_foo_start = output_sync_set('foo_start');
$wait_bar_start = output_sync_set('bar_start');
open(MAKEFILE,"> foo/Makefile");
print MAKEFILE <<EOF;
all: foo
foo: foo-base ; \@$set_foo
foo-base:
\t\@echo foo: start
\t\@$wait_bar
\t\@echo foo: end
foo-job: foo-job-base ; \@$set_foo
foo-job-base:
\t\@$wait_bar_start
\t\@echo foo: start
\t\@$set_foo_start
\t\@$wait_bar
\t\@echo foo: end
foo-fail:
\t\@echo foo-fail: start
\t\@$wait_bar
\t\@echo foo-fail: end
\t\@exit 1
EOF
close(MAKEFILE);
open(MAKEFILE,"> bar/Makefile");
print MAKEFILE <<EOF;
all: bar baz
bar: bar-base ; \@$set_bar
bar-base:
\t\@echo bar: start
\t\@echo bar: end
bar-job: bar-job-base ; \@$set_bar
bar-job-base:
\t\@echo bar: start
\t\@$set_bar_start
\t\@$wait_foo_start
\t\@echo bar: end
baz: baz-base
baz-base:
\t\@echo baz: start
\t\@$wait_foo
\t\@echo baz: end
EOF
close(MAKEFILE);
# Test per-make synchronization.
# Note we have to sleep again here after starting the foo makefile before
# starting the bar makefile, otherwise the "entering/leaving" messages for the
# submakes might be ordered differently than we expect.
unlink(@syncfiles);
run_make_test(qq!
all: make-foo make-bar
make-foo: ; \$(MAKE) -C foo
make-bar: ; #HELPER# -q sleep 1 ; \$(MAKE) -C bar!,
'-j -Orecurse',
"#MAKEPATH# -C foo
#MAKE#[1]: Entering directory '#PWD#/foo'
foo: start
foo: end
#MAKE#[1]: Leaving directory '#PWD#/foo'
#HELPER# -q sleep 1 ; #MAKEPATH# -C bar
#MAKE#[1]: Entering directory '#PWD#/bar'
bar: start
bar: end
baz: start
baz: end
#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, $tmout);
# Test per-target synchronization.
# Note we have to sleep again here after starting the foo makefile before
# starting the bar makefile, otherwise the "entering/leaving" messages for the
# submakes might be ordered differently than we expect.
unlink(@syncfiles);
run_make_test(qq!
x=1
\$xMAKEFLAGS += --no-print-directory
all: make-foo make-bar
make-foo: ; \$(MAKE) -C foo
make-bar: ; #HELPER# -q sleep 1 ; \$(MAKE) -C bar!,
'-j --output-sync=target',
"#MAKEPATH# -C foo
#HELPER# -q sleep 1 ; #MAKEPATH# -C bar
#MAKE#[1]: Entering directory '#PWD#/bar'
bar: start
bar: end
#MAKE#[1]: Leaving directory '#PWD#/bar'
#MAKE#[1]: Entering directory '#PWD#/foo'
foo: start
foo: end
#MAKE#[1]: Leaving directory '#PWD#/foo'
#MAKE#[1]: Entering directory '#PWD#/bar'
baz: start
baz: end
#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, $tmout);
# Rerun but this time suppress the directory tracking
unlink(@syncfiles);
run_make_test(undef, '-j --output-sync=target x=',
"#MAKEPATH# -C foo
#HELPER# -q sleep 1 ; #MAKEPATH# -C bar
bar: start
bar: end
foo: start
foo: end
baz: start
baz: end\n", 0, $tmout);
# Test that messages from make itself are enclosed with
# "Entering/Leaving directory" messages.
unlink(@syncfiles);
run_make_test(qq!
all: make-foo-fail make-bar-bar
make-foo-fail: ; \$(MAKE) -C foo foo-fail
make-bar-bar: ; #HELPER# -q sleep 1 ; \$(MAKE) -C bar bar!,
'-j -O',
"#MAKEPATH# -C foo foo-fail
#HELPER# -q sleep 1 ; #MAKEPATH# -C bar bar
#MAKE#[1]: Entering directory '#PWD#/bar'
bar: start
bar: end
#MAKE#[1]: Leaving directory '#PWD#/bar'
#MAKE#[1]: Entering directory '#PWD#/foo'
foo-fail: start
foo-fail: end
#MAKE#[1]: *** [Makefile:23: foo-fail] Error 1
#MAKE#[1]: Leaving directory '#PWD#/foo'
#MAKE#: *** [#MAKEFILE#:4: make-foo-fail] Error 2\n",
512);
# Test the per-job synchronization.
# For this we'll have bar-job:
# print start, invoke bar-start, wait for foo-start, print end, print-bar-end
# And foo-job:
# wait for bar-start, print foo-start, wait for bar-end, print end
unlink(@syncfiles);
run_make_test(qq!
all: make-foo make-bar
make-foo: ; \$(MAKE) -C foo foo-job
make-bar: ; #HELPER# -q sleep 1 ; \$(MAKE) -C bar bar-job!,
'-j --output-sync=line',
"#MAKEPATH# -C foo foo-job
#HELPER# -q sleep 1 ; #MAKEPATH# -C bar bar-job
#MAKE#[1]: Entering directory '#PWD#/foo'
foo: start
#MAKE#[1]: Leaving directory '#PWD#/foo'
#MAKE#[1]: Entering directory '#PWD#/bar'
bar: start
#MAKE#[1]: Leaving directory '#PWD#/bar'
#MAKE#[1]: Entering directory '#PWD#/bar'
bar: end
#MAKE#[1]: Leaving directory '#PWD#/bar'
#MAKE#[1]: Entering directory '#PWD#/foo'
foo: end
#MAKE#[1]: Leaving directory '#PWD#/foo'\n", 0, $tmout);
# Remove temporary directories and contents.
output_sync_clean();
# Ensure recursion doesn't mis-order or double-print output
run_make_test(qq!
all:
\t\@echo foo
\t\@+echo bar
!,
'-j -Oline', "foo\nbar\n");
run_make_test(undef, '-j -Otarget', "foo\nbar\n");
# Ensure when make writes out command it's not misordered
run_make_test(qq!
all:
\t\@echo foobar
\ttrue
!,
'-j -Oline', "foobar\ntrue\n");
run_make_test(undef, '-j -Otarget', "foobar\ntrue\n");
# Ensure that shell functions inside recipes write stderr to the sync file
run_make_test(q!
all: ; @: $(shell echo foo 1>&2)
!,
'-w -Oline', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n");
# Ensure that output generated while parsing makefiles is synced
# when appropriate.
run_make_test(q!
$(shell echo foo 1>&2)
all: ; echo bar
!,
'-s -w -Otarget', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n#MAKE#: Entering directory '#PWD#'\nbar\n#MAKE#: Leaving directory '#PWD#'\n");
# Test recursion
$m1 = get_tmpfile();
$m2 = get_tmpfile();
open(M1, "> $m1");
print M1 <<'EOF';
$(shell echo d1 stderr 1>&2)
$(info d1 stdout)
all:; @:
EOF
close(M1);
open(M2, "> $m2");
print M2 <<'EOF';
$(shell echo d2 stderr 1>&2)
$(info d2 stdout)
all:; @:
# Force an ordering on the output
$(shell sleep 1)
EOF
close(M2);
run_make_test(qq!
all: t1 t2
t1: ; \@\$(MAKE) -f $m1
t2: ; \@\$(MAKE) -f $m2
!,
"-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKE#[1]: Entering directory '#PWD#'\nd2 stderr\nd2 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n");
rmfiles($m1, $m2);
# Ensure that output generated while parsing makefiles is synced
# when appropriate.
$m1 = get_tmpfile();
open(M1, "> $m1");
print M1 <<'EOF';
$(shell echo d1 stderr 1>&2)
$(info d1 stdout)
$(error d1 failed)
all:; @:
EOF
close(M1);
run_make_test(qq!
all: t1
t1: ; -\@\$(MAKE) -f $m1
!,
"-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n$m1:3: *** d1 failed. Stop.\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKE#: [#MAKEFILE#:3: t1] Error 2 (ignored)\n");
rmfiles($m1);
# Test $(error ...) functions in recipes
run_make_test(q!
foo: $(OBJS) ; echo $(or $(filter %.o,$^),$(error fail))
!,
'-O', "#MAKEFILE#:2: *** fail. Stop.\n", 512);
# SV 47365: Make sure exec failure error messages are shown
# Needs to be ported to Windows
if ($port_type ne 'W32') {
run_make_test(q!
all:: ; @./foo bar baz
!,
'-O', "#MAKE#: ./foo: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:2: all] Error 127\n", 512);
}
if ($port_type eq 'UNIX') {
# POSIX doesn't require sh to set PPID so test this
my $cmd = create_command();
add_options($cmd, '-f', '/dev/null', '-E', q!all:;@echo $$PPID!);
my $fout = 'ppidtest.out';
run_command_with_output($fout, @$cmd);
$_ = read_file_into_string($fout);
chomp($_);
if (/^[0-9]+$/) {
use POSIX ();
# SV 63157.
# Test that make removes temporary files, even when a signal is received.
# The general test_driver postprocessing will ensure the temporary file used
# to synchronize output and the jobserver fifo are both removed.
# sleep is needed to let make write its "... Terminated" message to the log
# file.
run_make_test(q!
pid:=$(shell echo $$PPID)
all:; @kill -TERM $(pid) && sleep 16
!, '-O -j2', '/#MAKE#: \*\*\* \[#MAKEFILE#:3: all] Terminated/', POSIX::SIGTERM);
}
unlink($fout);
}
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,45 @@
# -*-perl-*-
$description = "Test the override directive on variable assignments.";
$details = "";
# TEST 0: Basic override
run_make_test('
X = start
override recur = $(X)
override simple := $(X)
X = end
all: ; @echo "$(recur) $(simple)"
',
'recur=I simple=J', "end start\n");
# TEST 1: Override with append
run_make_test('
X += X1
override X += X2
override Y += Y1
Y += Y2
all: ; @echo "$(X) $(Y)"
',
'', "X1 X2 Y1\n");
# TEST 2: Override with append to the command line
run_make_test(undef, 'X=C Y=C', "C X2 C Y1\n");
# Test override of define/endef
run_make_test('
override define foo
@echo First comes the definition.
@echo Then comes the override.
endef
all: ; $(foo)
',
'foo=Hello', "First comes the definition.\nThen comes the override.\n");
1;
@@ -0,0 +1,248 @@
# -*-perl-*-
$description = "Test parallelism (-j) option.";
$details = "";
if (!$parallel_jobs) {
return -1;
}
run_make_test(q!
all : def_1 def_2 def_3
def_1 : ; @#HELPER# file ONE wait THREE out TWO
def_2 : ; @#HELPER# wait FOUR file THREE
def_3 : ; @#HELPER# wait ONE file FOUR!,
'-j4', "file ONE\nwait ONE\nfile FOUR\nwait FOUR\nfile THREE\nwait THREE\nTWO");
rmfiles(qw(ONE TWO THREE FOUR));
# Verify -j added to MAKEFLAGS in the makefile
run_make_test(q!
MAKEFLAGS += -j4
all : def_1 def_2 def_3
def_1 : ; @#HELPER# file ONE wait THREE out TWO
def_2 : ; @#HELPER# wait FOUR file THREE
def_3 : ; @#HELPER# wait ONE file FOUR!,
'', "file ONE\nwait ONE\nfile FOUR\nwait FOUR\nfile THREE\nwait THREE\nTWO");
rmfiles(qw(ONE TWO THREE FOUR));
# Command line should take precedence
run_make_test(q!
MAKEFLAGS += -j2
all : def_1 def_2 def_3
def_1 : ; @#HELPER# file ONE wait THREE out TWO
def_2 : ; @#HELPER# wait FOUR file THREE
def_3 : ; @#HELPER# wait ONE file FOUR!,
'-j4', "file ONE\nwait ONE\nfile FOUR\nwait FOUR\nfile THREE\nwait THREE\nTWO");
rmfiles(qw(ONE TWO THREE FOUR));
# Test parallelism with included files. Here we sleep/echo while
# building the included files, to test that they are being built in
# parallel.
run_make_test(q!
all: 1 2; @#HELPER# out success
-include 1.inc 2.inc
.RECIPEPREFIX := >
1.inc:
> @#HELPER# file ONE.inc wait THREE.inc file TWO.inc
> @echo '1: ; @#HELPER# file ONE wait THREE file TWO' > $@
2.inc:
> @#HELPER# wait ONE.inc file THREE.inc
> @echo '2: ; @#HELPER# wait ONE file THREE' > $@!,
"-j4",
"file ONE.inc\nwait ONE.inc\nfile THREE.inc\nwait THREE.inc\nfile TWO.inc\nfile ONE\nwait ONE\nfile THREE\nwait THREE\nfile TWO\nsuccess\n", 0, 7);
rmfiles(qw(ONE.inc TWO.inc THREE.inc ONE TWO THREE 1.inc 2.inc));
# Test parallelism with included files--this time recurse first and make
# sure the jobserver works.
run_make_test(q!
recurse: ; @$(MAKE) --no-print-directory -f #MAKEFILE# INC=yes all
all: 1 2; @#HELPER# out success
INC = no
ifeq ($(INC),yes)
-include 1.inc 2.inc
endif
1.inc: ; @#HELPER# file ONE.inc wait THREE.inc file TWO.inc; echo '1: ; @#HELPER# file ONE wait THREE file TWO' > $@
2.inc: ; @#HELPER# wait ONE.inc file THREE.inc; echo '2: ; @#HELPER# wait ONE file THREE' > $@!,
"-j4",
"file ONE.inc\nwait ONE.inc\nfile THREE.inc\nwait THREE.inc\nfile TWO.inc\nfile ONE\nwait ONE\nfile THREE\nwait THREE\nfile TWO\nsuccess\n", 0, 7);
rmfiles(qw(ONE.inc TWO.inc THREE.inc ONE TWO THREE 1.inc 2.inc));
# Grant Taylor reports a problem where tokens can be lost (not written back
# to the pipe when they should be): this happened when there is a $(shell ...)
# function in an exported recursive variable. I added some code to check
# for this situation and print a message if it occurred. This test used
# to trigger this code when I added it but no longer does after the fix.
run_make_test(q!
export HI = $(shell $($@.CMD))
first.CMD = #HELPER# out hi
second.CMD = #HELPER# sleep 4
.PHONY: all first second
all: first second
first second: ; @#HELPER# out $@ sleep 1 out $@!,
'-j2', "first\nsleep 1\nfirst\nsecond\nsleep 1\nsecond", 0);
# Michael Matz <matz@suse.de> reported a bug where if make is running in
# parallel without -k and two jobs die in a row, but not too close to each
# other, then make will quit without waiting for the rest of the jobs to die.
run_make_test(q!
.PHONY: all fail.1 fail.2 fail.3 ok
all: fail.1 ok fail.2 fail.3
fail.1: ; @#HELPER# -q sleep 1 out $@ file fail.1 fail 1
fail.2: ; @#HELPER# -q sleep 2 out $@ wait fail.1 file fail.2 fail 1
fail.3: ; @#HELPER# -q sleep 3 out $@ wait fail.2 file fail.3 fail 1
ok: ; @#HELPER# -q sleep 4 wait fail.3 out OK!,
'-rR -j5', "fail.1\nfail 1
#MAKE#: *** [#MAKEFILE#:5: fail.1] Error 1
#MAKE#: *** Waiting for unfinished jobs....
fail.2\nfail 1
#MAKE#: *** [#MAKEFILE#:6: fail.2] Error 1
fail.3\nfail 1
#MAKE#: *** [#MAKEFILE#:7: fail.3] Error 1
OK",
512);
rmfiles(qw(fail.1 fail.2 fail.3));
# Test for Savannah bug #15641.
#
run_make_test('
.PHONY: all
all:; @:
-include foo.d
foo.d: comp ; @#HELPER# out $@
comp: mod_a.o mod_b.o; @:
mod_a.o mod_b.o: ; @#HELPER# fail 1
', '-j2', "fail 1\nfail 1\n");
# TEST #9 -- Savannah bugs 3330 and 15919
# In earlier versions of make this will either give the wrong answer, or hang.
utouch(-10, 'target');
run_make_test('target: intermed ; #HELPER# file $@
.INTERMEDIATE: intermed
intermed: | phony ; #HELPER# file $@
.PHONY: phony
phony: ; : phony', '-rR -j', ': phony');
rmfiles('target');
# TEST #11: Make sure -jN from MAKEFLAGS is processed even when we re-exec
# See Savannah bug #33873
$ENV{MAKEFLAGS} = '-j4';
run_make_test(q!
things = thing1 thing2
all: $(things)
thing1:; @#HELPER# wait thing2start file $@start wait thing2end out $@end
thing2:; @#HELPER# file $@start wait thing1start file $@end
-include inc.mk
inc.mk: ; @touch $@
!,
'', "file thing2start\nwait thing2start\nfile thing1start\nwait thing1start\nfile thing2end\nwait thing2end\nthing1end\n");
rmfiles(qw(inc.mk thing1start thing1end thing2start thing2end));
# Ensure intermediate/secondary files are not pruned incorrectly.
# See Savannah bug #30653
utouch(-15, 'file2');
utouch(-10, 'file4');
utouch(-5, 'file1');
run_make_test(q!
.INTERMEDIATE: file3
file4: file3 ; @mv -f $< $@
file3: file2 ; touch $@
file2: file1 ; @touch $@
!,
'--no-print-directory -j2', "touch file3");
rmfiles('file1', 'file2', 'file3', 'file4');
# Ensure that the jobserver is preserved across make re-exec.
run_make_test(q!
all: one two
one: ;@ #HELPER# wait TWO file ONE
two: ;@ #HELPER# file TWO
include fff1.mk
fff1.mk: ; touch $@
!,
'-j2', "touch fff1.mk\nfile TWO\nwait TWO\nfile ONE\n");
rmfiles('fff1.mk', 'ONE', 'TWO');
# Test if a sub-make needs to re-exec and the makefile is built via
# sub-make. Reported by Masahiro Yamada <yamada.masahiro@socionext.com>
run_make_test(q!
all: ; @$(MAKE) -f #MAKEFILE# recurse
recurse: one two ; @#HELPER# out $@
one: ;@ #HELPER# wait TWO file ONE
two: ;@ #HELPER# file TWO
mkinclude: ; touch fff1.mk
ifeq ($(MAKECMDGOALS),recurse)
include fff1.mk
fff1.mk: ; @$(MAKE) -f #MAKEFILE# mkinclude
endif
!,
'--no-print-directory -j2', "touch fff1.mk\nfile TWO\nwait TWO\nfile ONE\nrecurse\n");
rmfiles('fff1.mk', 'ONE', 'TWO');
# Make sure that all jobserver FDs are closed if we need to re-exec the
# master copy.
#
# First, find the "default" file descriptors we normally use
# Then make sure they're still used.
#
# Right now we don't have a way to run a makefile and capture the output
# without checking it, so we can't really write this test.
# run_make_test('
# submake: ; @$(MAKE) --no-print-directory -f #MAKEFILE# fdprint 5>output
# dependfile: ; @echo FOO=bar > $@
# INCL := true
# FOO=foo
# ifeq ($(INCL),true)
# -include dependfile
# endif
# fdprint: ; @echo $(filter --jobserver%,$(MAKEFLAGS))
# recurse: ; @$(MAKE) --no-print-directory -f #MAKEFILE# submake INCL=true',
# '-j2 INCL=false fdprint',
# 'bar');
# rmfiles(qw(dependfile output));
# # Do it again, this time where the include is done by the non-master make.
# run_make_test(undef, '-j2 recurse INCL=false', 'bar');
# rmfiles(qw(dependfile output));
1;
@@ -0,0 +1,148 @@
# -*-perl-*-
$description = "Test pattern-specific variable settings.";
$details = "\
Create a makefile containing various flavors of pattern-specific variable
settings, override and non-override, and using various variable expansion
rules, semicolon interference, etc.";
open(MAKEFILE,"> $makefile");
print MAKEFILE <<'EOF';
all: one.x two.x three.x
FOO = foo
BAR = bar
BAZ = baz
one.x: override FOO = one
%.x: BAR = two
t%.x: BAR = four
thr% : override BAZ = three
one.x two.x three.x: ; @echo $@: $(FOO) $(BAR) $(BAZ)
four.x: baz ; @echo $@: $(FOO) $(BAR) $(BAZ)
baz: ; @echo $@: $(FOO) $(BAR) $(BAZ)
# test matching multiple patterns
a%: AAA = aaa
%b: BBB = ccc
a%: BBB += ddd
%b: AAA ?= xxx
%b: AAA += bbb
.PHONY: ab
ab: ; @echo $(AAA); echo $(BBB)
EOF
close(MAKEFILE);
# TEST #1 -- basics
&run_make_with_options($makefile, "", &get_logfile);
$answer = "one.x: one two baz\ntwo.x: foo four baz\nthree.x: foo four three\n";
&compare_output($answer,&get_logfile(1));
# TEST #2 -- try the override feature
&run_make_with_options($makefile, "BAZ=five", &get_logfile);
$answer = "one.x: one two five\ntwo.x: foo four five\nthree.x: foo four three\n";
&compare_output($answer,&get_logfile(1));
# TEST #3 -- make sure patterns are inherited properly
&run_make_with_options($makefile, "four.x", &get_logfile);
$answer = "baz: foo two baz\nfour.x: foo two baz\n";
&compare_output($answer,&get_logfile(1));
# TEST #4 -- test multiple patterns matching the same target
&run_make_with_options($makefile, "ab", &get_logfile);
$answer = "aaa bbb\nccc ddd\n";
&compare_output($answer,&get_logfile(1));
# TEST #5 -- test pattern-specific exported variables
#
run_make_test('
/%: export foo := foo
/bar:
@echo $(foo) $$foo
', '', 'foo foo');
# TEST #6 -- test expansion of pattern-specific simple variables
#
run_make_test('
.PHONY: all
all: inherit := good $$t
all: bar baz
b%: pattern := good $$t
global := original $$t
# normal target
#
ifdef rec
bar: a = global: $(global) pattern: $(pattern) inherit: $(inherit)
else
bar: a := global: $(global) pattern: $(pattern) inherit: $(inherit)
endif
bar: ; @echo \'normal: $a;\'
# pattern target
#
ifdef rec
%z: a = global: $(global) pattern: $(pattern) inherit: $(inherit)
else
%z: a := global: $(global) pattern: $(pattern) inherit: $(inherit)
endif
%z: ; @echo \'pattern: $a;\'
global := new $$t
',
'',
'normal: global: original $t pattern: inherit: ;
pattern: global: original $t pattern: inherit: ;');
# TEST #7 -- test expansion of pattern-specific recursive variables
#
run_make_test(undef, # reuse previous makefile
'rec=1',
'normal: global: new $t pattern: good $t inherit: good $t;
pattern: global: new $t pattern: good $t inherit: good $t;');
# TEST #8: override in pattern-specific variables
run_make_test('
a%: override FOO += f1
a%: FOO += f2
ab: ; @echo "$(FOO)"
',
'', "f1\n");
run_make_test(undef, 'FOO=C', "C f1\n");
# TEST #9: Test shortest stem selection in pattern-specific variables.
run_make_test('
%-mt.x: x := two
%.x: x := one
all: foo.x foo-mt.x
foo.x: ;@echo $x
foo-mt.x: ;@echo $x
',
'',
"one\ntwo");
1;
@@ -0,0 +1,676 @@
# -*-perl-*-
$description = "Test pattern rules.";
$details = "";
use Cwd;
$dir = cwd;
$dir =~ s,.*/([^/]+)$,../$1,;
# TEST #0: Make sure that multiple patterns where the same target
# can be built are searched even if the first one fails
# to match properly.
#
run_make_test(q!
.PHONY: all
all: case.1 case.2 case.3 case.4
# We can't have this, due to "Implicit Rule Search Algorithm" step 5c
#xxx: void
# 1 - existing file
%.1: void ; @exit 1
%.1: #MAKEFILE# ; @exit 0
# 2 - phony
%.2: void ; @exit 1
%.2: 2.phony ; @exit 0
.PHONY: 2.phony
# 3 - implicit-phony
%.3: void ; @exit 1
%.3: 3.implicit-phony ; @exit 0
3.implicit-phony:
# 4 - explicitly mentioned file made by an implicit rule
%.4: void ; @exit 1
%.4: test.x ; @exit 0
%.x: ;
!,
'', '');
# TEST #1: make sure files that are built via implicit rules are marked
# as targets (Savannah bug #12202).
#
run_make_test('
TARGETS := foo foo.out
.PHONY: all foo.in
all: $(TARGETS)
%: %.in ; @echo $@
%.out: % ; @echo $@
foo.in: ; @:
',
'', "foo\nfoo.out");
# TEST #2: make sure intermediate files that also happened to be
# prerequisites are not removed (Savannah bug #12267).
#
run_make_test('
$(dir)/foo.o:
$(dir)/foo.y: ; @echo $@
%.c: %.y ; touch $@
%.o: %.c ; @echo $@
.PHONY: install
install: $(dir)/foo.c
',
"dir=$dir", "$dir/foo.y\ntouch $dir/foo.c\n$dir/foo.o");
unlink("$dir/foo.c");
# TEST #3: make sure precious flag is set properly for targets
# that are built via implicit rules (Savannah bug #13218).
#
run_make_test('
.DELETE_ON_ERROR:
.PRECIOUS: %.bar
%.bar:; @touch $@ && exit 1
$(dir)/foo.bar:
',
"dir=$dir",
"#MAKE#: *** [#MAKEFILE#:6: $dir/foo.bar] Error 1", 512);
unlink("$dir/foo.bar");
# TEST #4: make sure targets of a matched implicit pattern rule are
# never considered intermediate (Savannah bug #13022).
#
run_make_test('
.PHONY: all
all: foo.c foo.o
%.h %.c: %.in ; touch $*.h ; touch $*.c
%.o: %.c %.h ; echo $+ >$@
%.o: %.c ; @echo wrong rule
foo.in: ; touch $@
',
'', "touch foo.in\ntouch foo.h ; touch foo.c\necho foo.c foo.h >foo.o\nrm foo.h");
unlink('foo.in', 'foo.h', 'foo.c', 'foo.o');
# TEST #5: make sure both prefix and suffix patterns work with multiple
# target patterns (Savannah bug #26593).
#
run_make_test('
all: foo.s1 foo.s2 p1.foo p2.foo
p1.% p2.%: %.orig ; @echo $@
%.s1 %.s2: %.orig ; @echo $@
.PHONY: foo.orig
',
'', "foo.s1\np1.foo\n");
# TEST 6: Make sure that non-target files are still eligible to be created
# as part of implicit rule chaining. Savannah bug #17752.
run_make_test(sprintf(q!
BIN = xyz
COPY = $(BIN).cp
SRC = $(BIN).c
allbroken: $(COPY) $(BIN) ; @echo ok
$(SRC): ; @echo 'main(){}' > $@
%%.cp: %% ; @cp $< $@
%% : %%.c ; @cp $< $@
clean: ; @%s $(SRC) $(COPY) $(BIN)
!, $CMD_rmfile),
'', "ok\n");
unlink(qw(xyz xyz.cp xyz.c));
# TEST 7: Make sure that all prereqs of all "also_make" targets get created
# before any of the things that depend on any of them. Savannah bug #19108.
run_make_test(q!
final: x ; @echo $@
x: x.t1 x.t2 ; @echo $@
x.t2: dep
dep: ; @echo $@
%.t1 %.t2: ; @echo $*.t1 ; echo $*.t2
!,
'', "dep\nx.t1\nx.t2\nx\nfinal\n");
# TEST 8: Verify we can remove pattern rules. Savannah bug #18622.
my @f = (qw(foo.w foo.ch));
touch(@f);
run_make_test(q!
CWEAVE := :
# Disable builtin rules
%.tex : %.w
%.tex : %.w %.ch
!,
'foo.tex',
"#MAKE#: *** No rule to make target 'foo.tex'. Stop.", 512);
unlink(@f);
# TEST #9: Test shortest stem selection in pattern rules.
run_make_test('
%.x: ;@echo one
%-mt.x: ;@echo two
all: foo.x foo-mt.x
',
'', "one\ntwo");
# Test pattern rules building the same targets
# See SV 54233.
touch('a.c');
# a.lnk isn't listed as removed, because it's not actually created
run_make_test(q!
all: a.elf a.dbg
%.elf %.lnk: %.c ; : $*.elf $*.lnk
%.elf %.dbg: %.lnk ; : $*.elf $*.dbg
!,
'-j2', ": a.elf a.lnk\n: a.elf a.dbg\n");
# SV 60435 : a.lnk is removed, because it is intermediate.
run_make_test(q!
all: a.elf a.dbg
%.elf %.lnk: %.c ; touch $*.elf $*.lnk
%.elf %.dbg: %.lnk ; touch $*.elf $*.dbg
!,
'-j2', "touch a.elf a.lnk\ntouch a.elf a.dbg\nrm a.lnk\n");
unlink('a.elf', 'a.dbg');
# SV 60435 : a.lnk is not intermediate, because it is explicitly mentioned.
run_make_test(q!
all: a.elf a.dbg
%.elf %.lnk: %.c ; touch $*.elf $*.lnk
%.elf %.dbg: %.lnk ; touch $*.elf $*.dbg
install: a.lnk
.PHONY: install
!,
'-j2', "touch a.elf a.lnk\ntouch a.elf a.dbg\n");
unlink('a.c', 'a.elf', 'a.dbg', 'a.lnk');
# SV 56655: Test patterns matching files containing whitespace
touch('some file.yy');
run_make_test(q!
%.xx : %.yy ; @echo matched
!,
'"some file.xx"', "matched\n");
unlink('some file.xx', 'some file.yy');
# sv 60188.
# Test that a file explicitly mentioned by the user and made by an implicit
# rule is not considered intermediate.
touch('hello.z');
unlink('hello.x', 'test.x');
# subtest 1
# hello.x is not explicitly mentioned and thus is an intermediate file.
run_make_test(q!
all: hello.z
%.z: %.x ; touch $@
%.x: ;
!,
'', "#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2
# test.x is explicitly mentioned and thus is not an intermediate file.
run_make_test(q!
all: hello.z
%.z: %.x test.x ; touch $@
%.x: ;
!,
'', "touch hello.z");
# subtest 3
# hello.x is explicitly mentioned on an unrelated rule and thus is not an
# intermediate file.
touch('hello.z');
run_make_test(q!
all: hello.z
%.z: %.x; touch $@
%.x: ;
unrelated: hello.x
!,
'', "touch hello.z");
unlink('hello.z');
# sv 60188.
# Test that a file explicitly mentioned by the user and made by an implicit
# rule is not considered intermediate, even when the builtin rules are used.
touch('hello.x');
touch('test.x');
touch('hello.tsk');
# subtest 1
# hello.o is not explicitly mentioned and thus is an intermediate file.
run_make_test(q!
all: hello.tsk
%.tsk: %.z ; @echo $@
%.z : %.x ; @echo $@
!,
'', "#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2
# test.z is explicitly mentioned and thus is not an intermediate file.
# test.z is built first because until it's built we don't know if we
# need to rebuild the intermediate hello.z
run_make_test(q!
all: hello.tsk
%.tsk: %.z test.z ; @echo $@
%.z : %.x ; @echo $@
!,
'', "test.z\nhello.z\nhello.tsk\n");
# subtest 3
# hello.o is not explicitly mentioned and thus is an intermediate file.
run_make_test(q!
all: hello.tsk
dep:=%.o
%.tsk: $(dep) ; @echo $@
!,
'', "#MAKE#: Nothing to be done for 'all'.\n");
# subtest 4
# Even when test.z is constructed from 2 variables it is still explicitly
# mentioned and thus is not an intermediate file.
# test.z is built first because until it's built we don't know if we
# need to rebuild the intermediate hello.z
run_make_test(q!
all: hello.tsk
name:=test
suf:=.z
%.tsk: %.z $(name)$(suf) ; @echo $@
%.z: %.x ; @echo $@
!,
'', "test.z\nhello.z\nhello.tsk\n");
unlink('hello.x', 'test.x', 'hello.tsk');
# Test that chained pattern rules with multiple targets remove all intermediate
# files.
# sv 60435.
# subtest 1.
# a.1 and a.2 are intermediate and should be removed.
run_make_test(q!
a.4:
%.4: %.1 %.15 ; cat $^ >$@
%.1 %.15: ; touch $*.1 $*.15
!,
'', "touch a.1 a.15\ncat a.1 a.15 >a.4\nrm a.15 a.1");
unlink('a.4');
# subtest 2.
# a.1 and a.2 are intermediate and should be removed.
# a.3 is explicit and should not be removed.
run_make_test(q!
a.4:
%.4: %.1 %.15 a.3 ; cat $^ >$@
%.1 %.15: ; touch $*.1 $*.15
%.3: ; touch $@
!,
'', "touch a.3\ntouch a.1 a.15\ncat a.1 a.15 a.3 >a.4\nrm a.15 a.1");
unlink('a.3', 'a.4');
# subtest 3.
# a.1 and a.2 are intermediate and should be removed.
# a.3 is explicit and should not be removed.
run_make_test(q!
a.4:
%.4: %.1 %.15 a.3 ; cat $^ >$@
%.1 %.15 %.3: ; touch $*.1 $*.15 $*.3
!,
'', "touch a.1 a.15 a.3\ncat a.1 a.15 a.3 >a.4\nrm a.15 a.1");
unlink('a.3', 'a.4');
# subtest 4.
# a.1 and a.2 are intermediate and should be removed.
# a.3 is explicit and should not be removed.
run_make_test(q!
a.4:
%.4: %.1 %.15 a.3 ; cat $^ >$@
%.3 %.1 %.15: ; touch $*.1 $*.15 $*.3
!,
'', "touch a.1 a.15 a.3\ncat a.1 a.15 a.3 >a.4\nrm a.15 a.1");
unlink('a.3', 'a.4');
# subtest 5.
# a.1 and a.2 are intermediate and should be removed.
# a.3 is explicit and should not be removed.
run_make_test(q!
a.4:
%.4: a.3 %.1 %.15 ; cat $^ >$@
%.1 %.15 %.3: ; touch $*.1 $*.15 $*.3
!,
'', "touch a.1 a.15 a.3\ncat a.3 a.1 a.15 >a.4\nrm a.15 a.1");
unlink('a.3', 'a.4');
# subtest 6.
# a.2 is intermediate and should be removed.
# a.1 is mentioned explicitly on an unrelated rule and should not be removed.
run_make_test(q!
a.3:
%.3: %.1 %.2 ; cat $^ >$@
%.1 %.2: ; touch $*.1 $*.2
install: a.1
.PHONY: install
!,
'', "touch a.1 a.2\ncat a.1 a.2 >a.3\nrm a.2");
unlink('a.1', 'a.3');
# Test removal of intermediate files.
# subtest 1.
# hello.x is removed, because it is intermediate.
run_make_test(q!
hello.tsk:
%.tsk: %.x; touch $@
%.x: ; touch $@
!,
'', "touch hello.x\ntouch hello.tsk\nrm hello.x");
unlink('hello.tsk');
# subtest 2.
# Even though hello.x is intermediate, it is not removed, because it is not
# created.
touch('hello.x');
run_make_test(q!
hello.tsk:
%.tsk: %.x; touch $@
%.x: ; touch $@
!,
'', "touch hello.tsk");
unlink('hello.x', 'hello.tsk');
# subtest 2.
# Even though hello.x is intermediate, it is not removed, because it is not
# created.
run_make_test(q!
hello.tsk:
%.tsk: %.x; touch $@
%.x: ; : $@
!,
'', ": hello.x\ntouch hello.tsk");
unlink('hello.tsk');
# A target explicitly listed as a prerequisite of a pattern rule, is still
# considered mentioned and "ought to exist".
run_make_test(q!
1.all: 1.q ; touch $@
%.q: 1.r ; touch $@
%.r: ; touch $@
!,
'', "touch 1.r\ntouch 1.q\ntouch 1.all\n");
unlink('1.all', '1.q', '1.r');
# SV 63098: Verify that missing also_made in pattern rules gives a warning but
# doesn't fail.
run_make_test(q!
%a %b : ; touch $*a
!,
'gta', "touch gta\n#MAKEFILE#:2: warning: pattern recipe did not update peer target 'gtb'.\n");
unlink(qw(gta));
# We don't warn if we didn't update the file
utouch(-10, qw(gta));
run_make_test(q!
%a %b : xyzzy ; $(OP)
xyzzy: ;
ifdef RUN
OP = @echo no
endif
!,
'-rR gta', "#MAKE#: 'gta' is up to date.\n");
run_make_test(undef, '-rR gta RUN=1', "no\n");
unlink(qw(gta));
run_make_test(q!
all:;
include gta
%a %b : ; touch $*a
!,
'', "touch gta\n#MAKEFILE#:4: warning: pattern recipe did not update peer target 'gtb'.\n#MAKE#: 'all' is up to date.");
unlink(qw(gta));
run_make_test(q!
%.c %.h : %.y; touch $*.c
%.o: %.c; touch $@
foo.y: ; touch $@
!,
'foo.o', "touch foo.y\ntouch foo.c\n#MAKEFILE#:2: warning: pattern recipe did not update peer target 'foo.h'.\ntouch foo.o\nrm foo.c");
unlink(qw(foo.y foo.c foo.o));
if (0) {
# SV 12078: Missing grouped pattern peer causes remake regardless of which
# target caused the rule to run.
touch(qw(gta)); # but not gtb
run_make_test(q!
%a %b : ; touch $*a $*b
!,
'gta', "touch gta gtb\n");
unlink(qw(gta gtb));
# Ensure both goal targets are built if they depend on a grouped pattern
touch(qw(gta)); # but not gtb
run_make_test(q!
x y: ; touch $@
x: gta
y: gtb
%a %b : ; touch $*a $*b
!,
'x y', "touch gta gtb\ntouch x\ntouch y\n");
# Now everything should be up to date
run_make_test(undef, 'x y',
"#MAKE#: 'x' is up to date.\n#MAKE#: 'y' is up to date.");
unlink(qw(x y gta gtb));
# sv 12078 : make sure we notice when all targets need to be rebuilt
# a.1st exists but b.1st doesn't: make sure a.2nd is out of date as well
utouch(-20, 'a.1st');
utouch(-10, 'a.2nd', 'b.2nd');
run_make_test(q!
1st := a.1st b.1st
2nd := ${1st:.1st=.2nd}
.PHONY: all
all: ${2nd}
a.% b.% : ; touch a.$* b.$*
${2nd}: %.2nd: %.1st ; cp $< $@
!
, '', "touch a.1st b.1st\ncp a.1st a.2nd\ncp b.1st b.2nd\n");
unlink(qw(a.1st b.1st a.2nd b.2nd));
# Variation: b.1st exists but is newer
utouch(-20, 'a.1st');
utouch(-10, 'a.2nd', 'b.2nd');
touch(qw(b.1st));
run_make_test(undef, '', "cp b.1st b.2nd\n");
unlink(qw(a.1st b.1st a.2nd b.2nd));
}
# sv 62206.
# The following combinations are generated with and without second expansion.
# 1.
# all: bye.x
# %.x: ...
#
# 2.
# all: lib/bye.x
# %.x: ...
#
# 3.
# all: lib/bye.x
# lib/%.x: ...
#
# The following combination is not generated, because there is no rule to
# build bye.x, no stem substitution takes place, not of interest of this test.
# 4.
# all: bye.x
# lib/%.x: ...
my @dir = ('', 'lib/'); # With and without last slash.
my @secondexpansion = ('', '.SECONDEXPANSION:');
for my $se (@secondexpansion) {
for my $d (@dir) { # The directory of the prerequisite of 'all'.
for my $r (@dir) { # The directory of the target in the rule definition.
(!$d && $r) && next; # Combination 4.
my $dollar = $se ? '$' : '';
# The prerequisite should only have directory if the prerequisite of 'all' has
# it and if the prequisite pattern in the rule definition does not have it.
# That is combination 2.
my $pdir = $d && !$r ? $d : '';
my $prereqs = "${pdir}bye.1";
# One func, one %.
run_make_test("
$se
all: ${d}bye.x
$r%.x: $dollar\$(firstword %.1); \$(info \$@ from \$^)
.PHONY: $prereqs
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
$prereqs = "${pdir}bye.1 ${pdir}bye.2";
# Multiple funcs, each has one %.
run_make_test("
$se
all: ${d}bye.x
$r%.x: $dollar\$(firstword %.1) $dollar\$(firstword %.2); \$(info \$@ from \$^)
.PHONY: $prereqs
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
$prereqs = "${pdir}bye.1 ${pdir}bye.2 ${pdir}bye.3 ${pdir}bye.4";
# Multiple funcs, each has multiple %.
run_make_test("
$se
all: ${d}bye.x
$r%.x: $dollar\$(wordlist 1, 99, %.1 %.2) $dollar\$(wordlist 1, 99, %.3 %.4); \$(info \$@ from \$^)
.PHONY: $prereqs
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
$prereqs = "${pdir}bye.1 ${pdir}bye.2 ${pdir}bye.3 ${pdir}bye.4";
# Nested functions.
run_make_test("
$se
all: ${d}bye.x
$r%.x: $dollar\$(wordlist 1, 99, $dollar\$(wordlist 1, 99, %.1 %.2)) $dollar\$(wordlist 1, 99, $dollar\$(wordlist 1,99, %.3 %.4)); \$(info \$@ from \$^)
.PHONY: $prereqs
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
$prereqs = "${pdir}bye1%2% ${pdir}bye ${pdir}3bye4%5 ${pdir}6bye ${pdir}bye7%8 ${pdir}bye9 ${pdir}bye10% ${pdir}11bye12 13";
# Multiple funcs, each has multiple words, each word has multiple %, sole %,
# various corner cases.
# Make should substitute the first % and only the first % in each word with the
# stem.
run_make_test("
$se
all: ${d}bye.x
$r%.x: $dollar\$(wordlist 1, 99, %1%2% % 3%4%5 6%) %7%8 %9 $dollar\$(wordlist 1, 99, %10% 11%12) 13; \$(info \$@ from \$^)
.PHONY: $prereqs
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
if ($port_type eq 'UNIX') {
# Test that make does not use some hardcoded array of a finite size on stack.
# Long prerequisite name. This prerequisite name is over 66K long.
my $prefix = 'abcdefgh' x 128 x 33; # 33K long.
my $suffix = 'stuvwxyz' x 128 x 33; # 33K long.
$prereqs = "${pdir}${prefix}bye${suffix}.1 ${pdir}${prefix}bye${suffix}.2";
run_make_test("
$se
all: ${d}bye.x
$r%.x: $dollar\$(wordlist 1, 99, ${prefix}%${suffix}.1 ${prefix}%${suffix}.2); \$(info \$@ from \$^)
.PHONY: $prereqs
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
}
}
}
}
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,31 @@
# -*-perl-*-
$description = "The following test creates a makefile to test using \n" .
"quotes within makefiles.";
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE <<'EOM';
TEXFONTS = NICEFONT
DEFINES = -DDEFAULT_TFM_PATH=\".:$(TEXFONTS)\"
test: ; @"echo" 'DEFINES = $(DEFINES)'
EOM
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = 'DEFINES = -DDEFAULT_TFM_PATH=\".:NICEFONT\"' . "\n";
# COMPARE RESULTS
&compare_output($answer,&get_logfile(1));
1;
@@ -0,0 +1,67 @@
# -*-perl-*-
$description = "Test recursion.";
$details = "DETAILS";
# Test some basic recursion.
run_make_test('
.RECIPEPREFIX := |
all:
| $(MAKE) -f #MAKEFILE# foo
foo:
| @echo $(MAKE)
| @echo MAKELEVEL = $(MAKELEVEL)
| $(MAKE) -f #MAKEFILE# last
last:
| @echo $(MAKE)
| @echo MAKELEVEL = $(MAKELEVEL)
| @echo THE END
',
('CFLAGS=-O -w' . ($parallel_jobs ? ' -j 2' : '')),
($vos
? "#MAKE#: Entering directory '#PWD#'
make 'CFLAGS=-O' -f #MAKEFILE# foo
make CFLAGS=-O
MAKELEVEL = 0
make 'CFLAGS=-O' -f #MAKEFILE# last
make CFLAGS=-O
MAKELEVEL = 0
THE END
#MAKE#: Leaving directory '#PWD#'"
: "#MAKE#: Entering directory '#PWD#'
#MAKEPATH# -f #MAKEFILE# foo
#MAKE#[1]: Entering directory '#PWD#'
#MAKEPATH#
MAKELEVEL = 1
#MAKEPATH# -f #MAKEFILE# last
#MAKE#[2]: Entering directory '#PWD#'
#MAKEPATH#
MAKELEVEL = 2
THE END
#MAKE#[2]: Leaving directory '#PWD#'
#MAKE#[1]: Leaving directory '#PWD#'
#MAKE#: Leaving directory '#PWD#'"));
# Test command line overrides.
run_make_test('
recur: all ; @$(MAKE) --no-print-directory -f #MAKEFILE# a=AA all
all: ; @echo "MAKEOVERRIDES = $(MAKEOVERRIDES)"
',
'a=ZZ',
'MAKEOVERRIDES = a=ZZ
MAKEOVERRIDES = a=AA
');
# SV 46013: Ensure that MAKEOVERRIDES is passed even if set in the makefile
run_make_test(q!
ifeq ($(MAKELEVEL),0)
MAKEOVERRIDES += FOO+=bar
endif
.PHONY: M R
M: ; @$(MAKE) --no-print-directory -f #MAKEFILE# R
R: ; @echo '$(FOO)'
!,
'', 'bar');
1;
@@ -0,0 +1,180 @@
# -*-mode: perl-*-
$description = "Test GNU make's auto-reinvocation feature.";
$details = "\
If the makefile or one it includes can be rebuilt then it is, and make
is reinvoked. We create a rule to rebuild the makefile from a temp
file, then touch the temp file to make it newer than the makefile.";
$omkfile = $makefile;
&utouch(-600, 'incl.mk');
# For some reason if we don't do this then the test fails for systems
# with sub-second timestamps, maybe + NFS? Not sure.
&utouch(-1, 'incl-1.mk');
run_make_test('
all: ; @echo running rules.
#MAKEFILE# incl.mk: incl-1.mk ; @echo rebuilding $@; echo >> $@
include incl.mk',
'', "rebuilding incl.mk\nrunning rules.\n");
# Make sure updating the makefile itself also works
&utouch(-600, $omkfile);
run_make_test(undef, '', "rebuilding #MAKEFILE#\nrunning rules.\n");
&rmfiles('incl.mk', 'incl-1.mk');
# In this test we create an included file that's out-of-date, but then
# the rule doesn't update it. Make shouldn't re-exec.
&utouch(-600, 'b','a');
#&utouch(-10, 'a');
&touch('c');
run_make_test('
all: ; @echo hello
a : b ; echo >> $@
b : c ; test -f $@ || echo >> $@
c: ; echo >> $@
include $(F)',
'F=a', "test -f b || echo >> b\nhello\n");
# Now try with the file we're not updating being the actual file we're
# including: this and the previous one test different parts of the code.
run_make_test(undef, 'F=b', "test -f b || echo >> b\nhello\n");
&rmfiles('a','b','c');
# Ensure command line variables are preserved properly across re-exec
# Tests for Savannah bug #30723
run_make_test('
ifdef RECURSE
-include foo30723
endif
recurse: ; @$(MAKE) -f $(MAKEFILE_LIST) RECURSE=1 test
test: ; @echo F.O=$(F.O)
foo30723: ; @touch $@
',
'--no-print-directory F.O=bar', "F.O=bar\n");
unlink('foo30723');
# If ANY makefile is rebuilt then we should re-exec
run_make_test('
all: ; @echo RESTARTS=$(MAKE_RESTARTS)
m1.d: ; @echo $@; touch $@
m2.d: m1.d ; @test -f $< || { echo $@; touch $@; }
include m1.d
-include m2.d
',
'', "m1.d\nRESTARTS=1\n");
unlink('m1.d', 'm2.d');
# Same as before but be sure we get error messages for un-created makefiles
run_make_test('
all: ; @echo RESTARTS=$(MAKE_RESTARTS)
m1.d: ; @echo $@; touch $@
m2.d: m1.d ; @test -f $< || { echo $@; touch $@; }
include m1.d m2.d
', '',
# This runs afoul of https://savannah.gnu.org/bugs/?61226
0 ? "m1.d\n#MAKEFILE#:8: m2.d: $ERR_no_such_file"
: "m1.d\nRESTARTS=1",
0 ? 512 : 0);
unlink('m1.d', 'm2.d');
# sv 61226.
# This set of four cases tests two aspects of make.
#
# 1. If a rule has no prerequisites or recipe, and the target of the rule is a
# nonexistent file, then make imagines this target to have been updated
# whenever its rule is run.
#
# 2. Make does not re-execute itself in this case of imagined target.
#
# Test case 1.
# Make imagines hello.d was updated by a rule without recipe and without
# prereqs.
# This should succeed.
# Make should not re-execute itself.
run_make_test('
hello.o: hello.d; $(info RESTARTS=$(MAKE_RESTARTS))
hello.d:
include hello.d
', '', "RESTARTS=\n#MAKE#: 'hello.o' is up to date.");
# Test case 2.
# Make imagines hello.d was updated by a rule with a recipe and without
# prereqs.
# This should succeed.
# Make should not re-execute itself.
run_make_test('
hello.o: hello.d; $(info RESTARTS=$(MAKE_RESTARTS))
hello.d:; $(info $@)
include hello.d
', '', "hello.d\nRESTARTS=\n#MAKE#: 'hello.o' is up to date.");
&touch('hello.td');
# Test case 3.
# Make imagines hello.d was updated by a rule without a recipe and with
# prereqs.
# This should succeed.
# Make should not re-execute itself.
run_make_test('
hello.o: hello.d; $(info RESTARTS=$(MAKE_RESTARTS))
hello.d: hello.td
include hello.d
', '', "RESTARTS=\n#MAKE#: 'hello.o' is up to date.");
# Test case 4.
# Same test as three tests above, but the rule has both recipe and prereqs.
# Make should report this error.
run_make_test('
hello.o: hello.d; $(info $@)
hello.d: hello.td; $(info $@)
include hello.d
', '',
# This runs afoul of https://savannah.gnu.org/bugs/?61226
0 ? "hello.d\n#MAKEFILE#:4: hello.d: $ERR_no_such_file"
: "hello.d\nhello.o\n#MAKE#: 'hello.o' is up to date.",
0 ? 512 : 0);
unlink('hello.td');
# Test DV 62088 : make sure we don't re-invoke for stdin makefiles.
# The test framework doesn't seem to have a good way to do this.
create_file('input.mk', "all:;\$(info all)\n");
close(STDIN);
open(STDIN, "<", 'input.mk') || die "input.mk: $!\n";
run_make_test('', '-sf -', "all\n");
close(STDIN);
unlink('input.mk');
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,37 @@
# -*-perl-*-
$description = "Test globbing in targets and prerequisites.";
$details = "";
touch(qw(a.one a.two a.three));
# Test wildcards in regular targets and prerequisites
run_make_test(q{
.PHONY: all a.one a.two a.three
all: a.one* a.t[a-z0-9]o a.th[!q]ee
a.o[Nn][Ee] a.t*: ; @echo $@
},
'', "a.one\na.two\na.three");
# Test wildcards in pattern targets and prerequisites
run_make_test(q{
.PHONY: all
all: a.four
%.four : %.t* ; @echo $@: $(sort $^)
},
'', "a.four: a.three a.two");
# Test wildcards in second expansion targets and prerequisites
run_make_test(q{
.PHONY: all
all: a.four
.SECONDEXPANSION:
%.four : $$(sort %.t*) ; @echo $@: $(sort $^)
},
'', "a.four: a.three a.two");
unlink(qw(a.one a.two a.three));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,504 @@
# -*-perl-*-
$description = "Test second expansion in ordinary rules.";
$details = "";
# TEST #0: Test handing of '$' in prerequisites with and without second
# expansion.
# If we don't support archives then the prerequisite is different
my $prereq = exists $FEATURES{'archives'} ? '$' : '$(PRE)';
run_make_test(q!
ifdef SE
.SECONDEXPANSION:
endif
foo$$bar: bar$$baz bar$$biz ; @echo '$@ : $^'
PRE = one two
bar$$baz: $$(PRE)
baraz: $$(PRE)
PRE = three four
.DEFAULT: ; @echo '$@'
!,
'',
"$prereq\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
run_make_test(undef, 'SE=1', "three\nfour\nbariz\nfoo\$bar : baraz bariz");
# TEST #1: automatic variables.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
foo: bar baz
foo: biz | buz
foo: $$@.1 \
$$<.2 \
$$(addsuffix .3,$$^) \
$$(addsuffix .4,$$+) \
$$|.5 \
$$*.6
!,
'',
'bar
baz
biz
buz
foo.1
bar.2
bar.3
baz.3
biz.3
bar.4
baz.4
biz.4
buz.5
.6
');
# Test #2: target/pattern -specific variables.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
foo.x: $$a $$b
foo.x: a := bar
%.x: b := baz
!,
'',
'bar
baz
');
# Test #3: order of prerequisites.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
all: foo bar baz
# Subtest #1
foo: foo.1; @:
foo: foo.2
foo: foo.3
# Subtest #2
bar: bar.2
bar: bar.1; @:
bar: bar.3
# Subtest #3
baz: baz.1
baz: baz.2
baz: ; @:
!,
'',
'foo.1
foo.2
foo.3
bar.1
bar.2
bar.3
baz.1
baz.2
');
# TEST #4: eval in a context where there is no reading_file
run_make_test(q!
.SECONDEXPANSION:
all : $$(eval $$(info test))
!,
'', "test\n#MAKE#: Nothing to be done for 'all'.\n");
# TEST #5: (NEGATIVE) catch eval in a prereq list trying to create new
# target/prereq relationships.
run_make_test(q!
.SECONDEXPANSION:
proj1.exe : proj1.o $$(eval $$(test))
define test
proj1.o : proj1.c
proj1.c: proj1.h
endef
!,
'', "#MAKE#: *** prerequisites cannot be defined in recipes. Stop.\n", 512);
# Automatic $$+ variable expansion issue. Savannah bug #25780
run_make_test(q!
all : foo foo
.SECONDEXPANSION:
all : $$+ ; @echo '$+'
foo : ;
!,
'', "foo foo foo foo\n");
# Automatic $$+ variable expansion issue. Savannah bug #25780
run_make_test(q!
all : bar bar
bar : ;
q%x : ;
.SECONDEXPANSION:
a%l: q1x $$+ q2x ; @echo '$+'
!,
'', "q1x bar bar q2x bar bar\n");
# Allow patsubst shorthand in second expansion context.
# Requires the colon to be quoted. Savannah bug #16545
run_make_test(q!
.PHONY: foo.bar
.SECONDEXPANSION:
foo: $$(@\\:%=%.bar); @echo '$^'
!,
'', "foo.bar\n");
# SV 54549 : Ensure we don't free used variable_sets
run_make_test(q!
foo: -lcat
# Removing second expansion prevents segfault
.SECONDEXPANSION:
foo: $$@.o ;
# Having an empty command here prevents segfault unless,
# the environment is empty. `env -i make foo`
# MFLAGS=-w or MAKEFLAGS=-w `env MFLAGS=-w make foo`
# libcat.a target calls an extra command, `@true \n @touch $@`
# odd.
%.o: ; @true
# Having an empty command prevents segfault.
-l%: lib%.a ; @true
# Not creating libcat.a here prevents segfault,
libcat.a: ; @touch $@
!,
'', q!#MAKEFILE#:16: Recipe was specified for file '-lcat' at #MAKEFILE#:16,
#MAKEFILE#:16: but '-lcat' is now considered the same file as 'libcat.a'.
#MAKEFILE#:16: Recipe for '-lcat' will be ignored in favor of the one for 'libcat.a'.!);
unlink('libcat.a');
# SV 28456 : Don't reset $$< for default recipes
run_make_test(q!
.SECONDEXPANSION:
.PHONY: biz baz
biz: baz ;
biz: $$(info $$<)
!,
'', "baz\n#MAKE#: Nothing to be done for 'biz'.\n");
# sv 60659. Second expansion of automatic variables inside a function in the
# prerequisite list.
# $$@ expands to the target in the 1st and following rules.
# $$<,$$^,$$+,$$|,$$?,$$*,$$% expand to the empty string in the prerequisite
# list of the 1st rule.
# $$<,$$^,$$+,$$|,$$?,$$*,$$% in the prerequisite list of the 2nd (and
# following) rule expand to the values from the 1st rule.
# subtest 1. Explicit rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
2.x: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2. Explicit rules. 2nd rule.
run_make_test(q!
.SECONDEXPANSION:
all: 15.x 1.x
15.x: 5.z 6.z 5.z | 7.z 7.z 8.z
1.x: 1.z 2.z 2.z | 3.z 4.z
15.x 1.x: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=15.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=,%=
@=1.x,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 3. Grouped targets in explicit rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 15.x
15.x 1.x&: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=15.x,<=,^=,+=,|=,?=,*=,%=
@=1.x,<=,^=,+=,|=,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 4. Grouped targets in explicit rules. 2nd rule.
run_make_test(q!
.SECONDEXPANSION:
all: 15.x 1.x
15.x: 5.z 6.z 5.z | 7.z 7.z 8.z
1.x: 1.z 2.z 2.z | 3.z 4.z
15.x 1.x&: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=15.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=,%=
@=1.x,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# Double colon rules.
# Because each double colon rule is independent of the other double colon rules
# for the same target, each automatic variable in the prerequisite list, other
# than $$@, second expands to the empty string in any rule, 1st, 2nd or later.
# subtest 5. 1st double colon rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
2.x:: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 6. 2nd double colon rule.
run_make_test(q!
.SECONDEXPANSION:
all: 15.x 1.x
15.x:: 5.z 6.z 5.z | 7.z 7.z 8.z ;
1.x:: 1.z 2.z 2.z | 3.z 4.z ;
15.x 1.x:: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=15.x,<=,^=,+=,|=,?=,*=,%=
@=1.x,<=,^=,+=,|=,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# sv 62324.
# Integrity self check.
run_make_test(q!
.SECONDEXPANSION:
all: bye.x
bye.x: $$(firstword bye.1;
!, '', "#MAKEFILE#:4: *** unterminated call to function 'firstword': missing ')'. Stop.", 512);
unlink('hello.tsk', 'test.o', 'bye.tsk', 'hello.o', 'hello.h', 'hello.q', 'bye.c', 'bye.o');
# sv 62706.
# Test that makes avoids second expanding prerequisites of the targets which
# are not built.
# Here, hello.tsk is built and its prerequisites are second expanded.
# bye.tsk is not built and its prerequisites are not second expanded.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk: hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
bye.tsk: bye.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
hello.o: $$(info second expansion of $$@ prereqs); $(info $@)
bye.o: $$(info second expansion of $$@ prereqs); $(info $@)
!, 'hello.tsk',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Multipe rules per target.
run_make_test(q!
.SECONDEXPANSION:
all: hello.tsk
dep1:=hello.o
dep2:=hello.h
hello.tsk: $$(dep1)
hello.tsk: $$(dep2); $(info $@ from $^)
hello.o:; $(info $@)
hello.h:; $(info $@)
!, 'hello.tsk',
"hello.h
hello.o
hello.tsk from hello.h hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Multiple targets per rule.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk bye.tsk: hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
bye.tsk: bye.o $$(info second expansion of $$@ prereqs)
hello.o: $$(info second expansion of $$@ prereqs); $(info $@)
bye.o: $$(info second expansion of $$@ prereqs); $(info $@)
!, 'hello.tsk',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Grouped targets.
run_make_test(q!
.SECONDEXPANSION:
world.tsk: world.o $$(info 1 second expansion of $$@ prereqs)
hello.tsk world.tsk &: hello.o $$(info 2 second expansion of $$@ prereqs); $(info $@ from $<)
bye.tsk: bye.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
hello.o: $$(info second expansion of $$@ prereqs); $(info $@)
world.o: $$(info second expansion of $$@ prereqs); $(info $@)
bye.o: $$(info second expansion of $$@ prereqs); $(info $@)
!, 'hello.tsk',
"2 second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
2 second expansion of world.tsk prereqs
1 second expansion of world.tsk prereqs
second expansion of world.o prereqs
world.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Order only.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk:| hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $|)
bye.tsk:| bye.o $$(info second expansion of $$@ prereqs); $(info $@ from $|)
hello.o:| $$(info second expansion of $$@ prereqs); $(info $@)
bye.o:| $$(info second expansion of $$@ prereqs); $(info $@)
!, 'hello.tsk',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Double colon. 1 rule per target.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk:: hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
bye.tsk:: bye.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
hello.o:: $$(info second expansion of $$@ prereqs); $(info $@)
bye.o:: $$(info second expansion of $$@ prereqs); $(info $@)
!, 'hello.tsk',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Double colon. 2 rules per targets.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk:: hello.o $$(info 1 second expansion of $$@ prereqs); $(info 1 $@ from $<)
hello.tsk:: hello.o $$(info 2 second expansion of $$@ prereqs); $(info 2 $@ from $<)
bye.tsk:: bye.o $$(info 1 second expansion of $$@ prereqs); $(info 1 $@ from $<)
bye.tsk:: bye.o $$(info 2 second expansion of $$@ prereqs); $(info 2 $@ from $<)
hello.o:: $$(info 1 second expansion of $$@ prereqs); $(info 1 $@)
hello.o:: $$(info 2 second expansion of $$@ prereqs); $(info 2 $@)
bye.o:: $$(info 1 second expansion of $$@ prereqs); $(info 1 $@)
bye.o:: $$(info 2 second expansion of $$@ prereqs); $(info 2 $@)
!, 'hello.tsk',
"1 second expansion of hello.tsk prereqs
1 second expansion of hello.o prereqs
1 hello.o
2 second expansion of hello.o prereqs
2 hello.o
1 hello.tsk from hello.o
2 second expansion of hello.tsk prereqs
2 hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Test that the prerequisites of 'hello.tsk' are second expanded once.
run_make_test(q!
.SECONDEXPANSION:
all: hello.tsk hello.q
hello.tsk: hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $^)
hello.o: $$(info second expansion of $$@ prereqs); $(info $@)
hello.q: hello.tsk $$(info second expansion of $$@ prereqs); $(info $@ from $^)
!, '',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
second expansion of hello.q prereqs
hello.q from hello.tsk
#MAKE#: Nothing to be done for 'all'.\n");
# sv 62706.
# Merge vpath file and local file.
# Test that both sets of prerequisites from 'hello.c' rule and from
# 'src/hello.c' rule are second expanded.
run_make_test(q!
.SECONDEXPANSION:
vpath hello.c src
all: hello.c; $(info $@ from $^)
hello.c: $$(info second expansion of hello.c prereqs); $(info 1 $@)
src/hello.c: $$(info second expansion of src/hello.c prereqs); $(info 2 $@)
!, '',
"#MAKEFILE#:5: Recipe was specified for file 'hello.c' at #MAKEFILE#:5,
#MAKEFILE#:5: but 'hello.c' is now considered the same file as 'src/hello.c'.
#MAKEFILE#:5: Recipe for 'hello.c' will be ignored in favor of the one for 'src/hello.c'.
second expansion of src/hello.c prereqs
second expansion of hello.c prereqs
2 src/hello.c
all from src/hello.c
#MAKE#: 'all' is up to date.\n");
# sv 62706.
# .DEFAULT.
run_make_test(q!
.SECONDEXPANSION:
bye:=bye.c
all: hello.o
.DEFAULT: $$(info second expansion of prereqs of default recipe @ = $$@) ; $(info default recipe $@)
!, '',
"default recipe hello.o
#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.1');
# sv 62706.
# No side effects from second expansion of unrelated rules.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk:; exit 1
unrelated: $$(shell touch hello.1);
!, '',
"exit 1
#MAKE#: *** [#MAKEFILE#:3: hello.tsk] Error 1\n", 512);
# sv 62706.
# Second expansion of intermediate prerequisites.
# The rule to build hello.x is explicit.
# .SECONDARY marks hello.x as intermediate.
# Test that $$(deps) is secondary expanded.
run_make_test(q!
deps:=hello.h
.SECONDEXPANSION:
.SECONDARY: hello.x
all: hello.x
hello.x: $$(deps); $(info $@)
hello.h:; $(info $@)
!, '', "hello.h\nhello.x\n#MAKE#: Nothing to be done for 'all'.\n");
1;
@@ -0,0 +1,506 @@
# -*-perl-*-
$description = "Test second expansion in implicit rules.";
$details = "";
use Cwd;
$dir = cwd;
$dir =~ s,.*/([^/]+)$,../$1,;
# Test #1: automatic variables.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
foo.a: bar baz
foo.a: biz | buz
foo.%: 1.$$@ \
2.$$< \
$$(addprefix 3.,$$^) \
$$(addprefix 4.,$$+) \
5.$$| \
6.$$* ; @:
1.foo.a \
2.bar \
3.bar \
3.baz \
3.biz \
4.bar \
4.baz \
4.biz \
5.buz \
6.a: ; @echo '$@'
!,
'',
'1.foo.a
2.bar
3.bar
3.baz
3.biz
4.bar
4.baz
4.biz
5.buz
6.a
bar
baz
biz
buz
');
# Test #2: target/pattern -specific variables.
#
run_make_test(q!
.SECONDEXPANSION:
foo.x:
foo.%: $$(%_a) $$(%_b) bar ; @:
foo.x: x_a := bar
%.x: x_b := baz
bar baz: ; @echo '$@'
!,
'', "bar\nbaz\n");
# Test #3: order of prerequisites.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
all: foo bar baz
# Subtest #1
#
%oo: %oo.1; @:
foo: foo.2
foo: foo.3
foo.1: ; @echo '$@'
# Subtest #2
#
bar: bar.2
%ar: %ar.1; @:
bar: bar.3
bar.1: ; @echo '$@'
# Subtest #3
#
baz: baz.1
baz: baz.2
%az: ; @:
!,
'',
'foo.1
foo.2
foo.3
bar.1
bar.2
bar.3
baz.1
baz.2
');
# Test #4: stem splitting logic.
#
run_make_test(q!
.SECONDEXPANSION:
$(dir)/tmp/bar.o:
$(dir)/tmp/foo/bar.c: ; @echo '$@'
$(dir)/tmp/bar/bar.c: ; @echo '$@'
foo.h: ; @echo '$@'
%.o: $$(addsuffix /%.c,foo bar) foo.h ; @echo '$@: {$<} $^'
!,
"dir=$dir", "$dir/tmp/foo/bar.c
$dir/tmp/bar/bar.c
foo.h
$dir/tmp/bar.o: {$dir/tmp/foo/bar.c} $dir/tmp/foo/bar.c $dir/tmp/bar/bar.c foo.h
");
# Test #5: stem splitting logic and order-only prerequisites.
#
run_make_test(q!
.SECONDEXPANSION:
$(dir)/tmp/foo.o: $(dir)/tmp/foo.c
$(dir)/tmp/foo.c: ; @echo '$@'
bar.h: ; @echo '$@'
%.o: %.c|bar.h ; @echo '$@: {$<} {$|} $^'
!,
"dir=$dir", "$dir/tmp/foo.c
bar.h
$dir/tmp/foo.o: {$dir/tmp/foo.c} {bar.h} $dir/tmp/foo.c
");
# Test #6: lack of implicit prerequisites.
#
run_make_test(q!
.SECONDEXPANSION:
foo.o: foo.c
foo.c: ; @echo '$@'
%.o: ; @echo '$@: {$<} $^'
!,
'', "foo.c\nfoo.o: {foo.c} foo.c\n");
# Test #7: Test stem from the middle of the name.
#
run_make_test(q!
.SECONDEXPANSION:
foobarbaz:
foo%baz: % $$*.1 ; @echo '$*'
bar bar.1: ; @echo '$@'
!,
'', "bar\nbar.1\nbar\n");
# Test #8: Make sure stem triple-expansion does not happen.
#
run_make_test(q!
.SECONDEXPANSION:
foo$$bar:
f%r: % $$*.1 ; @echo '$*'
oo$$ba oo$$ba.1: ; @echo '$@'
!,
'', 'oo$ba
oo$ba.1
oo$ba
');
# Test #9: Check the value of $^
run_make_test(q!
.SECONDEXPANSION:
%.so: | $$(extra) ; @echo $^
foo.so: extra := foo.o
foo.so:
foo.o:
!,
'', "\n");
# Test #10: Test second expansion with second expansion prerequisites
# Ensures pattern_search() recurses with SE prereqs.
touch('a');
run_make_test(q!
.SECONDEXPANSION:
sim_base_rgg := just_a_name
sim_base_src := a
sim_base_f := a a a
sim_%.f: $${sim_$$*_f} ; echo $@
sim_%.src: $${sim_$$*_src} ; echo $@
sim_%: \
$$(if $$(sim_$$*_src),sim_%.src) \
$$(if $$(sim_$$*_f),sim_%.f) \
$$(if $$(sim_$$*_rgg),$$(sim_$$*_rgg).s) ; echo $@
!,
'-s sim_base', "#MAKE#: *** No rule to make target 'sim_base'. Stop.", 512);
unlink('a');
# Ensure that order-only tokens embedded in second expansions are parsed
run_make_test(q!
.SECONDEXPANSION:
PREREQS=p1|p2
P2=p2
all : foo bar
f%o: $$(PREREQS) ; @echo '$@' from '$^' and '$|'
b%r: p1|$$(P2) ; @echo '$@' from '$^' and '$|'
p% : ; : $@
!,
"", ": p1\n: p2\nfoo from p1 and p2\nbar from p1 and p2\n");
# SV 28456 : Don't reset $$< for default recipes
run_make_test(q!
.SECONDEXPANSION:
.PHONY: foo bar
foo: bar
foo: $$(info $$<)
%oo: ;
!,
'', "bar\n#MAKE#: Nothing to be done for 'foo'.\n");
# SV 54161: Expand $$* properly when it contains a path
run_make_test(q!
.SECONDEXPANSION:
%x: $$(info $$*); @echo '$*'
!,
'q/ux', "q/u\nq/u\n");
# sv 60188.
# Test that a file explicitly mentioned by the user and made by an implicit
# rule is not considered intermediate.
touch('hello.z');
# subtest 1.
# hello.x is derived from the stem and thus is an intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=.x
all: hello.z
%.z: %$$(dep) ; @echo $@
%.x: ;
!, '', "#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2.
# test.x is explicitly mentioned and thus is not an intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=test.x
all: hello.z
%.z: %.x $$(dep) ; @echo $@
%.x: ;
!, '', "hello.z\n");
# subtest 3.
# make is building hello.z and does not second expand the prerequisites of rule
# 'unrelated: $$(dep)'. '$$(dep)' stays not expanded and 'hello.x' is never
# entered to the database. Make considers 'hello.x' intermediate while building
# 'hello.z'. Because 'hello.z' is present and 'hello.x' is missing and
# 'hello.x' is intermediate, there is no need to rebuild 'hello.z'.
run_make_test(q!
.SECONDEXPANSION:
dep:=hello.x
all: hello.z
%.z: %.x; @echo $@
%.x: ;
unrelated: $$(dep)
!, '', "#MAKE#: Nothing to be done for 'all'.\n");
# subtest 4.
# Just like subtest 3. $$(dep) is not second expanded. 'hello.x' is
# intermediate.
run_make_test(q!
.SECONDEXPANSION:
dep:=hello.x
all: hello.z
%.z: %.x; @echo $@
%.x: ;
%.q: $$(dep)
!, '', "#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.z');
# sv 60188.
# Test that a file explicitly mentioned by the user and made by an implicit
# rule is not considered intermediate, even when the builtin rules are used.
touch('hello.x');
touch('hello.tsk');
# subtest 1.
# hello.z is explicitly mentioned and thus is not an intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=hello.z
all: hello.tsk
%.tsk: $$(dep) ; @echo $@
%.z : %.x ; @echo $@
!, '', "hello.z\nhello.tsk");
# subtest 2.
# hello.z is derived from the stem and thus is an intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=.z
all: hello.tsk
%.tsk: %$$(dep) ; @echo $@
%.z : %.x ; @echo $@
!, '', "#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.x');
unlink('hello.tsk');
# sv 60659. Second expansion of automatic variables inside a function in the
# prerequisite list.
# $$@ expands to the target in the 1st and following rules.
# $$* expands to the stem in the 1st and following rules.
# $$<,$$^,$$+,$$|,$$?,$$% expand to the empty string in the prerequisite list
# of the 1st rule.
# $$<,$$^,$$+,$$|,$$?,$$% in the prerequisite list of the 2nd (and following)
# rule expand to the values from the 1st rule.
# $$% cannot be used in prerequisites, because in pattern rules % is
# substituted for stem.
# subtest 1. Pattern rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
%.x: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=2
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2. Pattern rules. 2nd rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x 1.x
2.x: 5.z 6.z 5.z | 7.z 7.z 8.z
1.x: 1.z 2.z 2.z | 3.z 4.z
%.x: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=2
@=1.x,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=1
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 3. Static pattern rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
2.x: %.x: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=2
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 4. Static pattern rules. 2nd rule.
run_make_test(q!
.SECONDEXPANSION:
all: 15.x 1.x
15.x: 5.z 6.z 5.z | 7.z 7.z 8.z
1.x: 1.z 2.z 2.z | 3.z 4.z
15.x 1.x: %.x: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=15.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=15
@=1.x,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=1
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 5. Grouped targets in implicit rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
%.x %.xx&: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=2
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 6. Grouped targets in implicit rules. 2nd rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x 1.xx
2.x: 5.z 6.z 5.z | 7.z 7.z 8.z
1.xx: 1.z 2.z 2.z | 3.z 4.z
%.x %.xx&: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=2
@=1.xx,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=1
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 7. Double colon rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
%.x:: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
5.z 6.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=2
#MAKE#: Nothing to be done for 'all'.\n");
# sv 62324.
# Integrity self check.
run_make_test(q!
.SECONDEXPANSION:
all: bye.x
%.x: $$(firstword %.1;
!, '', "#MAKE#: *** unterminated call to function 'firstword': missing ')'. Stop.", 512);
# sv 62706.
# Test that makes avoids second expanding prerequisites of the rules which are
# not tried during implicit search.
# Here, make tries rules '%.tsk: %.o' and '%.o' and their prerequisites are
# second expanded.
# Rules '%.bin: %.x' and '%.x:' are not used in implicit search for 'hello.tsk'
# and 'hello.o' and their prerequisites are not expanded.
run_make_test(q!
.SECONDEXPANSION:
%.bin: %.x $$(info second expansion of $$@ prereqs); $(info $@ from $<)
%.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
%.x: $$(info second expansion of $$@ prereqs); $(info $@)
%.o: $$(info second expansion of $$@ prereqs); $(info $@)
!, '-R hello.tsk',
"second expansion of hello.o prereqs
second expansion of hello.tsk prereqs
hello.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# No side effects from second expansion of unrelated rules.
run_make_test(q!
.SECONDEXPANSION:
all: hello.tsk
%.tsk: %.o; exit 1
hello.o:;
%.q: $$(shell touch hello.1);
!, '',
"exit 1
#MAKE#: *** [#MAKEFILE#:4: hello.tsk] Error 1\n", 512);
# sv 62706.
# Second expansion of intermediate prerequisites.
# The rule to build hello.x is implicit.
# Test that $$(deps) is secondary expanded.
run_make_test(q!
deps:=hello.h
.SECONDEXPANSION:
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x: $$(deps); $(info $@)
hello.h:; $(info $@)
!, '', "hello.h\nhello.x\nhello.tsk\n#MAKE#: Nothing to be done for 'all'.\n");
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,232 @@
# -*-perl-*-
$description = "Test second expansion in static pattern rules.";
$details = "";
# Test #1: automatic variables.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
foo.a foo.b: foo.%: bar.% baz.%
foo.a foo.b: foo.%: biz.% | buz.%
foo.a foo.b: foo.%: $$@.1 \
$$<.2 \
$$(addsuffix .3,$$^) \
$$(addsuffix .4,$$+) \
$$|.5 \
$$*.6
!,
'', 'bar.a
baz.a
biz.a
buz.a
foo.a.1
bar.a.2
bar.a.3
baz.a.3
biz.a.3
bar.a.4
baz.a.4
biz.a.4
buz.a.5
a.6
');
# Test #2: target/pattern -specific variables.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
foo.x foo.y: foo.%: $$(%_a) $$($$*_b)
foo.x: x_a := bar
%.x: x_b := baz
!,
'', "bar\nbaz\n");
# Test #3: order of prerequisites.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
all: foo.a bar.a baz.a
# Subtest #1
foo.a foo.b: foo.%: foo.%.1; @:
foo.a foo.b: foo.%: foo.%.2
foo.a foo.b: foo.%: foo.%.3
# Subtest #2
bar.a bar.b: bar.%: bar.%.2
bar.a bar.b: bar.%: bar.%.1; @:
bar.a bar.b: bar.%: bar.%.3
# Subtest #3
baz.a baz.b: baz.%: baz.%.1
baz.a baz.b: baz.%: baz.%.2
baz.a baz.b: ; @:
!,
'', 'foo.a.1
foo.a.2
foo.a.3
bar.a.1
bar.a.2
bar.a.3
baz.a.1
baz.a.2
');
# Test #4: Make sure stem triple-expansion does not happen.
#
run_make_test(q!
.SECONDEXPANSION:
foo$$bar: f%r: % $$*.1 ; @echo '$*'
oo$$ba oo$$ba.1: ; @echo '$@'
!,
'', 'oo$ba
oo$ba.1
oo$ba
');
# sv 62324.
# Integrity self check.
run_make_test(q!
.SECONDEXPANSION:
all: bye.x
bye.x: %.x: $$(firstword %.1;
!, '', "#MAKEFILE#:4: *** unterminated call to function 'firstword': missing ')'. Stop.", 512);
#unlink('hello.tsk', 'bye.tsk', 'hello.o', 'hello.q', 'bye.o');
# sv 62706.
# Test that makes avoids second expanding prerequisites of the targets which
# are not built.
# Here, hello.tsk is built and its prerequisites are second expanded.
# bye.tsk is not built and its prerequisites are not second expanded.
# Static pattern rules.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
bye.tsk: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
hello.o: $$(info second expansion of $$@ prereqs); $(info $@)
bye.o: $$(info second expansion of $$@ prereqs); $(info $@)
!, 'hello.tsk',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Order only prereqs.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk: %.tsk:| %.o $$(info second expansion of $$@ prereqs); $(info $@ from $|)
bye.tsk: %.tsk:| %.o $$(info second expansion of $$@ prereqs); $(info $@ from $|)
hello.o:| $$(info second expansion of $$@ prereqs); $(info $@)
bye.o:| $$(info second expansion of $$@ prereqs); $(info $@)
!, 'hello.tsk',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Double colon. 1 rule per target.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk:: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
bye.tsk:: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<)
hello.o:: $$(info second expansion of $$@ prereqs); $(info $@)
bye.o:: $$(info second expansion of $$@ prereqs); $(info $@)
!, 'hello.tsk',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Double colon. 2 rules per target.
run_make_test(q!
.SECONDEXPANSION:
hello.tsk:: %.tsk: %.o $$(info 1 second expansion of $$@ prereqs); $(info 1 $@ from $<)
hello.tsk:: %.tsk: %.o $$(info 2 second expansion of $$@ prereqs); $(info 2 $@ from $<)
bye.tsk:: %.tsk: %.o $$(info 1 second expansion of $$@ prereqs); $(info 1 $@ from $<)
bye.tsk:: %.tsk: %.o $$(info 2 second expansion of $$@ prereqs); $(info 2 $@ from $<)
hello.o:: $$(info 1 second expansion of $$@ prereqs); $(info 1 $@)
hello.o:: $$(info 2 second expansion of $$@ prereqs); $(info 2 $@)
bye.o:: $$(info 1 second expansion of $$@ prereqs); $(info 1 $@)
bye.o:: $$(info 2 second expansion of $$@ prereqs); $(info 2 $@)
!, 'hello.tsk',
"1 second expansion of hello.tsk prereqs
1 second expansion of hello.o prereqs
1 hello.o
2 second expansion of hello.o prereqs
2 hello.o
1 hello.tsk from hello.o
2 second expansion of hello.tsk prereqs
2 hello.tsk from hello.o
#MAKE#: 'hello.tsk' is up to date.\n");
# sv 62706.
# Test that the prerequisites of 'hello.tsk' are second expanded once.
run_make_test(q!
.SECONDEXPANSION:
all: hello.tsk hello.q
hello.tsk: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $^)
hello.o: $$(info second expansion of $$@ prereqs); $(info $@)
hello.q: %.q: %.tsk $$(info second expansion of $$@ prereqs); $(info $@ from $^)
!, '',
"second expansion of hello.tsk prereqs
second expansion of hello.o prereqs
hello.o
hello.tsk from hello.o
second expansion of hello.q prereqs
hello.q from hello.tsk
#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.1');
# sv 62706.
# No side effects from second expansion of unrelated rules.
run_make_test(q!
.SECONDEXPANSION:
all: hello.tsk
hello.tsk: %.tsk: %.o; exit 1
hello.o:;
bye.tsk: %.tsk: $$(shell touch hello.1);
!, '',
"exit 1
#MAKE#: *** [#MAKEFILE#:4: hello.tsk] Error 1\n", 512);
# sv 62706.
# Second expansion of intermediate prerequisites.
# The rule to build hello.x is static pattern.
# .SECONDARY marks hello.x as intermediate.
# Test that $$(deps) is secondary expanded.
run_make_test(q!
deps:=hello.h
.SECONDEXPANSION:
.SECONDARY: hello.x
all: hello.x
hello.x: %.x: $$(deps); $(info $@)
hello.h:; $(info $@)
!, '', "hello.h\nhello.x\n#MAKE#: Nothing to be done for 'all'.\n");
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,65 @@
# -*-perl-*-
$description = "Test BSD-style shell assignments (VAR != VAL) for variables.";
$details = "";
# TEST 0: Basic shell assignment (!=).
run_make_test('
.POSIX:
demo1!=printf \' 1 2 3\n4\n\n5 \n \n 6\n\n\n\n\'
demo2 != printf \'7 8\n \'
demo3 != printf \'$$(demo2)\'
demo4 != printf \' 2 3 \n\'
demo5 != printf \' 2 3 \n\n\'
all: ; @echo "<$(demo1)> <$(demo2)> <$(demo3)> <$(demo4)> <${demo5}>"
',
'', "< 1 2 3 4 5 6 > <7 8 > <7 8 > < 2 3 > < 2 3 >\n");
# TEST 1: Handle '#' the same way as BSD make
run_make_test('
foo1!=echo bar#baz
hash != printf \'\043\'
foo2!= echo "bar$(hash)baz"
all: ; @echo "<$(foo1)> <$(hash)> <$(foo2)>"
',
'', "<bar> <#> <bar#baz>\n");
# TEST 2: shell assignment variables (from !=) should be recursive.
# Note that variables are re-evaluated later, so the shell can output
# a value like $(XYZZY) as part of !=. The $(XYZZY) will be EVALUATED
# when the value containing it is evaluated. On the negative side, this
# means if you don't want this, you need to escape dollar signs as $$.
# On the positive side, it means that shell programs can output macros
# that are then evaluated as they are traditionally evaluated.. and that
# you can use traditional macro evaluation semantics to implement !=.
run_make_test('
XYZZY = fiddle-dee-dee
dollar = $$
VAR3 != printf \'%s\' \'$(dollar)(XYZZY)\'
all: ; @echo "<$(VAR3)>"
',
'', "<fiddle-dee-dee>\n");
# TEST 3: Overrides invoke shell anyway; they just don't store the result
# in a way that is visible.
run_make_test('
override != echo abc > ,abc ; cat ,abc
all: ; @echo "<$(override)>" ; cat ,abc
',
'override=xyz', "<xyz>\nabc\n");
unlink(',abc');
1;
@@ -0,0 +1,311 @@
# -*-perl-*-
$description = "Test handling of static pattern rules.";
$details = "\
The makefile created in this test has three targets. The
filter command is used to get those target names ending in
.o and statically creates a compile command with the target
name and the target name with .c. It also does the same thing
for another target filtered with .elc and creates a command
to emacs a .el file";
&touch('bar.c', 'lose.c');
# TEST #0
# -------
run_make_test('
files = foo.elc bar.o lose.o
$(filter %.o,$(files)): %.o: %.c ; @echo CC -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el ; @echo emacs $<
',
'',
'CC -c bar.c -o bar.o');
# TEST #1
# -------
run_make_test(undef, 'lose.o', 'CC -c lose.c -o lose.o');
# TEST #2
# -------
&touch("foo.el");
run_make_test(undef, 'foo.elc', 'emacs foo.el');
# Clean up after the first tests.
unlink('foo.el', 'bar.c', 'lose.c');
# TEST #3 -- PR/1670: don't core dump on invalid static pattern rules
# -------
run_make_test('
.DEFAULT: ; @echo $@
foo: foo%: % %.x % % % y.% % ; @echo $@
',
'', ".x\ny.\nfoo");
# TEST #4 -- bug #12180: core dump on a stat pattern rule with an empty
# prerequisite list.
run_make_test('
foo.x bar.x: %.x : ; @echo $@
',
'', 'foo.x');
# TEST #5 -- bug #13881: double colon static pattern rule does not
# substitute %.
run_make_test('
foo.bar:: %.bar: %.baz
foo.baz: ;@:
',
'', '');
# TEST #6: make sure the second stem does not overwrite the first
# perprerequisite's stem (Savannah bug #16053).
#
run_make_test('
.RECIPEPREFIX := >
all.foo.bar: %.foo.bar: %.one
all.foo.bar: %.bar: %.two
all.foo.bar:
> @echo $*
> @echo $^
.DEFAULT:;@:
',
'',
'all.foo
all.one all.foo.two');
# TEST #7: make sure the second stem does not overwrite the first
# perprerequisite's stem when second expansion is enabled
# (Savannah bug #16053).
#
run_make_test('
.RECIPEPREFIX := >
.SECONDEXPANSION:
all.foo.bar: %.foo.bar: %.one $$*-one
all.foo.bar: %.bar: %.two $$*-two
all.foo.bar:
> @echo $*
> @echo $^
.DEFAULT:;@:
',
'',
'all.foo
all.one all-one all.foo.two all.foo-two');
# Test #8:
# sv 60188.
# Static pattern rules are considered explicit rules: no prerequisite of
# a static pattern rule can ever be considered intermediate.
touch('hello.z');
# subtest 1
run_make_test(q!
hello.z: %.z: %.x ; @echo $@
%.x: ;
!, '', "hello.z\n");
# subtest 2
run_make_test(q!
hello.z: %.z: %.x test.x ; @echo $@
%.x: ;
!, '', "hello.z\n");
# subtest 3
# 'hello.x' is mentioned explicitly on an unrelated rule.
run_make_test(q!
hello.z: %.z: %.x ; @echo $@
%.x: ;
unrelated: hello.x
!, '', "hello.z\n");
unlink('hello.z');
# sv 17374 Ensure double-colon static pattern rules work
touch(qw(a.src b.src));
run_make_test(q!
all: a.tgt b.tgt
a.tgt b.tgt:: %.tgt : %.src ; cp $< $@
!,
'', "cp a.src a.tgt\ncp b.src b.tgt\n");
unlink(qw(a.src b.src a.tgt b.tgt));
my @dir = ('', 'lib/'); # With and without last slash.
my @secondexpansion = ('', '.SECONDEXPANSION:');
# The following combinations are generated with and without second expansion.
# 1.
# all: bye.x
# bye.x: %.x: ...
#
# 2.
# all: lib/bye.x
# lib/bye.x: %.x: ...
#
# 3.
# all: lib/bye.x
# lib/bye.x: lib/%.x: ...
#
# The following combination is not generated, because there is no rule to
# build bye.x, no stem substitution takes place, not of interest of this test.
# 4.
# all: bye.x
# bye.x: lib/%.x: ...
#
for my $se (@secondexpansion) {
for my $d (@dir) { # The directory of the prerequisite of 'all'.
for my $r (@dir) { # The directory of the prerequisite in the rule definition.
(!$d && $r) && next; # Combination 4.
my $dollar = $se ? '$' : '';
# The prerequisite should only have directory if the prerequisite of 'all' has
# it and if the prequisite pattern in the rule definition does not have it.
# That is combination 2.
my $pdir = $d && !$r ? $d : '';
# One func, one %.
my $prereqs = "${pdir}bye.1";
run_make_test("
$se
.PHONY: $prereqs
all: ${d}bye.x
${d}bye.x: $r%.x: $dollar\$(firstword %.1); \$(info \$@ from \$^)
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
# Multiple funcs, each has one %.
$prereqs = "${pdir}bye.1 ${pdir}bye.2";
run_make_test("
$se
.PHONY: $prereqs
all: ${d}bye.x
${d}bye.x: $r%.x: $dollar\$(firstword %.1) $dollar\$(firstword %.2); \$(info \$@ from \$^)
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
# Multiple funcs, each has multiple %.
$prereqs = "${pdir}bye.1 ${pdir}bye.2 ${pdir}bye.3 ${pdir}bye.4";
run_make_test("
$se
.PHONY: $prereqs
all: ${d}bye.x
${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, %.1 %.2) $dollar\$(wordlist 1, 99, %.3 %.4); \$(info \$@ from \$^)
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
# Multiple funcs, each has multiple %, each prerequisite has multiple %.
$prereqs = "${pdir}bye_%_%.1 ${pdir}bye_%_%.2 ${pdir}bye_%_%.3 ${pdir}bye_%_%.4";
run_make_test("
$se
.PHONY: $prereqs
all: ${d}bye.x
${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, %_%_%.1 %_%_%.2) $dollar\$(wordlist 1, 99, %_%_%.3 %_%_%.4); \$(info \$@ from \$^)
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
# Nested functions.
$prereqs = "${pdir}bye.1 ${pdir}bye.2 ${pdir}bye.3 ${pdir}bye.4";
run_make_test("
$se
.PHONY: $prereqs
all: ${d}bye.x
${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, $dollar\$(wordlist 1, 99, %.1 %.2)) $dollar\$(wordlist 1, 99, $dollar\$(wordlist 1,99, %.3 %.4)); \$(info \$@ from \$^)
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
# Multiple funcs, each has multiple words, each word has multiple %, sole %,
# various corner cases.
# Make should substitude the first % and only the first % in each word with the
# stem.
$prereqs = "${pdir}bye1%2% ${pdir}bye 3${pdir}bye4%5 6${pdir}bye ${pdir}bye7%8 ${pdir}bye9 ${pdir}bye10% 11${pdir}bye12 13";
run_make_test("
$se
.PHONY: $prereqs
all: ${d}bye.x
${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, %1%2% % 3%4%5 6%) %7%8 %9 $dollar\$(wordlist 1, 99, %10% 11%12) 13; \$(info \$@ from \$^)
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
if ($port_type eq 'UNIX') {
# Test that make does not use some hardcoded array of a finite size on stack.
# Long prerequisite name. This prerequisite name is over 66K long.
my $prefix = 'abcdefgh' x 128 x 33; # 33K long.
my $suffix = 'stuvwxyz' x 128 x 33; # 33K long.
$prereqs = "${prefix}${pdir}bye${suffix}.1 ${prefix}${pdir}bye${suffix}.2";
run_make_test("
$se
.PHONY: $prereqs
all: ${d}bye.x
${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, ${prefix}%${suffix}.1 ${prefix}%${suffix}.2); \$(info \$@ from \$^)
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
}
# Empty stem.
$prereqs = "${pdir}.1";
run_make_test("
$se
.PHONY: $prereqs
all: ${d}bye.x
${d}bye.x: $r%bye.x: $dollar\$(firstword %.1); \$(info \$@ from \$^)
", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
# A word expands to an empty prerequisite.
run_make_test("
$se
all: ${d}bye.x
${d}bye.x: $r%.x: $dollar\$(%); \$(info \$@ from \$^)
", '', "${d}bye.x from \n#MAKE#: Nothing to be done for 'all'.\n");
}
}
}
# Escaped %.
# The following combinations are generated without second expansion.
# 1.
# all: the%weird\\_hello_pattern\\.x
# the\\%weird\\_hello_pattern\\.x: the\\%weird\\_%_pattern\\.x: ...
#
# 2.
# all: lib/the%weird\\_hello_pattern\\.x
# lib/the\\%weird\\_hello_pattern\\.x: lib/the\\%weird\\_%_pattern\\.x: ...
#
# Other combinations or second expansion are not tested, because escaped % is
# not implemented for those.
for my $d (@dir) {
my $prereqs = "${d}the%weird\\\\_hello_pattern%\\\\.1 ${d}the%weird\\\\_hello_pattern%\\\\.2";
run_make_test("
.PHONY: $prereqs
all: ${d}the%weird\\\\_hello_pattern\\\\.x
${d}the\\%weird\\\\_hello_pattern\\\\.x: ${d}the\\%weird\\\\_%_pattern\\\\.x: \$(wordlist 1, 99, ${d}the\\%weird\\\\_%_pattern%\\\\.1 ${d}the\\%weird\\\\_%_pattern%\\\\.2); \$(info \$@ from \$^)
", '', "${d}the%weird\\\\_hello_pattern\\\\.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n");
}
1;
@@ -0,0 +1,99 @@
# -*-perl-*-
$description = "Test suffix rules.";
$details = "";
# TEST #0: Clear all suffixes
touch('foo.c');
run_make_test(q!
.SUFFIXES:
all: foo.o ; @echo $@ $<
!,
'', "#MAKE#: *** No rule to make target 'foo.o', needed by 'all'. Stop.\n", 512);
unlink('foo.c');
# Test #1: Add a simple suffix rule
touch('foo.baz');
run_make_test(q!
.SUFFIXES: .biz .baz
.baz.biz: ; @echo make $@
!,
'foo.biz', "make foo.biz\n");
unlink('foo.baz');
# Test #2: Make sure the defaults still work
touch('foo.c');
run_make_test(undef, 'foo.o COMPILE.c=@echo OUTPUT_OPTION=', "foo.c\n");
unlink('foo.c');
# Test #3: Replacing all suffixes
touch('foo.baz');
run_make_test(q!
.SUFFIXES:
.SUFFIXES: .biz .baz
.baz.biz: ; @echo make $@
!,
'foo.biz', "make foo.biz\n");
unlink('foo.baz');
# SV 40657: Test #4: "Suffix rules" with deps are normal rules
my $prewarn = 'warning: ignoring prerequisites on suffix rule definition';
touch('foo.bar');
run_make_test(q!
.SUFFIXES:
.SUFFIXES: .biz .baz
$X.POSIX:
.baz.biz: foo.bar ; @echo make $@ from $<
!,
'X=1 .baz.biz', "#MAKEFILE#:7: $prewarn\nmake .baz.biz from foo.bar\n");
# SV 40657: Test #5: In POSIX mode we don't get a warning
run_make_test(undef, 'X= .baz.biz', "make .baz.biz from foo.bar\n");
unlink('foo.bar');
# SV 40657: Test #6: In POSIX mode, no pattern rules should be created
utouch(-20, 'foo.baz');
run_make_test(undef,
'X= foo.biz', "#MAKE#: *** No rule to make target 'foo.biz'. Stop.\n", 512);
# SV 40657: Test #7: In Non-POSIX mode, a pattern rule is created
run_make_test(undef,
'X=1 foo.biz', "#MAKEFILE#:7: $prewarn\nmake foo.biz from foo.baz\n");
# SV 40657: Test #8: ... but any prerequisites are ignored
utouch(-10, 'foo.biz');
touch('foo.bar');
run_make_test(undef,
'X=1 foo.biz', "#MAKEFILE#:7: $prewarn\n#MAKE#: 'foo.biz' is up to date.\n");
unlink('foo.baz', 'foo.biz', 'foo.bar');
# Complete
1;
@@ -0,0 +1,439 @@
# -*-perl-*-
$description = "Test target-specific variable settings.";
$details = "\
Create a makefile containing various flavors of target-specific variable
values, override and non-override, and using various variable expansion
rules, semicolon interference, etc.";
run_make_test('
export FOO = foo
export BAR = bar
one: override FOO = one
one two: ; @echo $(FOO) $(BAR)
two: BAR = two
.RECIPEPREFIX = >
three: ; BAR=1000
> @echo $(FOO) $(BAR)
# Some things that shouldn not be target vars
funk : override
funk : override adelic
adelic override : ; echo $@
# Test per-target recursive variables
four:FOO=x
four:VAR$(FOO)=ok
four: ; @echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx)"
five:FOO=x
five six : VAR$(FOO)=good
five six: ;@echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx) $(VARfoo)"
# Test per-target variable inheritance
seven: eight
seven eight: ; @echo $@: $(FOO) $(BAR)
seven: BAR = seven
seven: FOO = seven
eight: BAR = eight
# Test the export keyword with per-target variables
nine: ; @echo $(FOO) $(BAR) $$FOO $$BAR
nine: FOO = wallace
nine-a: export BAZ = baz
nine-a: ; @echo $$BAZ
# Test = escaping
EQ = =
ten: one$(EQ)two
ten: one $(EQ) two
ten one$(EQ)two $(EQ):;@echo $@
.PHONY: one two three four five six seven eight nine ten $(EQ) one$(EQ)two
# Test target-specific vars with pattern/suffix rules
QVAR = qvar
RVAR = =
%.q : ; @echo $(QVAR) $(RVAR)
foo.q : RVAR += rvar
# Target-specific vars with multiple LHS pattern rules
%.r %.s %.t: ; @echo $(QVAR) $(RVAR) $(SVAR) $(TVAR)
foo.r : RVAR += rvar
foo.t : TVAR := $(QVAR)
',
"one two three", "one bar\nfoo two\nBAR=1000\nfoo bar\n");
# TEST #2
run_make_test(undef, "one two FOO=1 BAR=2", "one 2\n1 2\n");
# TEST #3
run_make_test(undef, "four", "x ok ok\n");
# TEST #4
run_make_test(undef, "seven", "eight: seven eight\nseven: seven seven\n");
# TEST #5
run_make_test(undef, "nine", "wallace bar wallace bar\n");
# TEST #5-a
run_make_test(undef, "nine-a", "baz\n");
# TEST #6
run_make_test(undef, "ten", "one=two\none bar\n=\nfoo two\nten\n");
# TEST #6
run_make_test(undef, "foo.q bar.q", "qvar = rvar\nqvar =\n");
# TEST #7
run_make_test(undef, "foo.t bar.s", "qvar = qvar\nqvar =\n");
# TEST #8
# For PR/1378: Target-specific vars don't inherit correctly
run_make_test('
foo: FOO = foo
bar: BAR = bar
foo: bar
bar: baz
baz: ; @echo $(FOO) $(BAR)
', "", "foo bar\n");
# TEST #9
# For PR/1380: Using += assignment in target-specific variables sometimes fails
# Also PR/1831
run_make_test('
.PHONY: all one
all: FOO += baz
all: one; @echo $(FOO)
FOO = bar
one: FOO += biz
one: FOO += boz
one: ; @echo $(FOO)
',
'', "bar baz biz boz\nbar baz\n");
# Test #10
run_make_test(undef, 'one', "bar biz boz\n");
# Test #11
# PR/1709: Test semicolons in target-specific variable values
run_make_test('
foo : FOO = ; ok
foo : ; @echo "$(FOO)"
',
'', "; ok\n");
# Test #12
# PR/2020: More hassles with += target-specific vars. I _really_ think
# I nailed it this time :-/.
run_make_test('
.PHONY: a
BLAH := foo
COMMAND = echo $(BLAH)
a: ; @$(COMMAND)
a: BLAH := bar
a: COMMAND += snafu $(BLAH)
',
'', "bar snafu bar\n");
# Test #13
# Test double-colon rules with target-specific variable values
run_make_test('
W = bad
X = bad
foo: W = ok
foo:: ; @echo $(W) $(X) $(Y) $(Z)
foo:: ; @echo $(W) $(X) $(Y) $(Z)
foo: X = ok
Y = foo
bar: foo
bar: Y = bar
Z = nopat
ifdef PATTERN
fo% : Z = pat
endif
',
'foo', "ok ok foo nopat\nok ok foo nopat\n");
# Test #14
# Test double-colon rules with target-specific variable values and
# inheritance
run_make_test(undef, 'bar', "ok ok bar nopat\nok ok bar nopat\n");
# Test #15
# Test double-colon rules with pattern-specific variable values
run_make_test(undef, 'foo PATTERN=yes', "ok ok foo pat\nok ok foo pat\n");
# Test #16
# Test target-specific variables with very long command line
# (> make default buffer length)
run_make_test('
base_metals_fmd_reports.sun5 base_metals_fmd_reports CreateRealPositions CreateMarginFunds deals_changed_since : BUILD_OBJ=$(shell if test -f "build_information.generate" ; then echo "$(OBJ_DIR)/build_information.o"; else echo "no build information"; fi )
deals_changed_since: ; @echo $(BUILD_OBJ)
',
'', "no build information\n");
# TEST #17
# Test a merge of set_lists for files, where one list is much longer
# than the other. See Savannah bug #15757.
mkdir('t1', 0777);
touch('t1/rules.mk');
run_make_test('
VPATH = t1
include rules.mk
.PHONY: all
all: foo.x
foo.x : rules.mk ; @echo MYVAR=$(MYVAR) FOOVAR=$(FOOVAR) ALLVAR=$(ALLVAR)
all: ALLVAR = xxx
foo.x: FOOVAR = bar
rules.mk : MYVAR = foo
.INTERMEDIATE: foo.x rules.mk
',
'-I t1', 'MYVAR= FOOVAR=bar ALLVAR=xxx');
rmfiles('t1/rules.mk');
rmdir('t1');
# TEST #18
# Test appending to a simple variable containing a "$": avoid a
# double-expansion. See Savannah bug #15913.
run_make_test('
VAR := $$FOO
foo: VAR += BAR
foo: ; @echo '."'".'$(VAR)'."'".'
',
'', '$FOO BAR');
# TEST #19: Override with append variables
run_make_test('
a: override FOO += f1
a: FOO += f2
a: ; @echo "$(FOO)"
',
'', "f1\n");
run_make_test(undef, 'FOO=C', "C f1\n");
# TEST #19: Conditional variables with command-line settings
run_make_test('
a: FOO ?= f1
a: ; @echo "$(FOO)"
',
'', "f1\n");
run_make_test(undef, 'FOO=C', "C\n");
# TEST #20: Check for continuation after semicolons
run_make_test(q!
a: A = 'hello;\
world'
a: ; @echo $(A)
!,
'', "hello; world\n");
# TEST #21: SV-56834 Ensure setting PATH in a target var works properly
my $sname = "foobar$scriptsuffix";
mkdir('sd', 0775);
create_file("sd/$sname", "exit 0\n");
chmod 0755, "sd/$sname";
run_make_test(qq!
all: PATH := sd
all: ; $sname >/dev/null
!,
'', "$sname >/dev/null\n");
# Don't use the general PATH if not found on the target path
$ENV{PATH} = "$ENV{PATH}:sd";
my ($ernum, $erstr);
if ($port_type eq 'W32') {
$ernum = 1;
$erstr = "'$sname' is not recognized as an internal or external command,\noperable program or batch file.";
} else {
$ernum = 127;
$erstr = "#MAKE#: $sname: $ERR_no_such_file";
}
run_make_test(qq!
all: PATH := ..
all: ; $sname
!,
'', "$sname\n$erstr\n#MAKE#: *** [#MAKEFILE#:3: all] Error $ernum", 512);
unlink("sd/$sname");
rmdir ('sd');
# SV 59230: Conditional (non-)assignment of target-specific variables should
# preserve export settings.
$ENV{hello} = 'moon';
run_make_test(q!
all:; @echo hello=$$hello
dummy: hello?=world
!,
'', 'hello=moon');
# SV 59230: Assignment of a global variable should not affect export of a
# target specific variable.
$ENV{hello} = "moon";
run_make_test(q!
all:; @echo hello=$$hello
hello=sun
dummy: hello?=world
!,
'', 'hello=sun');
# Support target-specific unexport
$ENV{hello} = "moon";
run_make_test(q!
unexport hello=sun
all: base exp
base exp: ; @echo hello=$$hello
exp: export hello=world
!,
'', "hello=\nhello=world\n");
$ENV{hello} = "moon";
run_make_test(q!
hello=sun
all: base exp
base exp: ; @echo hello=$$hello
exp: unexport hello=world
!,
'', "hello=sun\nhello=\n");
run_make_test(q!
all:; @echo hello=$$hello
unexport hello=sun
dummy: hello?=world
!,
'', 'hello=');
$ENV{hello} = "moon";
run_make_test(q!
all:; @echo hello=$$hello
hello=sun
dummy: unexport hello=world
!,
'', 'hello=sun');
run_make_test(q!
all: mid
mid: base
ifeq ($(midexport),export)
mid: export hello=mid
else ifeq ($(midexport),unexport)
mid: unexport hello=mid
else
mid: hello=mid
endif
ifeq ($(baseexport),export)
base: export hello=base
else ifeq ($(baseexport),unexport)
base: unexport hello=base
else
base: hello=base
endif
all mid base:; @echo $@ make=$(hello) shell=$$hello
!,
'', "base make=base shell=\nmid make=mid shell=\nall make= shell=\n");
# Test base settings with env var
$ENV{hello} = "environ";
run_make_test(undef,
'', "base make=base shell=base\nmid make=mid shell=mid\nall make=environ shell=environ\n");
$ENV{hello} = "environ";
run_make_test(undef,
'baseexport=export', "base make=base shell=base\nmid make=mid shell=mid\nall make=environ shell=environ\n");
$ENV{hello} = "environ";
run_make_test(undef,
'baseexport=unexport', "base make=base shell=\nmid make=mid shell=mid\nall make=environ shell=environ\n");
# Test mid settings with env var
$ENV{hello} = "environ";
run_make_test(undef,
'midexport=export', "base make=base shell=base\nmid make=mid shell=mid\nall make=environ shell=environ\n");
$ENV{hello} = "environ";
run_make_test(undef,
'midexport=export baseexport=unexport', "base make=base shell=\nmid make=mid shell=mid\nall make=environ shell=environ\n");
$ENV{hello} = "environ";
run_make_test(undef,
'midexport=unexport', "base make=base shell=\nmid make=mid shell=\nall make=environ shell=environ\n");
$ENV{hello} = "environ";
run_make_test(undef,
'midexport=unexport baseexport=export', "base make=base shell=base\nmid make=mid shell=\nall make=environ shell=environ\n");
# Test base settings without env var
run_make_test(undef,
'baseexport=export', "base make=base shell=base\nmid make=mid shell=\nall make= shell=\n");
run_make_test(undef,
'baseexport=unexport', "base make=base shell=\nmid make=mid shell=\nall make= shell=\n");
# Test mid settings with env var
run_make_test(undef,
'midexport=export', "base make=base shell=base\nmid make=mid shell=mid\nall make= shell=\n");
run_make_test(undef,
'midexport=export baseexport=unexport', "base make=base shell=\nmid make=mid shell=mid\nall make= shell=\n");
run_make_test(undef,
'midexport=unexport', "base make=base shell=\nmid make=mid shell=\nall make= shell=\n");
run_make_test(undef,
'midexport=unexport baseexport=export', "base make=base shell=base\nmid make=mid shell=\nall make= shell=\n");
# TEST #19: Test define/endef variables as target-specific vars
# run_make_test('
# define b
# @echo global
# endef
# a: define b
# @echo local
# endef
# a: ; $(b)
# ',
# '', "local\n");
1;
@@ -0,0 +1,118 @@
# -*-mode: perl-*-
$description = "Test handling of temporary file created from stdin.";
# These tests rely on the test_driver checking for leftover temporary content
create_file('input.mk', "world:=1\n");
create_file('bye.mk', "moon:=2\n");
# sv 62118,62145.
# Test that makes leaves no temp file when make code is piped to stdin and -v,
# -h or an invalid option is specified.
my @opts = ('-v', '-h', '--nosuchopt');
my @exit_codes = (0, 0, 512);
for my $i (0 .. $#opts) {
close(STDIN);
open(STDIN, "<", 'input.mk') || die "$0: cannot open input.mk for reading: $!";
run_make_test(q!
all:; $(info hello world)
!,
"$opts[$i] -f-", "/uilt for /", $exit_codes[$i]);
}
# sv 62118,62145.
# Test that a stdin temp file is removed.
close(STDIN);
open(STDIN, "<", 'input.mk') || die "$0: cannot open input.mk for reading: $!";
run_make_test(q!
all:; $(info world=$(world))
!,
'-f-', "world=1\n#MAKE#: 'all' is up to date.\n");
# sv 62118,62145.
# Test that a stdin temp file is removed, even when make re-execs.
# Also test that make honors TMPDIR to create the temp file.
# Ensure touching bye.mk causes re-exec.
&utouch(-600, 'bye.mk');
close(STDIN);
open(STDIN, "<", 'input.mk') || die "$0: cannot open input.mk for reading: $!";
run_make_test(q!
include bye.mk
all:; $(info hello)
$(MAKE_RESTARTS)bye.mk: force; touch $@
force:
!,
'-R --debug=b -f-', "/Re-executing.+?--temp-stdin=\Q$temppath\E/");
if ($port_type eq 'UNIX') {
# POSIX doesn't require sh to set PPID so test this
my $cmd = create_command();
add_options($cmd, '-f', '/dev/null', '-E', q!all:;@echo $$PPID!);
my $fout = 'ppidtest.out';
run_command_with_output($fout, @$cmd);
$_ = read_file_into_string($fout);
chomp($_);
if (/^[0-9]+$/) {
use POSIX ();
# sv 63157.
# Test that make removes the temporary file which holds make code from stdin,
# even when a signal is received.
# include bye.mk and bye.mk: rule is needed to cause make to keep the temporary
# file for re-exec. Without re-exec make will remove the file before the signal
# arrives.
# sleep is needed to let make write its "... Terminated" message to the log
# file.
&utouch(-600, 'bye.mk');
close(STDIN);
open(STDIN, "<", 'input.mk') || die "$0: cannot open input.mk for reading: $!";
run_make_test(q!
include bye.mk
pid:=$(shell echo $$PPID)
all:;
bye.mk: force; @kill -TERM $(pid) && sleep 16
force:
!, '-f-', '/#MAKE#: \*\*\* \[#MAKEFILE#:5: bye.mk] Terminated/', POSIX::SIGTERM);
}
unlink($fout);
# sv 62118,62145.
# Test that a stdin temp file is removed, when execvp fails to re-exec make.
# In order to cause execvp to fail, copy the tested make binary to the temp
# directory and take away the 'x' bit.
use File::Spec;
use File::Copy;
my $tmakedir = File::Spec->catfile($cwdpath, 'tmakedir');
mkdir($tmakedir, 0770);
my $makecopy = File::Spec->catfile($tmakedir, 'make');
copy("$mkpath", $makecopy);
# Set file mode bits, because perl copy won't.
chmod 0700, $makecopy;
my @make_orig = @make_command;
@make_command = ($makecopy);
# Ensure touching bye.mk causes re-exec.
&utouch(-600, 'bye.mk');
close(STDIN);
open(STDIN, "<", 'input.mk') || die "$0: cannot open input.mk for reading: $!";
run_make_test("
include bye.mk
all:; \$(info hello)
\$(MAKE_RESTARTS)bye.mk: force; touch \$@ && chmod u-x $makecopy
force:
",
"-f-", "touch bye.mk && chmod u-x $makecopy\nmake: $makecopy: $ERR_nonexe_file\n", 32512);
@make_command = @make_orig;
unlink($makecopy);
rmdir($tmakedir);
}
close(STDIN);
unlink('input.mk', 'bye.mk');
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,11 @@
# -*-perl-*-
$description = "Test support for UTF-8.";
$details = "";
# Verify that the UTF-8 BOM is ignored.
run_make_test("\xEF\xBB\xBFall: ; \@echo \$\@\n", '', "all");
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,27 @@
# -*-perl-*-
$description = "Test recursive variables";
$details = "";
run_make_test('
x = variable1
variable2 := Hello
y = $(subst 1,2,$(x))
z = y
a := $($($(z)))
all: ; @echo $(a)
',
'', "Hello\n");
# This tests resetting the value of a variable while expanding it.
# You may only see problems with this if you're using valgrind or
# some other memory checker that poisons freed memory.
# See Savannah patch #7534
run_make_test('
VARIABLE = $(eval VARIABLE := echo hi)$(VARIABLE)
wololo: ; @$(VARIABLE)
',
'', "hi\n");
1;
@@ -0,0 +1,114 @@
# -*-perl-*-
$description = "Test vpath for particular classes of filenames.";
$details = "";
@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h",
"$workdir${pathsep}kbd.c","$workdir${pathsep}command.h",
"$workdir${pathsep}commands.c","$workdir${pathsep}display.c",
"$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c",
"$workdir${pathsep}command.c");
&touch(@files_to_touch);
run_make_test(q!
vpath %.c foo
vpath %.c #WORK#
vpath %.h #WORK#
objects = main.o kbd.o commands.o display.o insert.o
edit: $(objects) ; @echo cc -o $@ $^
main.o : main.c defs.h ; @echo cc -c $(firstword $^)
kbd.o : kbd.c defs.h command.h ; @echo cc -c kbd.c
commands.o : command.c defs.h command.h ; @echo cc -c commands.c
display.o : display.c defs.h buffer.h ; @echo cc -c display.c
insert.o : insert.c defs.h buffer.h ; @echo cc -c insert.c
!,
'', "cc -c $workdir${pathsep}main.c\ncc -c kbd.c\ncc -c commands.c\n"
."cc -c display.c\ncc -c insert.c\n"
."cc -o edit main.o kbd.o commands.o display.o insert.o\n");
unlink(@files_to_touch);
# TEST 2: after vpath lookup ensure we don't get incorrect circular dependency
# warnings due to change of struct file ptr. Savannah bug #13529.
mkdir('vpath-d', 0777);
run_make_test(q!
vpath %.te vpath-d/
.SECONDARY:
default: vpath-d/a vpath-d/b
vpath-d/a: fail.te
vpath-d/b : fail.te
vpath-d/fail.te:
!,
'', "#MAKE#: Nothing to be done for 'default'.\n");
rmdir('vpath-d');
# Test VPATH vs vpath
run_make_test(q!
VPATH = #WORK#:#PWD#
vpath %.c foo
vpath %.c #WORK#
vpath %.c #PWD#
vpath %.h #WORK#
vpath %.c
vpath
all: ; @echo ALL IS WELL
!,
'', "ALL IS WELL\n");
# Test interaction of -lfoo and vpath
my @dirs_to_make = qw(a1 b1 a2 b2 b3);
for my $d (@dirs_to_make) {
mkdir($d, 0777);
}
my @files_to_touch = ("a1${pathsep}lib1.a",
"a1${pathsep}libc.a",
"b1${pathsep}lib1.so",
"a2${pathsep}lib2.a",
"b2${pathsep}lib2.so",
"lib3.a",
"b3${pathsep}lib3.so");
&touch(@files_to_touch);
my $answer = "a1${pathsep}lib1.a a1${pathsep}libc.a " .
"a2${pathsep}lib2.a lib3.a\n";
if ($port_type eq 'VMS-DCL') {
$answer =~ s/ /,/g;
}
run_make_test('
vpath %.h b3
vpath %.a a1
vpath %.so b1
vpath % a2 b2
vpath % b3
all: -l1 -lc -l2 -l3; @echo $^
',
'', $answer);
unlink(@files_to_touch);
for my $d (@dirs_to_make) {
rmdir($d);
}
# Check that if we find find files with VPATH, we don't do pattern search
mkdir("vpa");
run_make_test(q!
VPATH = vpa
%.x: ; @echo pattern $@
vpa/foo.x: ; @echo vpath $@
!,
'foo.x', "vpath vpa/foo.x\n");
rmdir("vpa");
1;
@@ -0,0 +1,66 @@
# -*-perl-*-
$description = "Tests VPATH+/GPATH functionality.";
$details = "";
$VP = "$workdir$pathsep";
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "VPATH = $VP\n";
print MAKEFILE <<'EOMAKE';
GPATH = $(VPATH)
.SUFFIXES: .a .b .c .d
.PHONY: general rename notarget intermediate
%.a:
%.b:
%.c:
%.d:
%.a : %.b ; cat $^ > $@
%.b : %.c ; cat $^ > $@
%.c :: %.d ; cat $^ > $@
# General testing info:
general: foo.b
foo.b: foo.c bar.c
EOMAKE
close(MAKEFILE);
@touchedfiles = ();
$off = -500;
sub gtouchfiles {
foreach (@_) {
($f = $_) =~ s,VP/,$VP,g;
&utouch($off, $f);
$off += 10;
push(@touchedfiles, $f);
}
}
# Run the general-case test
&gtouchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d");
&run_make_with_options($makefile,"general",&get_logfile());
push(@touchedfiles, "bar.c");
$answer = "$make_name: Nothing to be done for 'general'.\n";
&compare_output($answer,&get_logfile(1));
unlink(@touchedfiles) unless $keep;
1;
@@ -0,0 +1,88 @@
# -*-perl-*-
$description = "Tests the new VPATH+ functionality added in 3.76.";
$details = "";
$VP = "$workdir$pathsep";
@touchedfiles = ();
$off = -500;
sub touchfiles {
foreach (@_) {
&utouch($off, $_);
$off += 10;
push(@touchedfiles, $_);
}
}
&touchfiles("$VP/foo.d", "$VP/bar.d", "$VP/foo.c", "$VP/bar.c", "foo.b", "bar.d");
# Run the general-case test
run_make_test(qq!VPATH = $VP! . q!
.SUFFIXES: .a .b .c .d
.PHONY: general rename notarget intermediate
%.a:
%.b:
%.c:
%.d:
%.a : %.b ; cat $^ > $@
%.b : %.c ; cat $^ > $@ 2>/dev/null || exit 1
%.c :: %.d ; cat $^ > $@
# General testing info:
general: foo.b
foo.b: foo.c bar.c
# Rename testing info:
rename: $(VPATH)/foo.c foo.d
# Target not made testing info:
notarget: notarget.b
notarget.c: notarget.d ; -@echo "not creating $@ from $^"
# Intermediate files:
intermediate: inter.a
!,
'general', "cat bar.d > bar.c\ncat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1\n");
push(@touchedfiles, "bar.c");
# Test rules that don't make the target correctly
&touchfiles("$VP/notarget.c", "notarget.b", "notarget.d");
run_make_test(undef, 'notarget', "not creating notarget.c from notarget.d\ncat notarget.c > notarget.b 2>/dev/null || exit 1\n#MAKE#: *** [#MAKEFILE#:11: notarget.b] Error 1\n", 512);
# Test intermediate file handling (part 1)
&touchfiles("$VP/inter.d");
my $be = pack("L", 1) eq pack("N", 1);
my $intfiles = $be ? "inter.c inter.b" : "inter.b inter.c";
run_make_test(undef, 'intermediate', "cat ${VP}inter.d > inter.c\ncat inter.c > inter.b 2>/dev/null || exit 1\ncat inter.b > inter.a\nrm $intfiles\n");
push(@touchedfiles, "inter.a", "inter.b");
# Test intermediate file handling (part 2)
&utouch(-20, "inter.a");
&utouch(-10, "$VP/inter.b");
&touch("$VP/inter.d");
run_make_test(undef, 'intermediate', "cat ${VP}inter.d > inter.c\ncat inter.c > inter.b 2>/dev/null || exit 1\ncat inter.b > inter.a\nrm inter.c\n");
push(@touchedfiles, "$VP/inter.b", "$VP/inter.d");
unlink @touchedfiles unless $keep;
1;
@@ -0,0 +1,84 @@
# -*-perl-*-
$description = "Test the abspath functions.";
$details = "";
# Someone needs to rewrite this to be portable for Windows
$port_type eq 'W32' and return -1;
run_make_test('
ifneq ($(realpath $(abspath .)),$(CURDIR))
$(warning .: abs="$(abspath .)" real="$(realpath $(abspath .))" curdir="$(CURDIR)")
endif
ifneq ($(realpath $(abspath ./)),$(CURDIR))
$(warning ./: abs="$(abspath ./)" real="$(realpath $(abspath ./))" curdir="$(CURDIR)")
endif
ifneq ($(realpath $(abspath .///)),$(CURDIR))
$(warning .///: abs="$(abspath .///)" real="$(realpath $(abspath .///))" curdir="$(CURDIR)")
endif
ifneq ($(abspath /),/)
$(warning /: abspath="$(abspath /)")
endif
ifneq ($(abspath ///),/)
$(warning ///: abspath="$(abspath ///)")
endif
ifneq ($(abspath /.),/)
$(warning /.: abspath="$(abspath /.)")
endif
ifneq ($(abspath ///.),/)
$(warning ///.: abspath="$(abspath ///.)")
endif
ifneq ($(abspath /./),/)
$(warning /./: abspath="$(abspath /./)")
endif
ifneq ($(abspath /.///),/)
$(warning /.///: abspath="$(abspath /.///)")
endif
ifneq ($(abspath /..),/)
$(warning /..: abspath="$(abspath /..)")
endif
ifneq ($(abspath ///..),/)
$(warning ///..: abspath="$(abspath ///..)")
endif
ifneq ($(abspath /../),/)
$(warning /../: abspath="$(abspath /../)")
endif
ifneq ($(abspath /..///),/)
$(warning /..///: abspath="$(abspath /..///)")
endif
ifneq ($(abspath /foo/bar/..),/foo)
$(warning /foo/bar/..: abspath="$(abspath /foo/bar/..)")
endif
ifneq ($(abspath /foo/bar/../../../baz),/baz)
$(warning /foo/bar/../../../baz: abspath="$(abspath /foo/bar/../../../baz)")
endif
ifneq ($(abspath /foo/bar/../ /..),/foo /)
$(warning /foo/bar/../ /..: abspath="$(abspath /foo/bar/../ /..)")
endif
.PHONY: all
all: ; @:
',
'',
'');
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,44 @@
$description = "The following test creates a makefile to test the addprefix "
."function.";
$details = "";
# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET
# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF
# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END.
# EXAMPLE: $makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "string := \$(addprefix src${pathsep},a.b.z.foo hacks) \n"
."all: \n"
."\t\@echo \$(string) \n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile,0);
# Create the answer to what should be produced by this Makefile
$answer = "src${pathsep}a.b.z.foo src${pathsep}hacks\n";
# COMPARE RESULTS
# In this call to compare output, you should use the call &get_logfile(1)
# to send the name of the last logfile created. You may also use
# the special call &get_logfile(1) which returns the same as &get_logfile(1).
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,36 @@
# -*-perl-*-
$description = "Test the addsuffix function.";
$details = "";
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE <<EOMAKE;
string := \$(addsuffix .c,src${pathsep}a.b.z.foo hacks)
one: ; \@echo \$(string)
two: ; \@echo \$(addsuffix foo,)
EOMAKE
close(MAKEFILE);
# TEST 0
&run_make_with_options($makefile, "", &get_logfile);
$answer = "src${pathsep}a.b.z.foo.c hacks.c\n";
&compare_output($answer,&get_logfile(1));
# TEST 1
&run_make_with_options($makefile, "two", &get_logfile);
$answer = "\n";
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,50 @@
# -*-perl-*-
$description = "Test the and & or functions.\n";
$details = "Try various uses of and & or to ensure they all give the correct
results.\n";
# TEST #0
# For $(and ...), it will either be empty or the last value
run_make_test('
NEQ = $(subst $1,,$2)
f =
t = true
all:
@echo 1 $(and ,$t)
@echo 2 $(and $t)
@echo 3 $(and $t,)
@echo 4 $(and z,true,$f,false)
@echo 5 $(and $t,$f,$(info bad short-circuit))
@echo 6 $(and $(call NEQ,a,b),true)
@echo 7 $(and $(call NEQ,a,a),true)
@echo 8 $(and z,true,fal,se) hi
@echo 9 $(and ,true,fal,se)there
@echo 10 $(and $(e) ,$t)',
'',
"1\n2 true\n3\n4\n5\n6 true\n7\n8 se hi\n9 there\n10\n");
# TEST #1
# For $(or ...), it will either be empty or the first true value
run_make_test('
NEQ = $(subst $1,,$2)
f =
t = true
all:
@echo 1 $(or , )
@echo 2 $(or $t)
@echo 3 $(or ,$t)
@echo 4 $(or z,true,$f,false)
@echo 5 $(or $t,$(info bad short-circuit))
@echo 6 $(or $(info short-circuit),$t)
@echo 7 $(or $(call NEQ,a,b),true)
@echo 8 $(or $(call NEQ,a,a),true)
@echo 9 $(or z,true,fal,se) hi
@echo 10 $(or ,true,fal,se)there
@echo 11 $(or $(e) ,$f)',
'',
"short-circuit\n1\n2 true\n3 true\n4 z\n5 true\n6 true\n7 b\n8 true\n9 z hi\n10 truethere\n11\n");
1;
@@ -0,0 +1,44 @@
$description = "The following test creates a makefile to test the suffix "
."function.";
$details = "";
# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET
# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF
# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END.
# EXAMPLE: $makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "string := \$(basename src${pathsep}a.b.z.foo.c src${pathsep}hacks src.bar${pathsep}a.b.z.foo.c src.bar${pathsep}hacks hacks) \n"
."all: \n"
."\t\@echo \$(string) \n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile,0);
# Create the answer to what should be produced by this Makefile
$answer = "src${pathsep}a.b.z.foo src${pathsep}hacks src.bar${pathsep}a.b.z.foo src.bar${pathsep}hacks hacks\n";
# COMPARE RESULTS
# In this call to compare output, you should use the call &get_logfile(1)
# to send the name of the last logfile created. You may also use
# the special call &get_logfile(1) which returns the same as &get_logfile(1).
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,92 @@
# -*-perl-*-
$description = "Test the call function.\n";
$details = "Try various uses of call and ensure they all give the correct
results.\n";
run_make_test(q!
# Simple, just reverse two things
#
reverse = $2 $1
# A complex 'map' function, using recursive 'call'.
#
map = $(foreach a,$2,$(call $1,$a))
# Test using a builtin; this is silly as it's simpler to do without call
#
my-notdir = $(call notdir,$(1))
# Test using non-expanded builtins
#
my-foreach = $(foreach $(1),$(2),$(3))
my-if = $(if $(1),$(2),$(3))
# Test recursive invocations of call with different arguments
#
one = $(1) $(2) $(3)
two = $(call one,$(1),foo,$(2))
# Test recursion on the user-defined function. As a special case make
# won't error due to this.
# Implement transitive closure using $(call ...)
#
DEP_foo = bar baz quux
DEP_baz = quux blarp
rest = $(wordlist 2,$(words ${1}),${1})
tclose = $(if $1,$(firstword $1)\
$(call tclose,$(sort ${DEP_$(firstword $1)} $(call rest,$1))))
all: ; @echo '$(call reverse,bar,foo)'; \
echo '$(call map,origin,MAKE reverse map)'; \
echo '$(call my-notdir,a/b c/d e/f)'; \
echo '$(call my-foreach)'; \
echo '$(call my-foreach,a,,,)'; \
echo '$(call my-if,a,b,c)'; \
echo '$(call two,bar,baz)'; \
echo '$(call tclose,foo)';
!,
"", "foo bar\ndefault file file\nb d f\n\n\nb\nbar foo baz\nfoo bar baz blarp quux \n");
# These won't work because call expands all its arguments first, before
# passing them on, then marks them as resolved/simple, so they're not
# expanded again by the function.
#
# echo '$(call my-foreach,a,x y z,$$(a)$$(a))'; \
# echo '$(call my-if,,$$(info don't print this),$$(info do print this))'
#
# $answer = "xx yy zz\ndo print this\n";
# TEST eclipsing of arguments when invoking sub-calls
run_make_test(q!
all = $1 $2 $3 $4 $5 $6 $7 $8 $9
level1 = $(call all,$1,$2,$3,$4,$5)
level2 = $(call level1,$1,$2,$3)
level3 = $(call level2,$1,$2,$3,$4,$5)
all:
@echo $(call all,1,2,3,4,5,6,7,8,9,10,11)
@echo $(call level1,1,2,3,4,5,6,7,8)
@echo $(call level2,1,2,3,4,5,6,7,8)
@echo $(call level3,1,2,3,4,5,6,7,8)
!,
"", "1 2 3 4 5 6 7 8 9\n1 2 3 4 5\n1 2 3\n1 2 3\n");
# Ensure that variables are defined in global scope even in a $(call ...)
delete $ENV{X123};
run_make_test('
tst = $(eval export X123)
$(call tst)
all: ; @echo "$${X123-not set}"
',
'', "\n");
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:
@@ -0,0 +1,44 @@
$description = "The following test creates a makefile to test the dir "
."function.";
$details = "";
# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET
# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF
# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END.
# EXAMPLE: $makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "string := \$(dir src${pathsep}foo.c hacks) \n"
."all: \n"
."\t\@echo \$(string) \n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile,0);
# Create the answer to what should be produced by this Makefile
$answer = "src${pathsep} .${pathsep}\n";
# COMPARE RESULTS
# In this call to compare output, you should use the call &get_logfile(1)
# to send the name of the last logfile created. You may also use
# the special call &get_logfile(1) which returns the same as &get_logfile(1).
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,71 @@
# -*-Perl-*-
$description = "\
The following test creates a makefile to test the error function.";
$details = "";
open(MAKEFILE,"> $makefile");
print MAKEFILE 'err = $(error Error found!)
ifdef ERROR1
$(error error is $(ERROR1))
endif
ifdef ERROR2
$(error error is $(ERROR2))
endif
ifdef ERROR3
all: some; @echo $(error error is $(ERROR3))
endif
ifdef ERROR4
all: some; @echo error is $(ERROR4)
@echo $(error error is $(ERROR4))
endif
some: ; @echo Some stuff
testvar: ; @: $(err)
';
close(MAKEFILE);
# Test #1
&run_make_with_options($makefile, "ERROR1=yes", &get_logfile, 512);
$answer = "$makefile:4: *** error is yes. Stop.\n";
&compare_output($answer,&get_logfile(1));
# Test #2
&run_make_with_options($makefile, "ERROR2=no", &get_logfile, 512);
$answer = "$makefile:8: *** error is no. Stop.\n";
&compare_output($answer,&get_logfile(1));
# Test #3
&run_make_with_options($makefile, "ERROR3=maybe", &get_logfile, 512);
$answer = "Some stuff\n$makefile:12: *** error is maybe. Stop.\n";
&compare_output($answer,&get_logfile(1));
# Test #4
&run_make_with_options($makefile, "ERROR4=definitely", &get_logfile, 512);
$answer = "Some stuff\n$makefile:17: *** error is definitely. Stop.\n";
&compare_output($answer,&get_logfile(1));
# Test #5
&run_make_with_options($makefile, "testvar", &get_logfile, 512);
$answer = "$makefile:22: *** Error found!. Stop.\n";
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:
@@ -0,0 +1,169 @@
# -*-perl-*-
$description = "Test the eval function.";
$details = "This is a test of the eval function in GNU make.
This function will evaluate inline makefile syntax and incorporate the
results into its internal database.\n";
open(MAKEFILE,"> $makefile");
print MAKEFILE <<'EOF';
define Y
all:: ; @echo $AA
A = B
endef
X = $(eval $(value Y))
$(eval $(shell echo A = A))
$(eval $(Y))
$(eval A = C)
$(eval $(X))
EOF
close(MAKEFILE);
&run_make_with_options($makefile, "", &get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = "AA\nBA\n";
&compare_output($answer,&get_logfile(1));
# Test to make sure defining variables when we have extra scope pushed works
# as expected.
$makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile2");
print MAKEFILE <<'EOF';
VARS = A B
VARSET = $(1) = $(2)
$(foreach v,$(VARS),$(eval $(call VARSET,$v,$v)))
all: ; @echo A = $(A) B = $(B)
EOF
close(MAKEFILE);
&run_make_with_options($makefile2, "", &get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = "A = A B = B\n";
&compare_output($answer,&get_logfile(1));
# Test to make sure eval'ing inside conditionals works properly
$makefile3 = &get_tmpfile;
open(MAKEFILE,"> $makefile3");
print MAKEFILE <<'EOF';
FOO = foo
all:: ; @echo it
define Y
all:: ; @echo worked
endef
ifdef BAR
$(eval $(Y))
endif
EOF
close(MAKEFILE);
&run_make_with_options($makefile3, "", &get_logfile);
$answer = "it\n";
&compare_output($answer,&get_logfile(1));
&run_make_with_options($makefile3, "BAR=1", &get_logfile);
$answer = "it\nworked\n";
&compare_output($answer,&get_logfile(1));
# TEST very recursive invocation of eval
$makefile3 = &get_tmpfile;
open(MAKEFILE,"> $makefile3");
print MAKEFILE <<'EOF';
..9 := 0 1 2 3 4 5 6 7 8 9
rev=$(eval res:=)$(foreach word,$1,$(eval res:=${word} ${res}))${res}
a:=$(call rev,${..9})
all: ; @echo '[$(a)]'
EOF
close(MAKEFILE);
&run_make_with_options($makefile3, "", &get_logfile);
$answer = "[ 9 8 7 6 5 4 3 2 1 0 ]\n";
&compare_output($answer,&get_logfile(1));
# TEST eval with no filename context.
# The trick here is that because EVAR is taken from the environment, it must
# be evaluated before every command is invoked. Make sure that works, when
# we have no file context for reading_file (bug # 6195)
$makefile4 = &get_tmpfile;
open(MAKEFILE,"> $makefile4");
print MAKEFILE <<'EOF';
EVAR = $(eval FOBAR = 1)
all: ; @echo "OK"
EOF
close(MAKEFILE);
$ENV{EVAR} = '1';
&run_make_with_options($makefile4, "", &get_logfile);
$answer = "OK\n";
&compare_output($answer,&get_logfile(1));
# Clean out previous information to allow new run_make_test() interface.
# If we ever convert all the above to run_make_test() we can remove this line.
$makefile = undef;
# Test handling of backslashes in strings to be evaled.
run_make_test('
define FOO
all: ; @echo hello \
world
endef
$(eval $(FOO))
', '', 'hello world');
run_make_test('
define FOO
all: ; @echo '."'".'he\llo'."'".'
@echo world
endef
$(eval $(FOO))
', '', 'he\llo
world');
# We don't allow new target/prerequisite relationships to be defined within a
# command script, because these are evaluated after snap_deps() and that
# causes lots of problems (like core dumps!)
# See Savannah bug # 12124.
run_make_test('deps: ; $(eval deps: foo)', '',
'#MAKEFILE#:1: *** prerequisites cannot be defined in recipes. Stop.',
512);
1;
@@ -0,0 +1,222 @@
# -*-perl-*-
$description = 'Test the $(file ...) function.';
# Test > and >>
run_make_test(q!
define A
a
b
endef
B = c d
$(file >file.out,$(A))
$(foreach L,$(B),$(file >> file.out,$L))
x:;@echo hi; cat file.out
!,
'', "hi\na\nb\nc\nd");
unlink('file.out');
# Test >> to a non-existent file
run_make_test(q!
define A
a
b
endef
$(file >> file.out,$(A))
x:;@cat file.out
!,
'', "a\nb");
unlink('file.out');
# Test > with no content
run_make_test(q!
$(file >4touch)
.PHONY:x
x:;@cat 4touch
!,
'', '');
# Test >> with no content
run_make_test(q!
$(file >>4touch)
.PHONY:x
x:;@cat 4touch
!,
'', '');
unlink('4touch');
# Test > to a read-only file
if (defined $ERR_read_only_file) {
touch('file.out');
chmod(0444, 'file.out');
run_make_test(q!
define A
a
b
endef
$(file > file.out,$(A))
x:;@cat file.out
!,
'', "#MAKEFILE#:6: *** open: file.out: $ERR_read_only_file. Stop.",
512);
unlink('file.out');
}
# Use variables for operator and filename
run_make_test(q!
define A
a
b
endef
OP = >
FN = file.out
$(file $(OP) $(FN),$(A))
x:;@cat file.out
!,
'', "a\nb");
unlink('file.out');
# Don't add newlines if one already exists
run_make_test(q!
define A
a
b
endef
$(file >file.out,$(A))
x:;@cat file.out
!,
'', "a\nb");
unlink('file.out');
# Empty text
run_make_test(q!
$(file >file.out,)
$(file >>file.out,)
x:;@cat file.out
!,
'', "\n\n");
unlink('file.out');
# Reading files
run_make_test(q!
$(file >file.out,A = foo)
X1 := $(file <file.out)
$(file >>file.out,B = bar)
$(eval $(file <file.out))
x:;@echo '$(X1)'; echo '$(A)'; echo '$(B)'
!,
'', "A = foo\nfoo\nbar\n");
unlink('file.out');
# Read an empty file.
touch("file.out");
run_make_test(q!# empty file
X1 := x$(file <file.out)y
x:;@echo '$(X1)'
!,
'', "xy\n");
unlink('file.out');
# Read a file whose full contents is a newline.
create_file('file.out', "\n");
run_make_test(q!# <nl>
X1 := x$(file <file.out)y
x:;@echo '$(X1)'
!,
'', "xy\n");
unlink('file.out');
# Read a file which does not end with a newline.
create_file('file.out', "hello");
# echo prints a trailig newline, because run_make_test appends a newline.
run_make_test(q!# hello
X1 := x$(file <file.out)y
x:;@echo $(X1)
!,
'', "xhelloy\n");
unlink('file.out');
# Read a file which ends with a newline.
create_file('file.out', "hello\n");
# echo prints a trailig newline, because run_make_test appends a newline.
run_make_test(q!# hello<nl>
X1 := x$(file <file.out)y
x:;@echo '$(X1)'
!,
'', "xhelloy\n");
unlink('file.out');
# Read a file which ends with multiple newlines.
create_file('file.out', "hello\n\n");
run_make_test(q!# hello<nl><nl>
X1 := x$(file <file.out)y
export X1
x:;@echo "$$X1"
!,
'', "xhello\ny\n");
unlink('file.out');
# Read a file whose contents exceed 200 bytes.
# 200 is the initial size of variable_buffer.
# File bigger than 200 bytes causes a realloc.
# The size of the file in this test not only exceeds 200 bytes, it exceeds 65k.
# Use $(info ...) here to avoid command line limitations
my $s = "hello world, hello world, hello world, hello world, hello world";
my $answer = $s x 2000;
create_file('file.out', $answer);
run_make_test(q!# <hugestring>
X1 := x$(file <file.out)y
x:;@$(info $(X1))
!,
'', "x${answer}y\n#MAKE#: 'x' is up to date.\n");
unlink('file.out');
# Reading from non-existent file
run_make_test(q!
X1 := $(file <file.out)
x:;@echo '$(X1)';
!,
'', "\n");
# Extra arguments in read mode
run_make_test(q!
X1 := $(file <file.out,foo)
x:;@echo '$(X1)';
!,
'', "#MAKEFILE#:2: *** file: too many arguments. Stop.\n", 512);
# Missing filename
run_make_test('$(file >)', '',
"#MAKEFILE#:1: *** file: missing filename. Stop.\n", 512);
run_make_test('$(file >>)', '',
"#MAKEFILE#:1: *** file: missing filename. Stop.\n", 512);
run_make_test('$(file <)', '',
"#MAKEFILE#:1: *** file: missing filename. Stop.\n", 512);
# Bad call
run_make_test('$(file foo)', '',
"#MAKEFILE#:1: *** file: invalid file operation: foo. Stop.\n", 512);
1;
@@ -0,0 +1,58 @@
# -*-perl-*-
$description = "Test the filter and filter-out functions.";
$details = "The makefile created in this test has two variables. The
filter-out function is first used to discard names ending in
.o with a single simple pattern. The second filter-out function
augments the simple pattern with three literal names, which are
also added to the text argument. This tests an internal hash table
which is only used if there are multiple literals present in both
the pattern and text arguments. The result of both filter-out
functions is the same single .elc name.\n";
# Basic test -- filter
run_make_test(q!
files1 := $(filter %.o, foo.elc bar.o lose.o)
files2 := $(filter %.o foo.i, foo.i bar.i lose.i foo.elc bar.o lose.o)
all: ; @echo '$(files1) $(files2)'
!,
'', "bar.o lose.o foo.i bar.o lose.o\n");
# Basic test -- filter-out
run_make_test(q!
files1 := $(filter-out %.o, foo.elc bar.o lose.o)
files2 := $(filter-out foo.i bar.i lose.i %.o, foo.i bar.i lose.i foo.elc bar.o lose.o)
all: ; @echo '$(files1) $(files2)'
!,
'', "foo.elc foo.elc\n");
# Force use of hash (see function.c:func_filter_filterout for params)
my $base = 'foo.1 foo.2 foo.3 foo.4 foo.5 foo.6 foo.7 foo.8 foo.9 foo.10';
my $base10 = join(' ', ($base) x 10);
my $out3 = join(' ', ('foo.3') x 10);
my $out456 = join(' ', ('foo.4 foo.5 foo.6') x 10);
run_make_test("words := $base10" . q!
files1 := $(filter %.3, $(words))
files2 := $(filter %.4 foo.5 foo.6, $(words))
all: ; @echo '$(files1) $(files2)'
!,
'', "$out3 $out456\n");
# Escaped patterns
run_make_test(q!all:;@echo '$(filter foo\%bar,foo%bar fooXbar)'!,
'', "foo%bar\n");
run_make_test(q!all:;@echo '$(filter foo\%\%\\\\\%\%bar,foo%%\\%%bar fooX\\Ybar)'!,
'', "foo%%\\%%bar\n");
run_make_test(q!
X = $(filter foo\\\\\%bar,foo\%bar foo\Xbar)
all:;@echo '$(X)'!,
'', "foo\\%bar\n");
1;
@@ -0,0 +1,47 @@
$description = "The following test creates a makefile to test the findstring "
."function.";
$details = "";
# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET
# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF
# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END.
# EXAMPLE: $makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "string := \$(findstring port, reporter)\n"
."all: \n"
."\t\@echo \$(string) \n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,
"",
&get_logfile,
0);
# Create the answer to what should be produced by this Makefile
$answer = "port\n";
# COMPARE RESULTS
# In this call to compare output, you should use the call &get_logfile(1)
# to send the name of the last logfile created. You may also use
# the special call &get_logfile(1) which returns the same as &get_logfile(1).
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,44 @@
# -*-perl-*-
$description = "Test the flavor function.";
$details = "";
# Test #1: Test general logic.
#
run_make_test('
s := s
r = r
$(info u $(flavor u))
$(info s $(flavor s))
$(info r $(flavor r))
ra += ra
rc ?= rc
$(info ra $(flavor ra))
$(info rc $(flavor rc))
s += s
r += r
$(info s $(flavor s))
$(info r $(flavor r))
.PHONY: all
all:;@:
',
'',
'u undefined
s simple
r recursive
ra recursive
rc recursive
s simple
r recursive');
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,93 @@
# -*-perl-*-
# $Id$
$description = "Test the foreach function.";
$details = "This is a test of the foreach function in gnu make.
This function starts with a space separated list of
names and a variable. Each name in the list is subsituted
into the variable and the given text evaluated. The general
form of the command is $(foreach var,\$list,\$text). Several
types of foreach loops are tested\n";
# TEST 0
# Set an environment variable that we can test in the makefile.
$ENV{FOOFOO} = 'foo foo';
run_make_test("space = ' '".'
null :=
auto_var = udef space CC null FOOFOO MAKE foo CFLAGS WHITE @ <
foo = bletch null @ garf
av = $(foreach var, $(auto_var), $(origin $(var)) )
override WHITE := BLACK
for_var = $(addsuffix .c,foo $(null) $(foo) $(space) $(av) )
fe = $(foreach var2, $(for_var),$(subst .c,.o, $(var2) ) )
all: auto for2
auto : ; @echo $(av)
for2: ; @echo $(fe)',
'-e WHITE=WHITE CFLAGS=',
"undefined file default file environment default file command line override automatic automatic
foo.o bletch.o null.o @.o garf.o .o .o undefined.o file.o default.o file.o environment.o default.o file.o command.o line.o override.o automatic.o automatic.o");
# TEST 1: Test that foreach variables take precedence over global
# variables in a global scope (like inside an eval). Tests bug #11913
run_make_test('
.PHONY: all target
all: target
x := BAD
define mktarget
target: x := $(x)
target: ; @echo "$(x)"
endef
x := GLOBAL
$(foreach x,FOREACH,$(eval $(value mktarget)))',
'',
'FOREACH');
# Allow variable names with trailing space
run_make_test(q!
$(foreach \
a \
, b c d \
, $(info $a))
all:;@:
!,
"", "b\nc\nd\n");
# Allow empty variable names. We still expand the body.
run_make_test('
x = $(foreach ,1 2 3,a)
y := $x
all: ; @echo $y',
'', "a a a\n");
# Check some error conditions.
run_make_test('
x = $(foreach )
y = $x
all: ; @echo $y',
'',
"#MAKEFILE#:2: *** insufficient number of arguments (1) to function 'foreach'. Stop.",
512);
run_make_test('
x = $(foreach x,y)
y := $x
all: ; @echo $y',
'',
"#MAKEFILE#:2: *** insufficient number of arguments (2) to function 'foreach'. Stop.",
512);
1;
@@ -0,0 +1,116 @@
# -*-perl-*-
$description = 'Test the $(guile ...) function.';
$details = 'This only works on systems that support it.';
# If this instance of make doesn't support GNU Guile, skip it
# This detects if guile is loaded using the "load" directive
# $makefile = get_tmpfile();
# open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
# print MAKEFILE q!
# -load guile
# all: ; @echo $(filter guile,$(.LOADED))
# !;
# close(MAKEFILE) || die "Failed to write $makefile: $!\n";
# $cmd = subst_make_string("#MAKEPATH# -f $makefile");
# $log = get_logfile(0);
# $code = run_command_with_output($log, $cmd);
# read_file_into_string ($log) eq "guile\n" and $FEATURES{guile} = 1;
# If we don't have Guile support, never mind.
exists $FEATURES{guile} or return -1;
# Guile and Valgrind don't play together at all.
$valgrind and return -1;
# Verify simple data type conversions
# Currently we don't support vectors:
# echo '$(guile (vector 1 2 3))'; \
run_make_test(q!
x:;@echo '$(guile #f)'; \
echo '$(guile #t)'; \
echo '$(guile #\c)'; \
echo '$(guile 1234)'; \
echo '$(guile 'foo)'; \
echo '$(guile "bar")'; \
echo '$(guile (cons 'a 'b))'; \
echo '$(guile '(a b (c . d) 1 (2) 3))'
!,
'', "\n#t\nc\n1234\nfoo\nbar\na b\na b c d 1 2 3");
# Verify guile functions in variables -- SV 43378
run_make_test(q!
res := $(guile #f) \
$(guile #t) \
$(guile #\c) \
$(guile 1234) \
$(guile 'foo) \
$(guile "bar") \
$(guile (cons 'a 'b)) \
$(guile '(a b (c . d) 1 (2) 3))
x:;@echo '$(res)'
!,
'', " #t c 1234 foo bar a b a b c d 1 2 3");
# Verify the gmk-expand function
run_make_test(q!
VAR = $(guile (gmk-expand "$(shell echo hi)"))
x:;@echo '$(VAR)'
!,
'', "hi");
# Verify the gmk-eval function
# Prove that the string is expanded only once (by eval)
run_make_test(q!
TEST = bye
EVAL = VAR = $(TEST) $(shell echo there)
$(guile (gmk-eval "$(value EVAL)"))
TEST = hi
x:;@echo '$(VAR)'
!,
'', "hi there");
# Verify the gmk-eval function with a list
run_make_test(q!
$(guile (gmk-eval '(VAR = 1 (2) () 3)))
x:;@echo '$(VAR)'
!,
'', "1 2 3");
# Verify the gmk-var function
run_make_test(q!
VALUE = hi $(shell echo there)
VAR = $(guile (gmk-var "VALUE"))
x:;@echo '$(VAR)'
!,
'', "hi there");
# Verify the gmk-var function with a symbol
run_make_test(q!
VALUE = hi $(shell echo there)
VAR = $(guile (gmk-var 'VALUE))
x:;@echo '$(VAR)'
!,
'', "hi there");
# Write a Guile program using define and run it
run_make_test(q!
# Define the "fib" function in Guile
define fib
;; A procedure for counting the n:th Fibonacci number
;; See SICP, p. 37
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
endef
$(guile $(fib))
# Now run it
x:;@echo $(guile (fib $(FIB)))
!,
'FIB=10', "55");
1;
@@ -0,0 +1,33 @@
# -*-perl-*-
$description = "Test the if function.\n";
$details = "Try various uses of if and ensure they all give the correct
results.\n";
open(MAKEFILE, "> $makefile");
print MAKEFILE <<EOMAKE;
NEQ = \$(subst \$1,,\$2)
e =
all:
\t\@echo 1 \$(if ,true,false)
\t\@echo 2 \$(if ,true,)
\t\@echo 3 \$(if ,true)
\t\@echo 4 \$(if z,true,false)
\t\@echo 5 \$(if z,true,\$(shell echo hi))
\t\@echo 6 \$(if ,\$(shell echo hi),false)
\t\@echo 7 \$(if \$(call NEQ,a,b),true,false)
\t\@echo 8 \$(if \$(call NEQ,a,a),true,false)
\t\@echo 9 \$(if z,true,fal,se) hi
\t\@echo 10 \$(if ,true,fal,se)there
\t\@echo 11 \$(if \$(e) ,true,false)
EOMAKE
close(MAKEFILE);
&run_make_with_options($makefile, "", &get_logfile);
$answer = "1 false\n2\n3\n4 true\n5 true\n6 false\n7 true\n8 false\n9 true hi\n10 fal,sethere\n11 false\n";
&compare_output($answer, &get_logfile(1));
1;
@@ -0,0 +1,72 @@
# -*-perl-*-
$description = "Test the intcmp function.\n";
$details = "Try various uses of intcmp and ensure they all give the correct
results.\n";
run_make_test('# Negative
n = -10
# Zero
z = 0
# Positive
p = 888
min = -9223372036854775808
max = 9223372036854775807
huge = 8857889956778499040639527525992734031025567913257255490371761260681427
.RECIPEPREFIX = >
all:
> @echo 0_1 $(intcmp $n,$n)
> @echo 0_2 $(intcmp $z,$z)
> @echo 0_3 $(intcmp -$z,$z)
> @echo 0_4 $(intcmp $p,$p)
> @echo 0_5 $(intcmp $n,$z)
> @echo 0_6 $(intcmp $z,$n)
> @echo 1_1 $(intcmp $n,$n,$(shell echo lt))
> @echo 1_2 $(intcmp $n,$z,$(shell echo lt))
> @echo 1_3 $(intcmp $z,$n,$(shell echo lt))
> @echo 2_1 $(intcmp $n,$p,lt,ge)
> @echo 2_2 $(intcmp $z,$z,lt,ge)
> @echo 2_3 $(intcmp $p,$n,lt,ge)
> @echo 3_0 $(intcmp $p,$n,lt,eq,)
> @echo 3_1 $(intcmp $z,$p,lt,eq,gt)
> @echo 3_2 $(intcmp $p,$z,lt,eq,gt)
> @echo 3_3 $(intcmp $p,$p,lt,eq,gt)
> @echo 4_0 $(intcmp $(min),$(max),lt,eq,gt)
> @echo 4_1 $(intcmp $(max),$(min),lt,eq,gt)
> @echo 4_2 $(intcmp $(min),$(min),lt,eq,gt)
> @echo 4_3 $(intcmp $(max),$(max),lt,eq,gt)
> @echo 5_0 $(intcmp -$(huge),$(huge),lt,eq,gt)
> @echo 5_1 $(intcmp $(huge),-$(huge),lt,eq,gt)
> @echo 5_2 $(intcmp -$(huge),-$(huge),lt,eq,gt)
> @echo 5_3 $(intcmp +$(huge),$(huge),lt,eq,gt)
', '', "0_1 -10\n0_2 0\n0_3 0\n0_4 888\n0_5\n0_6\n1_1\n1_2 lt\n1_3\n2_1 lt\n2_2 ge\n2_3 ge\n3_0\n3_1 lt\n3_2 gt\n3_3 eq\n4_0 lt\n4_1 gt\n4_2 eq\n4_3 eq\n5_0 lt\n5_1 gt\n5_2 eq\n5_3 eq\n");
# Test error conditions
run_make_test('
intcmp-e1: ; @echo $(intcmp 12a,1,foo)
intcmp-e2: ; @echo $(intcmp 0,,foo)
intcmp-e3: ; @echo $(intcmp -1,)
intcmp-e4: ; @echo $(intcmp ,55)',
'intcmp-e1',
"#MAKEFILE#:2: *** non-numeric first argument to 'intcmp' function: '12a'. Stop.",
512);
run_make_test(undef,
'intcmp-e2',
"#MAKEFILE#:3: *** non-numeric second argument to 'intcmp' function: empty value. Stop.",
512);
run_make_test(undef,
'intcmp-e3',
"#MAKEFILE#:4: *** non-numeric second argument to 'intcmp' function: empty value. Stop.",
512);
run_make_test(undef,
'intcmp-e4',
"#MAKEFILE#:5: *** non-numeric first argument to 'intcmp' function: empty value. Stop.",
512);
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,44 @@
$description = "The following test creates a makefile to test the join "
."function.";
$details = "";
# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET
# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF
# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END.
# EXAMPLE: $makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "string := \$(join a b c,foo hacks .pl1) \n"
."all: \n"
."\t\@echo \$(string) \n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile,0);
# Create the answer to what should be produced by this Makefile
$answer = "afoo bhacks c.pl1\n";
# COMPARE RESULTS
# In this call to compare output, you should use the call &get_logfile(1)
# to send the name of the last logfile created. You may also use
# the special call &get_logfile(1) which returns the same as &get_logfile(1).
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,111 @@
# -*-perl-*-
# $Id$
$description = "Test the let function.";
$details = "This is a test of the let function in gnu make.
This function destructures a list of values and binds each
value to a variable name in a list of variable names.
Superfluous variable names are assigned the empty string and
the remaining values are assigned to the last variable name.
The binding holds for the duration of the evaluation of the
given text and no longer. The general form of the command
is $(let \$vars,\$list,\$text). Several types of let
assignments are tested\n";
# check for mismatched var and list word counts
run_make_test(q!
a = bad
b = news
x = $(let a b,1 2,$a $b)
y = $(let a,1 2,$a)
z = $(let a b,1,$a $b)
all:;@echo 'a=,$a,' 'b=,$b,' 'x=,$x,' 'y=,$y,' 'z=,$z,'
!,
'', "a=,bad, b=,news, x=,1 2, y=,1 2, z=,1 ,\n");
# check for whitespace
run_make_test(q!
a = bad
b = news
x = $(let a b, 1 2 ,+$a+$b+)
y = $(let a, 1 2 ,+$a+)
z = $(let a b, 1 ,+$a+$b+)
all:;@echo 'a=,$a,' 'b=,$b,' 'x=,$x,' 'y=,$y,' 'z=,$z,'
!,
'', "a=,bad, b=,news, x=,+1+2 +, y=,+1 2 +, z=,+1++,\n");
# Allow empty variable names and empty value list.
# We still expand the list and body.
run_make_test('
null =
v = $(let ,$(info blankvar),abc)
x = $(let $(null),$(info side-effect),abc)
y = $(let y,,$ydef)
all: ; @echo $v/$x/$y',
'', "blankvar\nside-effect\nabc/abc/def\n");
# The example macro from the manual.
run_make_test('
reverse = $(let first rest,$1,$(if $(rest),$(call reverse,$(rest)) )$(first))
all: ; @echo $(call reverse, \
moe miny meeny eeny \
)',
'', "eeny meeny miny moe\n");
# Set an environment variable that we can test in the makefile.
$ENV{FOOFOO} = 'foo foo';
# Verify masking: expansion outside the scope of let is unaffected.
run_make_test('
auto_var = \
udef \
CC \
FOOFOO \
MAKE \
foo \
CFLAGS \
WHITE \
@ \
<
av = $(foreach var, $(auto_var), $(origin $(var)) )
foo = bletch null @ garf
override WHITE := BLACK
define mktarget
target: foo := $(foo)
target: ; @echo $(AR)_$(foo)_
endef
all: auto target
auto: ; @echo $(let $(auto_var),,$(av)) $(av)
$(let AR foo,bar foo ,$(eval $(value mktarget)))',
'-e WHITE=WHITE CFLAGS=',
"automatic automatic automatic automatic automatic automatic automatic automatic automatic undefined default environment default file command line override automatic automatic
ar_foo _
");
# Check some error conditions.
run_make_test('
x = $(let )
y = $x
all: ; @echo $y',
'',
"#MAKEFILE#:2: *** insufficient number of arguments (1) to function 'let'. Stop.",
512);
run_make_test('
x = $(let x,y)
y := $x
all: ; @echo $y',
'',
"#MAKEFILE#:2: *** insufficient number of arguments (2) to function 'let'. Stop.",
512);
1;
@@ -0,0 +1,44 @@
$description = "The following test creates a makefile to test the notdir "
."function.";
$details = "";
# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET
# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF
# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END.
# EXAMPLE: $makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "string := \$(notdir ${pathsep}src${pathsep}foo.c hacks) \n"
."all: \n"
."\t\@echo \$(string) \n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile,0);
# Create the answer to what should be produced by this Makefile
$answer = "foo.c hacks\n";
# COMPARE RESULTS
# In this call to compare output, you should use the call &get_logfile(1)
# to send the name of the last logfile created. You may also use
# the special call &get_logfile(1) which returns the same as &get_logfile(1).
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,49 @@
# -*-perl-*-
$description = "Test the origin function.";
$details = "This is a test of the origin function in gnu make.
This function will report on where a variable was
defined per the following list:
'undefined' never defined
'default' default definition
'environment' environment var without -e
'environment override' environment var with -e
'file' defined in makefile
'command line' defined on the command line
'override' defined by override in makefile
'automatic' Automatic variable\n";
# Set an environment variable
$ENV{MAKETEST} = 1;
run_make_test('
foo := bletch garf
auto_var = undefined CC MAKETEST MAKE foo CFLAGS WHITE @
av = $(foreach var, $(auto_var), $(origin $(var)) )
override WHITE := BLACK
.RECIPEPREFIX = >
all: auto
> @echo $(origin undefined)
> @echo $(origin CC)
> @echo $(origin MAKETEST)
> @echo $(origin MAKE)
> @echo $(origin foo)
> @echo $(origin CFLAGS)
> @echo $(origin WHITE)
> @echo $(origin @)
auto :
> @echo $(av)',
'-e WHITE=WHITE CFLAGS=',
'undefined default environment default file command line override automatic
undefined
default
environment
default
file
command line
override
automatic');
1;
@@ -0,0 +1,92 @@
# -*-perl-*-
$description = "Test the realpath functions.";
$details = "";
# Check the local directory's realpath
run_make_test('
ifneq ($(realpath .),$(CURDIR))
$(warning $(realpath .) != $(CURDIR))
endif
ifneq ($(realpath ./),$(CURDIR))
$(warning $(realpath ./) != $(CURDIR))
endif
ifneq ($(realpath .///),$(CURDIR))
$(warning $(realpath .///) != $(CURDIR))
endif
.PHONY: all
all: ; @:
',
'', '');
# Find the realpath to the root of the partition
create_file('root.mk', 'all:;$(info $(realpath /))');
my $root = `$make_path -sf root.mk`;
unlink('root.mk');
chomp $root;
my $tst = '
ifneq ($(realpath /.),#ROOT#)
$(warning $(realpath /.) != #ROOT#)
endif
ifneq ($(realpath /./),#ROOT#)
$(warning $(realpath /./) != #ROOT#)
endif
ifneq ($(realpath /.///),#ROOT#)
$(warning $(realpath /.///) != #ROOT#)
endif
ifneq ($(realpath /..),#ROOT#)
$(warning $(realpath /..) != #ROOT#)
endif
ifneq ($(realpath /../),#ROOT#)
$(warning $(realpath /../) != #ROOT#)
endif
ifneq ($(realpath /..///),#ROOT#)
$(warning $(realpath /..///) != #ROOT#)
endif
ifneq ($(realpath . /..),$(CURDIR) #ROOT#)
$(warning $(realpath . /..) != $(CURDIR) #ROOT#)
endif
.PHONY: all
all: ; @:
';
$tst =~ s/#ROOT#/$root/g;
run_make_test($tst, '', '');
# On Windows platforms "//" means something special. So, don't do these tests
# there.
if ($port_type ne 'W32') {
$tst = '
ifneq ($(realpath ///),#ROOT#)
$(warning $(realpath ///) != #ROOT#)
endif
ifneq ($(realpath ///.),#ROOT#)
$(warning $(realpath ///.) != #ROOT#)
endif
ifneq ($(realpath ///..),#ROOT#)
$(warning $(realpath ///..) != #ROOT#)
endif
.PHONY: all
all: ; @:';
$tst =~ s/#ROOT#/$root/g;
run_make_test($tst, '', '');
}
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,214 @@
# -*-perl-*-
$description = 'Test the $(shell ...) function.';
$details = '';
# Test standard shell
run_make_test('.PHONY: all
OUT := $(shell echo hi)
all: ; @echo $(OUT)
','','hi');
# Test shells inside rules.
run_make_test('.PHONY: all
all: ; @echo $(shell echo hi)
','','hi');
# Verify .SHELLSTATUS
run_make_test('.PHONY: all
PRE := $(.SHELLSTATUS)
$(shell exit 0)
OK := $(.SHELLSTATUS)
$(shell exit 1)
BAD := $(.SHELLSTATUS)
all: ; @echo PRE=$(PRE) OK=$(OK) BAD=$(BAD)
','','PRE= OK=0 BAD=1');
# Test unescaped comment characters in shells. Savannah bug #20513
run_make_test(q!
FOO := $(shell echo '#')
foo: ; echo '$(FOO)'
!,
'', "echo '#'\n#\n");
# Test that exported variables are passed to $(shell ...)
$ENV{FOO} = 'baz';
run_make_test(q!
OUT = $(shell echo $$FOO)
foo: ; @echo '$(OUT)'
!,
'', 'baz');
$ENV{FOO} = 'baz';
run_make_test(q!
FOO = bar
OUT = $(shell echo $$FOO)
foo: ; @echo '$(OUT)'
!,
'', 'bar');
run_make_test(q!
export FOO = bar
OUT = $(shell echo $$FOO)
foo: ; @echo '$(OUT)'
!,
'', 'bar');
# Test shells inside exported environment variables, simply expanded.
run_make_test('
export HI := $(shell echo hi)
.PHONY: all
all: ; @echo $$HI
',
'','hi');
# Test shells inside exported environment variables. See SV 10593
run_make_test('
export HI = $(shell echo hi)
.PHONY: all
all: ; @echo $$HI
',
'',"hi");
$ENV{HI} = 'foo';
run_make_test('
HI = $(shell echo hi)
.PHONY: all
all: ; @echo $$HI
',
'',"hi");
$ENV{HI} = 'foo';
run_make_test('
HI = $(shell echo hi)
bad := $(HI)
.PHONY: all
all: ; @echo $$HI $(bad)
',
'',"hi hi");
# SV 63016: Exported variable that contains a variable containing $(shell...)
run_make_test('
HI = $(shell echo hi)
export bad = $(HI)
.PHONY: all
all:; : $(HI)
',
'',": hi");
$ENV{HI} = 'outer';
run_make_test('
export HI = $(shell echo $$HI)
.PHONY: all
all:; @echo $$HI
',
'',"outer");
$ENV{HI} = 'outer';
run_make_test('
export HI = $(shell echo $$HI)
.PHONY: all
all:; : $(HI)
',
'',": outer");
if ($port_type ne 'W32') {
# Test shell errors in recipes including offset
# This needs to be ported to Windows, or else Windows error messages
# need to converted to look like more normal make errors.
run_make_test('
.RECIPEPREFIX = >
all:
>@echo hi
>$(shell ./basdfdfsed there)
>@echo $(.SHELLSTATUS)
',
'', "#MAKE#: ./basdfdfsed: $ERR_no_such_file\nhi\n127\n");
run_make_test('
$(shell ./basdfdfsed where)
all: ; @echo $(.SHELLSTATUS)
',
'', "#MAKE#: ./basdfdfsed: $ERR_no_such_file\n127\n");
# Test SHELLSTATUS for kill.
# This test could be ported to Windows, using taskkill ... ?
# Figure out the exit code for SIGINT
my $pid = fork();
if (! $pid) {
exec('kill -2 $$') or die "exec: Cannot execute sleep\n";
}
waitpid($pid, 0);
# .SHELLSTATUS for a signal gives 128 + the signal number
my $ret = $?;
if ($ret > 255) {
# Solaris 10 perl 5.8.4 puts signal number + 128 into the high 8 bits.
$ret >>= 8;
}
$ret |= 128;
run_make_test('.PHONY: all
$(shell kill -2 $$$$)
STAT := $(.SHELLSTATUS)
all: ; @echo STAT=$(STAT)
','',"STAT=$ret\n");
# Test that not-found errors can be redirected
if ($ERR_command_not_found) {
$_ = $ERR_command_not_found;
s/#CMDNAME#/bad-command/g;
run_make_test(q!
out := $(shell bad-command 2>&1)
all: ; @echo '$(.SHELLSTATUS): $(out)'
!,
'', "127: $_\n");
}
# If we're using pipes for jobserver, then we will close them and not
# allow them to be available to sub-makes invoked via $(shell ...)
if (exists $FEATURES{'jobserver'}) {
run_make_test(q!
ifeq ($(ELT),)
default:; @$(MAKE) -f #MAKEFILE# ELT=1
else ifeq ($(ELT),1)
OUTPUT := $(shell $(MAKE) -f #MAKEFILE# ELT=2)
$(info $(OUTPUT))
default:;: $(ELT)
else
default:;: $(ELT)
endif
!,
'--no-print-directory -j2 --jobserver-style=pipe', "#MAKE#[2]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.\n: 2\n: 1");
}
# This crashes if we use vfork and don't reset environ properly
run_make_test(q!
export PATH = $(shell echo "tests:$$PATH")
foo = $(shell echo yes)
all:;echo $(foo)
!,
'', "echo yes\nyes\n");
}
# If we're not using pipes for jobserver, then they are available in sub-makes
# invoked by $(shell ...)
if ($port_type eq 'W32' || exists $FEATURES{'jobserver-fifo'}) {
run_make_test(q!
ifeq ($(ELT),)
default:; @$(MAKE) -f #MAKEFILE# ELT=1
else ifeq ($(ELT),1)
OUTPUT := $(shell $(MAKE) -f #MAKEFILE# ELT=2)
$(info $(OUTPUT))
default:;: $(ELT)
else
default:;: $(ELT)
endif
!,
'--no-print-directory -j2', ": 2\n: 1");
}
1;
@@ -0,0 +1,51 @@
# -*-perl-*-
$description = "The following test creates a makefile to verify
the ability of make to sort lists of object. Sort
will also remove any duplicate entries. This will also
be tested.";
$details = "The make file is built with a list of object in a random order
and includes some duplicates. Make should sort all of the elements
remove all duplicates\n";
run_make_test('
foo := moon_light days
foo1:= jazz
bar := captured
bar2 = boy end, has rise A midnight
bar3:= $(foo)
s1 := _by
s2 := _and_a
t1 := $(addsuffix $(s1), $(bar) )
t2 := $(addsuffix $(s2), $(foo1) )
t3 := $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2)
t4 := $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3)
t5 := $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4)
t6 := $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5)
t7 := $(t6) $(t6) $(t6)
p1 := $(addprefix $(foo1), $(s2) )
blank:=
all:
@echo $(sort $(bar2) $(foo) $(addsuffix $(s1), $(bar) ) $(t2) $(bar2) $(bar3))
@echo $(sort $(blank) $(foo) $(bar2) $(t1) $(p1) )
@echo $(sort $(foo) $(bar2) $(t1) $(t4) $(t5) $(t7) $(t6) )
',
'', 'A boy captured_by days end, has jazz_and_a midnight moon_light rise
A boy captured_by days end, has jazz_and_a midnight moon_light rise
A boy captured_by days end, has jazz_and_a midnight moon_light rise
');
# Test with non-space/tab whitespace. Note that you can't see the
# original bug except using valgrind.
run_make_test("FOO = a b\tc\rd\fe \f \f \f \f \ff
all: ; \@echo \$(words \$(sort \$(FOO)))\n",
'', "6\n");
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:
@@ -0,0 +1,57 @@
# -*-perl-*-
$description = "The following test creates a makefile to verify
the ability of make to strip white space from lists of object.\n";
$details = "The make file is built with a list of objects that contain white space
These are then run through the strip command to remove it. This is then
verified by echoing the result.\n";
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE <<'EOMAKE';
TEST1 := "Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING..."
E :=
TEST2 := $E try this and this $E
define TEST3
and these test out
some
blank lines
endef
.PHONY: all
all:
@echo '$(strip $(TEST1) )'
@echo '$(strip $(TEST2) )'
@echo '$(strip $(TEST3) )'
space: ; @echo '$(strip ) $(strip )'
EOMAKE
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile);
$answer = "\"Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING...\"
try this and this
and these test out some blank lines
";
&compare_output($answer,&get_logfile(1));
&run_make_with_options($makefile,"space",&get_logfile);
$answer = " \n";
&compare_output($answer,&get_logfile(1));
1;
@@ -0,0 +1,38 @@
# -*-perl-*-
$description = "Test the subst and patsubst functions";
$details = "";
# Generic patsubst test: test both the function and variable form.
run_make_test('
foo := a.o b.o c.o
bar := $(foo:.o=.c)
bar2:= $(foo:%.o=%.c)
bar3:= $(patsubst %.c,%.o,x.c.c bar.c)
all:;@echo $(bar); echo $(bar2); echo $(bar3)',
'',
'a.c b.c c.c
a.c b.c c.c
x.c.o bar.o');
# Patsubst without '%'--shouldn't match because the whole word has to match
# in patsubst. Based on a bug report by Markus Mauhart <qwe123@chello.at>
run_make_test('all:;@echo $(patsubst Foo,Repl,FooFoo)', '', 'FooFoo');
# Variable subst where a pattern matches multiple times in a single word.
# Based on a bug report by Markus Mauhart <qwe123@chello.at>
run_make_test('
A := fooBARfooBARfoo
all:;@echo $(A:fooBARfoo=REPL)', '', 'fooBARREPL');
1;
@@ -0,0 +1,57 @@
$description = "The following test creates a makefile to test the suffix\n"
."function. \n";
$details = "The suffix function will return the string following the last _._\n"
."the list provided. It will provide all of the unique suffixes found\n"
."in the list. The long strings are sorted to remove duplicates.\n";
# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET
# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF
# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END.
# EXAMPLE: $makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "string := word.pl general_test2.pl1 FORCE.pl word.pl3 generic_test.perl /tmp.c/bar foo.baz/bar.c MAKEFILES_variable.c\n"
."string2 := \$(string) \$(string) \$(string) \$(string) \$(string) \$(string) \$(string)\n"
."string3 := \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2)\n"
."string4 := \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3)\n"
."all: \n"
."\t\@echo \$(suffix \$(string)) \n"
."\t\@echo \$(sort \$(suffix \$(string4))) \n"
."\t\@echo \$(suffix \$(string) a.out) \n"
."\t\@echo \$(sort \$(suffix \$(string3))) \n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile,0);
# Create the answer to what should be produced by this Makefile
# COMPARE RESULTS
$answer = ".pl .pl1 .pl .pl3 .perl .c .c\n"
.".c .perl .pl .pl1 .pl3\n"
.".pl .pl1 .pl .pl3 .perl .c .c .out\n"
.".c .perl .pl .pl1 .pl3\n";
# In this call to compare output, you should use the call &get_logfile(1)
# to send the name of the last logfile created. You may also use
# the special call &get_logfile(1) which returns the same as &get_logfile(1).
&compare_output($answer,&get_logfile(1));
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,30 @@
# -*-perl-*-
$description = "Test the value function.";
$details = "This is a test of the value function in GNU make.
This function will evaluate to the value of the named variable with no
further expansion performed on it.\n";
open(MAKEFILE,"> $makefile");
print MAKEFILE <<'EOF';
export FOO = foo
recurse = FOO = $FOO
static := FOO = $(value FOO)
all: ; @echo $(recurse) $(value recurse) $(static) $(value static)
EOF
close(MAKEFILE);
&run_make_with_options($makefile, "", &get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = "FOO = OO FOO = foo FOO = foo FOO = foo\n";
&compare_output($answer,&get_logfile(1));
1;
@@ -0,0 +1,83 @@
# -*-Perl-*-
$description = "\
The following test creates a makefile to test the warning function.";
$details = "";
open(MAKEFILE,"> $makefile");
print MAKEFILE <<'EOF';
ifdef WARNING1
$(warning warning is $(WARNING1))
endif
ifdef WARNING2
$(warning warning is $(WARNING2))
endif
ifdef WARNING3
all: some; @echo hi $(warning warning is $(WARNING3))
endif
ifdef WARNING4
all: some; @echo hi
@echo there $(warning warning is $(WARNING4))
endif
some: ; @echo Some stuff
EOF
close(MAKEFILE);
# Test #1
&run_make_with_options($makefile, "WARNING1=yes", &get_logfile, 0);
$answer = "$makefile:2: warning is yes\nSome stuff\n";
&compare_output($answer,&get_logfile(1));
# Test #2
&run_make_with_options($makefile, "WARNING2=no", &get_logfile, 0);
$answer = "$makefile:6: warning is no\nSome stuff\n";
&compare_output($answer,&get_logfile(1));
# Test #3
&run_make_with_options($makefile, "WARNING3=maybe", &get_logfile, 0);
$answer = "Some stuff\n$makefile:10: warning is maybe\nhi\n";
&compare_output($answer,&get_logfile(1));
# Test #4
&run_make_with_options($makefile, "WARNING4=definitely", &get_logfile, 0);
$answer = "Some stuff\n$makefile:15: warning is definitely\nhi\nthere\n";
&compare_output($answer,&get_logfile(1));
# Test linenumber offset
run_make_test(q!
all: one two
$(warning in $@ line 3)
@true
$(warning in $@ line 5)
one two:
$(warning in $@ line 8)
@true
$(warning in $@ line 10)
!,
'', "#MAKEFILE#:8: in one line 8
#MAKEFILE#:10: in one line 10
#MAKEFILE#:8: in two line 8
#MAKEFILE#:10: in two line 10
#MAKEFILE#:3: in all line 3
#MAKEFILE#:5: in all line 5\n");
# This tells the test driver that the perl test script executed properly.
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:
@@ -0,0 +1,163 @@
# -*-perl-*-
$description = "The following test creates a makefile to test wildcard
expansions and the ability to put a command on the same
line as the target name separated by a semi-colon.";
$details = "\
This test creates 4 files by the names of 1.example,
two.example and 3.example. We execute three tests. The first
executes the print1 target which tests the '*' wildcard by
echoing all filenames by the name of '*.example'. The second
test echo's all files which match '?.example' and
[a-z0-9].example. Lastly we clean up all of the files using
the '*' wildcard as in the first test";
touch("example.1");
touch("example.two");
touch("example.3");
touch("example.for");
touch("example._");
# TEST #1
# -------
run_make_test(qq/
.PHONY: print1 print2 clean
print1: ;\@echo \$(wildcard example.*)
print2:
\t\@echo \$(wildcard example.?)
\t\@echo \$(wildcard example.[a-z0-9])
\t\@echo \$(wildcard example.[!A-Za-z_\\!])
clean:
\t$CMD_rmfile \$(wildcard example.*)
/,
'print1', "example.1 example.3 example._ example.for example.two\n");
# TEST #2
# -------
run_make_test(undef, 'print2', "example.1 example.3 example._\n"
."example.1 example.3\n"
."example.1 example.3\n");
# TEST #3
# -------
$answer = "$CMD_rmfile example.1 example.3 example._ example.for example.two";
if ($vos)
{
$answer .= " \n";
}
else
{
$answer .= "\n";
}
run_make_test(undef, 'clean', $answer);
# TEST #4: Verify that failed wildcards don't return the pattern
run_make_test(q!
all: ; @echo $(wildcard xz--y*.7)
!,
'', "\n");
# TEST #5: wildcard used to verify file existence
touch('xxx.yyy');
run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!, '', "file=xxx.yyy\n");
unlink('xxx.yyy');
run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!, '', "file=\n");
# TEST #7: verify that when the input pattern has a trailing slash wildcard
# returns only directories.
#
# Currently this doesn't work with our embedded GLOB so disable it.
# -------
if (get_config('USE_SYSTEM_GLOB') eq 'yes') {
touch("hellof");
mkdir("hellod", 0770);
mkdir("hellod/worldd", 0770);
touch("hellod/worldf");
mkdir("hellod/worldd/kend1", 0770);
mkdir("hellod/worldd/kend2", 0770);
touch("hellod/worldd/kenf1");
touch("hellod/worldd/kenf2");
run_make_test(qq!
print3:
\t\@echo \$(wildcard hello*)
\t\@echo \$(wildcard hello*/)
\t\@echo \$(wildcard hellod/world*)
\t\@echo \$(wildcard hellod/world*/)
\t\@echo \$(wildcard hello* hellod/world*)
\t\@echo \$(wildcard hello*/ hellod/world*/)
\t\@echo \$(wildcard hellod/*)
\t\@echo \$(wildcard hellod/*/)
\t\@echo \$(wildcard */world*)
\t\@echo \$(wildcard */worldd/)
\t\@echo \$(wildcard hellod/*/ken*/)
\t\@echo \$(wildcard hellod/*/ken?[12])
\t\@echo \$(wildcard hellod/*/ken?[12]/)
!, '',
"hellod hellof\n"
."hellod/\n"
."hellod/worldd hellod/worldf\n"
."hellod/worldd/\n"
."hellod hellof hellod/worldd hellod/worldf\n"
."hellod/ hellod/worldd/\n"
."hellod/worldd hellod/worldf\n"
."hellod/worldd/\n"
."hellod/worldd hellod/worldf\n"
."hellod/worldd/\n"
."hellod/worldd/kend1/ hellod/worldd/kend2/\n"
."hellod/worldd/kend1 hellod/worldd/kend2 "
."hellod/worldd/kenf1 hellod/worldd/kenf2\n"
."hellod/worldd/kend1/ hellod/worldd/kend2/\n");
unlink('hellof', 'hellod/worldf', 'hellod/worldd/kenf1',
'hellod/worldd/kenf2');
foreach $d ('hellod/worldd/kend1', 'hellod/worldd/kend2', 'hellod/worldd',
'hellod') {
rmdir($d);
}
}
if ($port_type ne 'W32') {
# Check wildcard on the root directory
run_make_test('print4: ; @echo $(wildcard /)', '', "/\n");
}
if ($port_type ne 'W32' && eval { symlink("",""); 1 }) {
# TEST #6: check for wildcards matching directories
# See SV 53465
my $dir = '__rdir';
my $lnk = '__ldir';
mkdir($dir, 0777);
symlink($dir, $lnk);
run_make_test(qq!all: ; \@echo \$(wildcard $lnk*/.)!, '', "$lnk/.");
unlink($lnk);
rmdir($dir);
# Test for dangling symlinks
# This doesn't work with the built-in glob... needs to be updated!
if (get_config('USE_SYSTEM_GLOB') eq 'yes') {
symlink($dir, $lnk);
run_make_test(qq!all: ; \@echo \$(wildcard $lnk)!, '', "$lnk");
unlink($lnk);
}
}
1;
@@ -0,0 +1,175 @@
# -*-perl-*-
$description = "\
Test the word, words, wordlist, firstword, and lastword functions.\n";
$details = "\
Produce a variable with a large number of words in it,
determine the number of words, and then read each one back.\n";
run_make_test('
string := word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl
string2 := $(string) $(string) $(string) $(string) $(string) $(string) $(string)
string3 := $(string2) $(string2) $(string2) $(string2) $(string2) $(string2) $(string2)
string4 := $(string3) $(string3) $(string3) $(string3) $(string3) $(string3) $(string3)
.RECIPEPREFIX = >
all:
> @echo $(words $(string))
> @echo $(words $(string4))
> @echo $(word 1, $(string))
> @echo $(word 100, $(string))
> @echo $(word 1 , $(string))
> @echo $(word 1000, $(string3))
> @echo $(word 9223372036854775807, $(string2))
> @echo $(wordlist 3, 4, $(string))
> @echo $(wordlist 4, 3, $(string))
> @echo $(wordlist 1 , 6 , $(string))
> @echo $(wordlist 5,7, $(string))
> @echo $(wordlist 100, 110, $(string))
> @echo $(wordlist 7, 10, $(string2))
> @echo $(wordlist 9223372036854775807, 0, $(string2))
', '', "6\n"
."2058\n"
."word.pl\n"
."\n"
."word.pl\n"
."\n"
."\n"
."FORCE.pl word.pl\n"
."\n"
."word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl\n"
."generic_test.perl MAKEFILES_variable.pl\n"
."\n"
."word.pl general_test2.pl FORCE.pl word.pl\n"
."\n"
);
# Test error conditions
run_make_test('FOO = foo bar biz baz
word-e1: ; @echo $(word ,$(FOO))
word-e2: ; @echo $(word abc ,$(FOO))
word-e3: ; @echo $(word 1a,$(FOO))
word-e4: ; @echo $(word 9999999999999999999,$(FOO))
wordlist-e1: ; @echo $(wordlist ,,$(FOO))
wordlist-e2: ; @echo $(wordlist abc ,,$(FOO))
wordlist-e3: ; @echo $(wordlist 1, 12a ,$(FOO))',
'word-e1',
"#MAKEFILE#:3: *** invalid first argument to 'word' function: empty value. Stop.",
512);
run_make_test(undef,
'word-e2',
"#MAKEFILE#:4: *** invalid first argument to 'word' function: 'abc '. Stop.",
512);
run_make_test(undef,
'word-e3',
"#MAKEFILE#:5: *** invalid first argument to 'word' function: '1a'. Stop.",
512);
run_make_test(undef,
'word-e4',
"#MAKEFILE#:6: *** invalid first argument to 'word' function: '9999999999999999999' out of range. Stop.",
512);
run_make_test(undef,
'wordlist-e1',
"#MAKEFILE#:8: *** invalid first argument to 'wordlist' function: empty value. Stop.",
512);
run_make_test(undef,
'wordlist-e2',
"#MAKEFILE#:9: *** invalid first argument to 'wordlist' function: 'abc '. Stop.",
512);
run_make_test(undef,
'wordlist-e3',
"#MAKEFILE#:10: *** invalid second argument to 'wordlist' function: ' 12a '. Stop.",
512);
# Test error conditions again, but this time in a variable reference
run_make_test('FOO = foo bar biz baz
W = $(word $x,$(FOO))
WL = $(wordlist $s,$e,$(FOO))
word-e: ; @echo $(W)
wordlist-e: ; @echo $(WL)',
'word-e x=',
"#MAKEFILE#:3: *** invalid first argument to 'word' function: empty value. Stop.",
512);
run_make_test(undef,
'word-e x=abc',
"#MAKEFILE#:3: *** invalid first argument to 'word' function: 'abc'. Stop.",
512);
run_make_test(undef,
'word-e x=0',
"#MAKEFILE#:3: *** first argument to 'word' function must be greater than 0. Stop.",
512);
run_make_test(undef,
'wordlist-e s= e=',
"#MAKEFILE#:4: *** invalid first argument to 'wordlist' function: empty value. Stop.",
512);
run_make_test(undef,
'wordlist-e s=abc e=',
"#MAKEFILE#:4: *** invalid first argument to 'wordlist' function: 'abc'. Stop.",
512);
run_make_test(undef,
'wordlist-e s=4 e=12a',
"#MAKEFILE#:4: *** invalid second argument to 'wordlist' function: '12a'. Stop.",
512);
run_make_test(undef,
'wordlist-e s=0 e=12',
"#MAKEFILE#:4: *** invalid first argument to 'wordlist' function: '0'. Stop.",
512);
run_make_test(undef,
'wordlist-e s=1 e=-1',
"#MAKEFILE#:4: *** invalid second argument to 'wordlist' function: '-1'. Stop.",
512);
# TEST #8 -- test $(firstword )
#
run_make_test('
void :=
list := $(void) foo bar baz #
a := $(word 1,$(list))
b := $(firstword $(list))
.PHONY: all
all: ; @test "$a" = "$b" && echo $a
',
'',
'foo');
# TEST #9 -- test $(lastword )
#
run_make_test('
void :=
list := $(void) foo bar baz #
a := $(word $(words $(list)),$(list))
b := $(lastword $(list))
.PHONY: all
all: ; @test "$a" = "$b" && echo $a
',
'',
'baz');
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,230 @@
# -*-perl-*-
$description = "Test backslash-newline handling.";
$details = "";
# TEST #1
# -------
# Backslash-newlines in recipes
# These are basic backslash-newlines with no tricks
run_make_test("fast:;\@echo fa\\\nst\n",
'', 'fast');
run_make_test("slow:;\@: no-op; echo sl\\\now\n",
'', 'slow');
run_make_test("dquote:;\@echo \"dqu\\\note\"\n",
'', 'dquote');
# Single quotes don't behave the same in Windows
if ($port_type ne 'W32') {
run_make_test("squote:;\@echo 'squ\\\note'\n",
'', "squ\\\note");
}
# Ensure that a leading prefix character is omitted
run_make_test("fast:;\@echo fa\\\n\tst\n",
'', 'fast');
run_make_test("slow:;\@: no-op; echo sl\\\n\tow\n",
'', 'slow');
run_make_test("dquote:;\@echo \"dqu\\\n\tote\"\n",
'', 'dquote');
# Single quotes don't behave the same in Windows
if ($port_type ne 'W32') {
run_make_test("squote:;\@echo 'squ\\\n\tote'\n",
'', "squ\\\note");
}
# Ensure that ONLY the leading prefix character is omitted
run_make_test("fast:;\@echo fa\\\n\t st\n",
'', 'fa st');
run_make_test("slow:;\@: no-op; echo sl\\\n\t\tow\n",
'', "sl ow");
run_make_test("dquote:;\@echo \"dqu\\\n\t ote\"\n",
'', 'dqu ote');
run_make_test("squote:;\@echo 'squ\\\n\t\t ote'\n",
'', "squ\\\n\t ote");
# Backslash-newlines in variable values
# Simple
run_make_test(q!
var = he\
llo
var:;@echo '|$(var)|'!,
'', "|he llo|");
# Condense trailing space
run_make_test(q!
var = he \
llo
var:;@echo '|$(var)|'!,
'', "|he llo|");
# Remove leading space
run_make_test(q!
var = he\
llo
var:;@echo '|$(var)|'!,
'', "|he llo|");
# Multiple bs/nl condensed
run_make_test(q!
var = he\
\
\
llo
var:;@echo '|$(var)|'!,
'', "|he llo|");
# POSIX: Preserve trailing space
run_make_test(q!
.POSIX:
var = he \
llo
var:;@echo '|$(var)|'!,
'', "|he llo|");
# POSIX: One space per bs-nl
run_make_test(q!
.POSIX:
var = he\
\
\
llo
var:;@echo '|$(var)|'!,
'', "|he llo|");
# Savannah #39035: handle whitespace in call
run_make_test(q!
f = echo $(1)
t:; @$(call f,"a \
b"); \
$(call f,"a \
b")
!,
'', "a b\na b\n");
# Savannah #38945: handle backslash CRLF
# We need our own makefile so we can set binmode
my $m1 = get_tmpfile();
open(MAKEFILE, "> $m1");
binmode(MAKEFILE);
print MAKEFILE "FOO = foo \\\r\n";
close(MAKEFILE);
my $m2 = get_tmpfile();
open(MAKEFILE, "> $m2");
print MAKEFILE "include $m1\ndefine BAR\nall: ; \@echo \$(FOO) bar\nendef\n\$(eval \$(BAR))\n";
close(MAKEFILE);
run_make_with_options($m2, '', get_logfile());
compare_output("foo bar\n", get_logfile(1));
# Test different types of whitespace, and bsnl inside functions
sub xlate
{
$_ = $_[0];
s/\\r/\r/g;
s/\\t/\t/g;
s/\\f/\f/g;
s/\\n/\n/g;
return $_;
}
run_make_test(xlate(q!
$(foreach\r a \t , b\t c \r ,$(info $a \r ) )
all:;@:
!),
'', "b \r \nc \r \n");
run_make_test(xlate(q!
all:;@:$(foreach\r a \t , b\t c \r ,$(info $a \r ) )
!),
'', "b \r \nc \r \n");
run_make_test(xlate(q!
$(foreach \
\r a \t\
, b\t \
c \r ,$(info \
$a \r ) \
)
all:;@:
!),
'', "b \r \nc \r \n");
run_make_test(xlate(q!
all:;@:$(foreach \
\r a \t\
, b\t \
c \r ,$(info \
$a \r ) \
)
!),
'', "b \r \nc \r \n");
run_make_test(xlate(q!
define FOO
$(foreach
\r a \t
, b\t
c \r ,$(info
$a \r )
)
endef
$(FOO)
all:;@:
!),
'', "b \r \nc \r \n");
run_make_test(xlate(q!
define FOO
$(foreach
\r a \t
, b\t
c \r ,$(info
$a \r )
)
endef
all:;@:$(FOO)
!),
'', "b \r \nc \r \n");
# Test variables in recipes that expand to multiple lines
run_make_test(q!
define var
echo foo
echo bar
endef
all:;$(var)
!,
'', "echo foo\nfoo\necho bar\nbar\n");
run_make_test(q!
define var
echo foo
@
echo bar
endef
all:;$(var)
!,
'', "echo foo\nfoo\necho bar\nbar\n");
1;
@@ -0,0 +1,9 @@
# -*-perl-*-
$description = "Make sure make exits with an error if stdout is full.";
-e '/dev/full' or return -1;
run_make_test("\n", '-v > /dev/full', '/^#MAKE#: write error/', 256);
1;
@@ -0,0 +1,22 @@
# -*-perl-*-
$description = "Make sure make exits with an error if fopen fails.";
# For some reason on Cygwin, make exits with no error message after
# it recurses for a while.
$^O =~ /cygwin/ and return -1;
# Recurse infinitely until we run out of open files, and ensure we
# fail with a non-zero exit code. Don't bother to test the output
# since it's hard to know what it will be, exactly.
# See Savannah bug #27374.
# Use a longer-than-normal timeout: some systems have more FDs available?
# We also set ulimit -n 512 in check-regression in Makefile.am, which see.
# See Savannah bug #42390.
run_make_test(q!
include $(lastword $(MAKEFILE_LIST))
!,
'', undef, 512, 300);
1;
@@ -0,0 +1,51 @@
# -*-perl-*-
$description = "The following test creates a makefile to test the
simple functionality of make. It mimics the
rebuilding of a product with dependencies.
It also tests the simple definition of VPATH.";
open(MAKEFILE,"> $makefile");
print MAKEFILE <<EOF;
VPATH = $workdir
edit: main.o kbd.o commands.o display.o \\
insert.o
\t\@echo cc -o edit main.o kbd.o commands.o display.o \\
insert.o
main.o : main.c defs.h
\t\@echo cc -c main.c
kbd.o : kbd.c defs.h command.h
\t\@echo cc -c kbd.c
commands.o : command.c defs.h command.h
\t\@echo cc -c commands.c
display.o : display.c defs.h buffer.h
\t\@echo cc -c display.c
insert.o : insert.c defs.h buffer.h
\t\@echo cc -c insert.c
EOF
close(MAKEFILE);
@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h",
"$workdir${pathsep}kbd.c","$workdir${pathsep}command.h",
"$workdir${pathsep}commands.c","$workdir${pathsep}display.c",
"$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c",
"$workdir${pathsep}command.c");
&touch(@files_to_touch);
&run_make_with_options($makefile,"",&get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = "cc -c main.c\ncc -c kbd.c\ncc -c commands.c\ncc -c display.c
cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o insert.o\n";
# COMPARE RESULTS
if (&compare_output($answer,&get_logfile(1))) {
unlink @files_to_touch;
}
1;
@@ -0,0 +1,50 @@
# -*-perl-*-
$description = "The following test creates a makefile to test the
simple functionality of make. It is the same as
general_test1 except that this one tests the
definition of a variable to hold the object filenames.";
open(MAKEFILE,"> $makefile");
# The contents of the Makefile ...
print MAKEFILE <<EOF;
VPATH = $workdir
objects = main.o kbd.o commands.o display.o insert.o
edit: \$(objects)
\t\@echo cc -o edit \$(objects)
main.o : main.c defs.h
\t\@echo cc -c main.c
kbd.o : kbd.c defs.h command.h
\t\@echo cc -c kbd.c
commands.o : command.c defs.h command.h
\t\@echo cc -c commands.c
display.o : display.c defs.h buffer.h
\t\@echo cc -c display.c
insert.o : insert.c defs.h buffer.h
\t\@echo cc -c insert.c
EOF
close(MAKEFILE);
@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h",
"$workdir${pathsep}kbd.c","$workdir${pathsep}command.h",
"$workdir${pathsep}commands.c","$workdir${pathsep}display.c",
"$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c",
"$workdir${pathsep}command.c");
&touch(@files_to_touch);
&run_make_with_options($makefile,"",&get_logfile);
# Create the answer to what should be produced by this Makefile
$answer = "cc -c main.c\ncc -c kbd.c\ncc -c commands.c\ncc -c display.c
cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o insert.o\n";
if (&compare_output($answer,&get_logfile(1))) {
unlink @files_to_touch;
}
1;
@@ -0,0 +1,347 @@
# -*-perl-*-
$description = "\
This tests random features of the parser that need to be supported, and
which have either broken at some point in the past or seem likely to
break.";
run_make_test("
# We want to allow both empty commands _and_ commands that resolve to empty.
EMPTY =
.PHONY: all a1 a2 a3 a4
all: a1 a2 a3 a4
a1:;
a2:
\t
a3:;\$(EMPTY)
a4:
\t\$(EMPTY)
\# Non-empty lines that expand to nothing should also be ignored.
STR = \# Some spaces
TAB = \t \# A TAB and some spaces
\$(STR)
\$(STR) \$(TAB)",
'', "#MAKE#: Nothing to be done for 'all'.");
# TEST 2
# Make sure files without trailing newlines are handled properly.
# Have to use the old style invocation to test this.
$makefile2 = &get_tmpfile;
open(MAKEFILE, "> $makefile2");
print MAKEFILE "all:;\@echo FOO = \$(FOO)\nFOO = foo";
close(MAKEFILE);
&run_make_with_options($makefile2,"",&get_logfile);
$answer = "FOO = foo\n";
&compare_output($answer,&get_logfile(1));
# TEST 3
# Check semicolons in variable references
run_make_test('
$(if true,$(info true; true))
all: ; @:
',
'', 'true; true');
# TEST 4
# Check that backslashes in command scripts are handled according to POSIX.
# Checks Savannah bug # 1332.
# Test the fastpath / no quotes
run_make_test('
all:
@echo foo\
bar
@echo foo\
bar
@echo foo\
bar
@echo foo\
bar
@echo foo \
bar
@echo foo \
bar
@echo foo \
bar
@echo foo \
bar
',
'', 'foobar
foobar
foo bar
foo bar
foo bar
foo bar
foo bar
foo bar');
# Test the fastpath / single quotes
# Single quotes don't behave the same in Windows
if ($port_type ne 'W32') {
run_make_test(q!
all:
@echo 'foo\
bar'
@echo 'foo\
bar'
@echo 'foo\
bar'
@echo 'foo\
bar'
@echo 'foo \
bar'
@echo 'foo \
bar'
@echo 'foo \
bar'
@echo 'foo \
bar'
!,
'', 'foo\
bar
foo\
bar
foo\
bar
foo\
bar
foo \
bar
foo \
bar
foo \
bar
foo \
bar');
}
# Test the fastpath / double quotes
run_make_test('
all:
@echo "foo\
bar"
@echo "foo\
bar"
@echo "foo\
bar"
@echo "foo\
bar"
@echo "foo \
bar"
@echo "foo \
bar"
@echo "foo \
bar"
@echo "foo \
bar"
',
'', 'foobar
foobar
foo bar
foo bar
foo bar
foo bar
foo bar
foo bar');
# Test the slow path / no quotes
run_make_test('
all:
@echo hi; echo foo\
bar
@echo hi; echo foo\
bar
@echo hi; echo foo\
bar
@echo hi; echo foo\
bar
@echo hi; echo foo \
bar
@echo hi; echo foo \
bar
@echo hi; echo foo \
bar
@echo hi; echo foo \
bar
',
'', 'hi
foobar
hi
foobar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar');
# Test the slow path / no quotes. This time we put the slow path
# determination _after_ the backslash-newline handling.
run_make_test('
all:
@echo foo\
bar; echo hi
@echo foo\
bar; echo hi
@echo foo\
bar; echo hi
@echo foo\
bar; echo hi
@echo foo \
bar; echo hi
@echo foo \
bar; echo hi
@echo foo \
bar; echo hi
@echo foo \
bar; echo hi
',
'', 'foobar
hi
foobar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar
hi');
# Test the slow path / single quotes
run_make_test(q!
all:
@echo hi; echo 'foo\
bar'
@echo hi; echo 'foo\
bar'
@echo hi; echo 'foo\
bar'
@echo hi; echo 'foo\
bar'
@echo hi; echo 'foo \
bar'
@echo hi; echo 'foo \
bar'
@echo hi; echo 'foo \
bar'
@echo hi; echo 'foo \
bar'
!,
'', 'hi
foo\
bar
hi
foo\
bar
hi
foo\
bar
hi
foo\
bar
hi
foo \
bar
hi
foo \
bar
hi
foo \
bar
hi
foo \
bar');
# Test the slow path / double quotes
run_make_test('
all:
@echo hi; echo "foo\
bar"
@echo hi; echo "foo\
bar"
@echo hi; echo "foo\
bar"
@echo hi; echo "foo\
bar"
@echo hi; echo "foo \
bar"
@echo hi; echo "foo \
bar"
@echo hi; echo "foo \
bar"
@echo hi; echo "foo \
bar"
',
'', 'hi
foobar
hi
foobar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar
hi
foo bar');
run_make_test('x:;@-exit 1', '', "#MAKE#: [#MAKEFILE#:1: x] Error 1 (ignored)\n");
# Slow path with odd setups
if ($port_type ne 'W32') {
run_make_test(q!
slow: SHELL := echo
slow: .SHELLFLAGS := hoho
slow:; @foo bar
!,
'', "hoho foo bar\n");
run_make_test(q!
slow: SHELL := echo hi
slow: .SHELLFLAGS := ho ho
slow:; @foo bar
!,
'', "hi ho ho foo bar\n");
run_make_test(q!
slow: SHELL := echo hi
slow: .SHELLFLAGS := 'ho;ho'
slow:; @foo bar
!,
'', "hi ho;ho foo bar\n");
}
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:
@@ -0,0 +1,146 @@
# -*-perl-*-
$description = "\
This tests random features of make's algorithms, often somewhat obscure,
which have either broken at some point in the past or seem likely to
break.";
run_make_test('
# Make sure that subdirectories built as prerequisites are actually handled
# properly.
all: dir/subdir/file.a
dir/subdir: ; @echo mkdir -p dir/subdir
dir/subdir/file.b: dir/subdir ; @echo touch dir/subdir/file.b
dir/subdir/%.a: dir/subdir/%.b ; @echo cp $< $@',
'', "mkdir -p dir/subdir\ntouch dir/subdir/file.b\ncp dir/subdir/file.b dir/subdir/file.a\n");
# Test implicit rules
&touch('foo.c');
run_make_test('foo: foo.o',
'CC="@echo cc" OUTPUT_OPTION=',
'cc -c foo.c
cc foo.o -o foo');
unlink('foo.c');
# Test implicit rules with '$' in the name (see se_implicit)
run_make_test(q!
%.foo : baz$$bar ; @echo 'done $<'
%.foo : bar$$baz ; @echo 'done $<'
test.foo:
baz$$bar bar$$baz: ; @echo '$@'
!,
'',
"baz\$bar\ndone baz\$bar");
# Test implicit rules with '$' in the name (see se_implicit)
# Use the '$' in the pattern.
run_make_test(q!
%.foo : %$$bar ; @echo 'done $<'
test.foo:
test$$bar: ; @echo '$@'
!,
'',
"test\$bar\ndone test\$bar");
# Make sure that subdirectories built as prerequisites are actually handled
# properly... this time with '$'
run_make_test(q!
all: dir/subdir/file.$$a
dir/subdir: ; @echo mkdir -p '$@'
dir/subdir/file.$$b: dir/subdir ; @echo touch '$@'
dir/subdir/%.$$a: dir/subdir/%.$$b ; @echo 'cp $< $@'
!,
'', "mkdir -p dir/subdir\ntouch dir/subdir/file.\$b\ncp dir/subdir/file.\$b dir/subdir/file.\$a\n");
# Test odd whitespace at the beginning of a line
run_make_test("
all:
\f
\\
\f \\
\013 \\
all: ; \@echo hi
",
'', "hi\n");
# SV-56834 Ensure setting PATH in the makefile works properly
my $sname = "foobar$scriptsuffix";
mkdir('sd', 0775);
create_file("sd/$sname", "exit 0\n");
chmod 0755, "sd/$sname";
run_make_test(qq!
PATH := sd
all: ; $sname >/dev/null
!,
'', "$sname >/dev/null\n");
# Don't use the general PATH if not found on the target path
$ENV{PATH} = "$ENV{PATH}:sd";
my ($ernum, $erstr);
if ($port_type eq 'W32') {
$ernum = 2;
$erstr = "process_begin: CreateProcess(NULL, $sname, ...) failed.\nmake (e=2): The system cannot find the file specified.";
} else {
$ernum = 127;
$erstr = "#MAKE#: $sname: $ERR_no_such_file";
}
run_make_test(qq!
PATH := ..
all: ; $sname
!,
'', "$sname\n$erstr\n#MAKE#: *** [#MAKEFILE#:3: all] Error $ernum", 512);
unlink("sd/$sname");
rmdir('sd');
# Ensure that local programs are not found if "." is not on the PATH
create_file($sname, '');
chmod 0755, $sname;
if ($port_type eq 'W32') {
$ernum = -1;
$erstr = "";
} else {
$ernum = 127;
$erstr = "#MAKE#: $sname: $ERR_no_such_file\n";
}
run_make_test(qq!
PATH := ..
all: ; $sname
!,
'', "$sname\n$erstr#MAKE#: *** [#MAKEFILE#:3: all] Error $ernum", 512);
unlink($sname);
# SV 57674: ensure we use a system default PATH if one is not set
delete $ENV{PATH};
run_make_test(q!
a: ; @echo hi
!,
'', "hi\n");
1;
@@ -0,0 +1,14 @@
# -*-perl-*-
$description = "Test utf8 handling.";
$details = "";
# Variable names containing UTF8 characters
run_make_test("
\xe2\x96\xaa := hello
\$(info \$(\xe2\x96\xaa))
all:
",
'', "hello\n#MAKE#: Nothing to be done for 'all'.");
1;
@@ -0,0 +1,87 @@
# -*-perl-*-
$description = "Test make -B (always remake) option.\n";
$details = "\
Construct a simple makefile that builds a target.
Invoke make once, so it builds everything. Invoke it again and verify
that nothing is built. Then invoke it with -B and verify that everything
is built again.";
&touch('bar.x');
run_make_test('
.SUFFIXES:
.PHONY: all
all: foo
foo: bar.x
@echo cp $< $@
@echo "" > $@
',
'', 'cp bar.x foo');
run_make_test(undef, '', "#MAKE#: Nothing to be done for 'all'.");
run_make_test(undef, '-B', 'cp bar.x foo');
# Put the timestamp for foo into the future; it should still be remade.
utouch(1000, 'foo');
run_make_test(undef, '', "#MAKE#: Nothing to be done for 'all'.");
run_make_test(undef, '-B', 'cp bar.x foo');
# Clean up
rmfiles('bar.x', 'foo');
# Test -B with the re-exec feature: we don't want to re-exec forever
# Savannah bug # 7566
run_make_test('
all: ; @:
$(info MAKE_RESTARTS=$(MAKE_RESTARTS))
include foo.x
foo.x: ; @touch $@
',
'-B', 'MAKE_RESTARTS=
MAKE_RESTARTS=1');
rmfiles('foo.x');
# Test -B with the re-exec feature: we DO want -B in the "normal" part of the
# makefile.
&touch('blah.x');
run_make_test('
all: blah.x ; @echo $@
$(info MAKE_RESTARTS=$(MAKE_RESTARTS))
include foo.x
foo.x: ; @touch $@
blah.x: ; @echo $@
',
'-B', 'MAKE_RESTARTS=
MAKE_RESTARTS=1
blah.x
all');
rmfiles('foo.x', 'blah.x');
# Test that $? is set properly with -B; all prerequisites will be newer!
utouch(-10, 'x.b');
touch('x.a');
run_make_test(q!
x.a: x.b ; @echo $?
!,
'-B', "x.b\n");
unlink(qw(x.a x.b));
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:
@@ -0,0 +1,66 @@
# -*-perl-*-
$description = "Test the -C option to GNU make.";
$details = "\
This test is similar to the clean test except that this test creates the file
to delete in the work directory instead of the current directory. Make is
called from another directory using the -C workdir option so that it can both
find the makefile and the file to delete in the work directory.";
$example = $workdir . $pathsep . "EXAMPLE";
open(MAKEFILE,"> $makefile");
print MAKEFILE qq!
all: ; \@echo This makefile did not clean the dir ... good
clean: ; $CMD_rmfile EXAMPLE\$(ext)
!;
close(MAKEFILE);
# TEST #1
# -------
touch($example);
run_make_with_options("${testname}.mk", "-C $workdir clean", &get_logfile);
use Cwd;
chdir $workdir;
$wpath = cwd();
chdir $cwdpath;
if (-f $example) {
$test_passed = 0;
}
# Create the answer to what should be produced by this Makefile
$answer = "$make_name: Entering directory '$wpath'\n"
. "$CMD_rmfile EXAMPLE\n"
. "$make_name: Leaving directory '$wpath'\n";
compare_output($answer,&get_logfile(1));
# TEST #2
# -------
# Do it again with trailing "/"; this should work the same
$example .= "slash";
touch($example);
run_make_with_options("${testname}.mk", "-C $workdir/ clean ext=slash", &get_logfile);
if (-f $example) {
$test_passed = 0;
}
# Create the answer to what should be produced by this Makefile
$answer = "$make_name: Entering directory '$wpath'\n"
. "$CMD_rmfile EXAMPLEslash\n"
. "$make_name: Leaving directory '$wpath'\n";
&compare_output($answer,&get_logfile(1));
unlink($example);
1;
@@ -0,0 +1,116 @@
# -*-perl-*-
$description = "The following test creates a makefile to test the -I option.";
$details = "\
This test tests the -I option by including a filename in
another directory and giving make that directory name
under -I in the command line. Without this option, the make
would fail to find the included file. It also checks to make
sure that the -I option gets passed to recursive makes.";
use File::Spec;
# Create a directory and put a makefile in it.
# We can't put it in the current directory since that's automatically searched
# anyway.
my $subdir = 'idir';
mkdir($subdir, 0777);
my $included = 'ifile.mk';
my $ipath = File::Spec->catfile($subdir, $included);
create_file($ipath, "
ANOTHER:
\t\@echo This is another included makefile
recurse:
\t\@\$(MAKE) ANOTHER -f \$(main_makefile)\n");
my $nosuch = "#MAKEFILE#:5: $included: $ERR_no_such_file
#MAKE#: *** No rule to make target '$included'. Stop.\n";
# Verify that we get an error if we don't have -I
run_make_test(qq!
main_makefile := \$(firstword \$(MAKEFILE_LIST))
all:
\t\@echo There should be no errors for this makefile
include $included
!,
'', $nosuch, 512);
# Check basic -I works
run_make_test(undef, "-I $subdir all",
"There should be no errors for this makefile\n");
# Check that the included target works
run_make_test(undef, "-I $subdir ANOTHER",
"This is another included makefile\n");
# Check that -I is passed down through MAKEFLAGS
run_make_test(undef, "-I $subdir recurse",
"#MAKE#[1]: Entering directory '#PWD#'
This is another included makefile
#MAKE#[1]: Leaving directory '#PWD#'\n");
# Verify that we get an error if we add -I- to delete previous includes
run_make_test(undef, "-I $subdir -I- all", $nosuch, 512);
# Make another directory with the same name and make sure the right one is
# chosen if -I- stops the path.
mkdir('idir2', 0777);
my $ipath2 = File::Spec->catfile('idir2', $included);
create_file($ipath2, "This is a bad makefile!!\n");
run_make_test(undef, "-I idir2 -I $subdir ANOTHER",
"$included:1: *** missing separator. Stop.\n", 512);
run_make_test(undef, "-I idir2 -I - -I $subdir ANOTHER",
"This is another included makefile\n");
# Check that -I- is passed down through MAKEFLAGS
run_make_test(undef, "-I idir2 -I - -I $subdir recurse",
"#MAKE#[1]: Entering directory '#PWD#'
This is another included makefile
#MAKE#[1]: Leaving directory '#PWD#'\n");
unlink($ipath2);
rmdir('idir2');
# The only way to check if -I- voids included directories is to see if a file
# exists in one and try to include it. We very likely can't add our own files
# to the default directories since they're probably write-protected. This
# won't work if none of the default directories contain any files :-/
create_file('defaultdirs.mk', "\$(info \$(.INCLUDE_DIRS))\nall:;\@:\n");
my $cmd = subst_make_string("#MAKEPATH# -f defaultdirs.mk");
my @dirs = `$cmd`;
my $dirs = $dirs[0];
chomp $dirs;
unlink('defaultdirs.mk');
my $fn = undef;
foreach my $dn (split ' ', $dirs) {
# On Windows the default is "." which is bogus!
if ($dn ne '.') {
my @files = glob(File::Spec->catfile($dn, "*"));
if (@files) {
(undef, undef, $fn) = File::Spec->splitpath($files[0]);
last;
}
}
}
if ($fn) {
run_make_test("
all:;
include $fn
",
'-I-', "#MAKEFILE#:3: $fn: $ERR_no_such_file
#MAKE#: *** No rule to make target '$fn'. Stop.\n", 512);
}
unlink($ipath);
rmdir($subdir);
1;
@@ -0,0 +1,91 @@
# -*-perl-*-
$description = "Test make -W (what if) option.\n";
# Basic build
run_make_test('
a.x: b.x
a.x b.x: ; echo >> $@
',
'', "echo >> b.x\necho >> a.x");
# Run it again: nothing should happen
run_make_test(undef, '', "#MAKE#: 'a.x' is up to date.");
# Now run it with -W b.x: should rebuild a.x
run_make_test(undef, '-W b.x', 'echo >> a.x');
# Put the timestamp for a.x into the future; it should still be remade.
utouch(1000, 'a.x');
run_make_test(undef, '', "#MAKE#: 'a.x' is up to date.");
run_make_test(undef, '-W b.x', 'echo >> a.x');
# Clean up
rmfiles('a.x', 'b.x');
# Test -W with the re-exec feature: we don't want to re-exec forever
# Savannah bug # 7566
# First set it up with a normal build
run_make_test('
all: baz.x ; @:
include foo.x
foo.x: bar.x
@echo "\$$(info restarts=\$$(MAKE_RESTARTS))" > $@
@echo "touch $@"
bar.x: ; echo >> $@
baz.x: bar.x ; @echo "touch $@"
',
'', 'echo >> bar.x
touch foo.x
restarts=1
touch baz.x');
# Now run with -W bar.x
# Tweak foo.x's timestamp so the update will change it.
&utouch(1000, 'foo.x');
run_make_test(undef, '-W bar.x', "restarts=\ntouch foo.x\nrestarts=1\ntouch baz.x");
rmfiles('foo.x', 'bar.x');
# Test -W on vpath-found files: it should take effect.
# Savannah bug # 15341
mkdir('x-dir', 0777);
utouch(-20, 'x-dir/x');
touch('y');
run_make_test('
y: x ; @echo cp $< $@
',
'-W x-dir/x VPATH=x-dir',
'cp x-dir/x y');
# Make sure ./ stripping doesn't interfere with the match.
run_make_test('
y: x ; @echo cp $< $@
',
'-W ./x-dir/x VPATH=x-dir',
'cp x-dir/x y');
run_make_test(undef,
'-W x-dir/x VPATH=./x-dir',
'cp ./x-dir/x y');
unlink(qw(y x-dir/x));
rmdir('x-dir');
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:
@@ -0,0 +1,9 @@
# -*-perl-*-
$description = "Test make -d option.\n";
# sv 60777.
# Test that debug output is printed when both -d and --trace are specified.
run_make_test('all: ; :', '-d --trace', "/GNU Make/");
1;
@@ -0,0 +1,15 @@
# -*-perl-*-
$description = "The following test creates a makefile to ...";
$details = "";
$ENV{GOOGLE} = 'boggle';
run_make_test(q!
GOOGLE = bazzle
all:; @echo "$(GOOGLE)"
!,
'-e', "boggle\n");
1;
@@ -0,0 +1,162 @@
# -*-perl-*-
$description = "The following test tests that if you specify greater \n"
."than one '-f makefilename' on the command line, \n"
."that make concatenates them. This test creates three \n"
."makefiles and specifies all of them with the -f option \n"
."on the command line. To make sure they were concatenated, \n"
."we then call make with the rules from the concatenated \n"
."makefiles one at a time. Finally, it calls all three \n"
."rules in one call to make and checks that the output\n"
."is in the correct order.";
$makefile2 = &get_tmpfile;
$makefile3 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "all: \n";
print MAKEFILE "\t\@echo This is the output from the original makefile\n";
# END of Contents of MAKEFILE
close(MAKEFILE);
# Create a second makefile
open(MAKEFILE,"> $makefile2");
print MAKEFILE "TWO: \n";
print MAKEFILE "\t\@echo This is the output from makefile 2\n";
close(MAKEFILE);
# Create a third makefile
open(MAKEFILE,"> $makefile3");
print MAKEFILE "THREE: \n";
print MAKEFILE "\t\@echo This is the output from makefile 3\n";
close(MAKEFILE);
# Create the answer to what should be produced by this Makefile
$answer = "This is the output from the original makefile\n";
# Run make to catch the default rule
&run_make_with_options($makefile,"-f $makefile2 -f $makefile3",&get_logfile,0);
&compare_output($answer,&get_logfile(1));
# Run Make again with the rule from the second makefile: TWO
$answer = "This is the output from makefile 2\n";
&run_make_with_options($makefile,"-f $makefile2 -f $makefile3 TWO",&get_logfile,0);
&compare_output($answer,&get_logfile(1));
# Run Make again with the rule from the third makefile: THREE
$answer = "This is the output from makefile 3\n";
&run_make_with_options($makefile,
"-f $makefile2 -f $makefile3 THREE",
&get_logfile,
0);
&compare_output($answer,&get_logfile(1));
# Run Make again with ALL three rules in the order 2 1 3 to make sure
# that all rules are executed in the proper order
$answer = "This is the output from makefile 2\n";
$answer .= "This is the output from the original makefile\n";
$answer .= "This is the output from makefile 3\n";
&run_make_with_options($makefile,
"-f $makefile2 -f $makefile3 TWO all THREE",
&get_logfile,
0);
&compare_output($answer,&get_logfile(1));
# sv 62118.
# Validate all sorts of -f etc. options
my $hello = 'hello.mk';
my $bye = 'bye.mk';
my $byesrc = 'bye.mk.src';
create_file($hello, 'all:; $(info hello, world)
');
create_file($bye, 'def:; $(info bye, world)
bye.mk: bye.mk.src; touch $@
bye.mk.src:; touch $@
');
# These invocations use the empty filename string so that the test framework
# doesn't add any -f options on its own.
# Incorrect order of options. -R follows -f.
# Invocation of make is equivalent to
# echo 'all:; $(info hello, world)' | make -f bye.mk -fR - all
# There is bye.mk, but there is no 'R'.
# make runs the recipes from bye.mk and prints the error about missing 'R'.
# Ensure the newly created bye.src.mk is newer than bye.mk.
&utouch(-600, $bye);
run_make_test('', "-f$bye -fR - all", "#MAKE#: R: No such file or directory
touch bye.mk.src
touch bye.mk
#MAKE#: *** No rule to make target 'R'. Stop.
", 512);
my @opts;
my $answer;
# Test double -f-.
@opts = ('-f- -f-', '-f - -f -', '-f- -f -', '-f - -f-',
'-f- --file=-', '-f- --file -', '-f - --file=-', '-f - --file -',
'-f- --makefile=-', '-f- --makefile -',
'-f - --makefile=-', '-f - --makefile -',
'--file=- --makefile=-', '--file=- --makefile -',
'--file - --makefile=-', '--file - --makefile -');
for my $opt (@opts) {
# We shouldn't need this; if the options are wrong then make shouldn't try
# to read from stdin.
close(STDIN);
open(STDIN, "<", $hello) || die "$0: cannot open $hello for reading: $!";
run_make_test('', "-f$bye $opt", "#MAKE#: *** Makefile from standard input specified twice. Stop.\n", 512);
}
# -f is not followed by filename.
@opts = ('-f', '--file', '--makefile');
$answer = "/requires an argument/";
for my $opt (@opts) {
run_make_test('', $opt, $answer, 512);
}
# Test that make correctly parses all possible syntaxes to pipe make code to
# the standard input.
$answer = "touch bye.mk.src
touch bye.mk
hello, world
#MAKE#: 'all' is up to date.\n";
@opts = ('-f- all', '-f - all', '-Rf- all', '-Rf - all',
'--file=- all', '--file - all',
'--makefile=- all', '--makefile - all');
for my $opt (@opts) {
unlink($byesrc);
close(STDIN);
open(STDIN, "<", $hello) || die "$0: cannot open $hello for reading: $!";
# Ensure the newly created bye.src.mk is newer than bye.mk.
&utouch(-600, $bye);
run_make_test('', "-f$bye $opt", $answer);
}
close(STDIN);
unlink($hello, $bye, $byesrc);
# This tells the test driver that the perl test script executed properly.
1;
@@ -0,0 +1,115 @@
# -*-perl-*-
$description = "Test the make -k (don't stop on error) option.\n";
$details = "\
The makefile created in this test is a simulation of building
a small product. However, the trick to this one is that one
of the dependencies of the main target does not exist.
Without the -k option, make would fail immediately and not
build any part of the target. What we are looking for here,
is that make builds the rest of the dependencies even though
it knows that at the end it will fail to rebuild the main target.";
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE <<EOF;
VPATH = $workdir
edit: main.o kbd.o commands.o display.o
\t\@echo cc -o edit main.o kbd.o commands.o display.o
main.o : main.c defs.h
\t\@echo cc -c main.c
kbd.o : kbd.c defs.h command.h
\t\@echo cc -c kbd.c
commands.o : command.c defs.h command.h
\t\@echo cc -c commands.c
display.o : display.c defs.h buffer.h
\t\@echo cc -c display.c
EOF
# END of Contents of MAKEFILE
close(MAKEFILE);
@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h",
"$workdir${pathsep}command.h",
"$workdir${pathsep}commands.c","$workdir${pathsep}display.c",
"$workdir${pathsep}buffer.h",
"$workdir${pathsep}command.c");
&touch(@files_to_touch);
if ($vos) {
$error_code = 3307;
}
else {
$error_code = 512;
}
&run_make_with_options($makefile, "-k", &get_logfile, $error_code);
# Create the answer to what should be produced by this Makefile
$answer = "cc -c main.c
$make_name: *** No rule to make target 'kbd.c', needed by 'kbd.o'.
cc -c commands.c
cc -c display.c
$make_name: Target 'edit' not remade because of errors.\n";
# COMPARE RESULTS
&compare_output($answer, &get_logfile(1));
unlink(@files_to_touch) unless $keep;
# TEST 1: Make sure that top-level targets that depend on targets that
# previously failed to build, aren't attempted. Regression for PR/1634.
$makefile2 = &get_tmpfile;
open(MAKEFILE, "> $makefile2");
print MAKEFILE <<'EOF';
.SUFFIXES:
all: exe1 exe2; @echo making $@
exe1 exe2: lib; @echo cp $^ $@
lib: foo.o; @echo cp $^ $@
foo.o: ; exit 1
EOF
close(MAKEFILE);
&run_make_with_options($makefile2, "-k", &get_logfile, $error_code);
$answer = "exit 1
$make_name: *** [$makefile2:9: foo.o] Error 1
$make_name: Target 'all' not remade because of errors.\n";
&compare_output($answer, &get_logfile(1));
# TEST -- make sure we keep the error code if we can't create an included
# makefile.
if (defined $ERR_no_such_file) {
run_make_test('all: ; @echo hi
include ifile
ifile: no-such-file; exit 1
',
'-k',
"#MAKEFILE#:2: ifile: $ERR_no_such_file
#MAKE#: *** No rule to make target 'no-such-file', needed by 'ifile'.
#MAKEFILE#:2: Failed to remake makefile 'ifile'.\n",
512);
}
1;
@@ -0,0 +1,51 @@
# -*-perl-*-
# Date: Tue, 11 Aug 1992 09:34:26 -0400
# From: pds@lemming.webo.dg.com (Paul D. Smith)
$description = "Test load balancing (-l) option.";
$details = "\
This test creates a makefile where all depends on three rules
which contain the same body. Each rule checks for the existence
of a temporary file; if it exists an error is generated. If it
doesn't exist then it is created, the rule sleeps, then deletes
the temp file again. Thus if any of the rules are run in
parallel the test will fail. When make is called in this test,
it is given the -l option with a value of 0.0001. This ensures
that the load will be above this number and make will therefore
decide that it cannot run more than one job even though -j 4 was
also specified on the command line.";
# On Windows a very different algorithm is used.
$port_type eq 'W32' and return -1;
open(MAKEFILE,"> $makefile");
printf MAKEFILE q,
define test
if [ ! -f test-file ]; then \
echo >> test-file; sleep 2; %s test-file; \
else \
echo $@ FAILED; \
fi
endef
all : ONE TWO THREE
ONE : ; @$(test)
TWO : ; @$(test)
THREE : ; @$(test)
,, $CMD_rmfile;
close(MAKEFILE);
$mkoptions = "-l 0.0001";
$mkoptions .= " -j 4" if ($parallel_jobs);
# We have to wait longer than the default (5s).
&run_make_with_options($makefile, $mkoptions, &get_logfile, 0, 8);
$slurp = &read_file_into_string(&get_logfile(1));
if ($slurp =~ /cannot enforce load limit/) {
return -1;
}
&compare_output("", &get_logfile(1));
1;
@@ -0,0 +1,100 @@
# -*-perl-*-
$description = "Test the -n option.\n";
$details = "Try various uses of -n and ensure they all give the correct results.\n";
touch('orig');
run_make_test(q!
final: intermediate ; echo >> $@
intermediate: orig ; echo >> $@
!,
'', "echo >> intermediate\necho >> final\n");
# TEST 1
run_make_test(undef, '-Worig -n', "echo >> intermediate\necho >> final\n");
rmfiles(qw(orig intermediate final));
# We consider the actual updated timestamp of targets with all
# recursive commands, even with -n. Switching this to the new model
# is non-trivial because we use a trick below to change the log content
# before we compare it ...
$makefile2 = &get_tmpfile;
open(MAKEFILE, "> $makefile2");
print MAKEFILE <<'EOF';
.SUFFIXES:
BAR = # nothing
FOO = +$(BAR)
a: b; echo > $@
b: c; $(FOO)
EOF
close(MAKEFILE);
&utouch(-20, 'b');
&utouch(-10, 'a');
&touch('c');
# TEST 2
&run_make_with_options($makefile2, "", &get_logfile);
$answer = "$make_name: 'a' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST 3
&run_make_with_options($makefile2, "-n", &get_logfile);
$answer = "$make_name: 'a' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST 4
unlink(qw(a b));
&run_make_with_options($makefile2, "-t -n", &get_logfile);
open(DASH_N_LOG, ">>" . &get_logfile(1));
print DASH_N_LOG "a exists but should not!\n" if -e 'a';
print DASH_N_LOG "b exists but should not!\n" if -e 'b';
close(DASH_N_LOG);
&compare_output("touch b\ntouch a\n", &get_logfile(1));
# CLEANUP
unlink(qw(a b c));
# Ensure -n continues to be included with recursive/re-execed make
# See Savannah bug #38051
$topmake = &get_tmpfile;
$submake = &get_tmpfile;
open(MAKEFILE, "> $topmake");
print MAKEFILE <<"EOF";
foo: ; \@\$(MAKE) -f "$submake" bar
EOF
close(MAKEFILE);
# The bar target should print what would happen, but not actually run
open(MAKEFILE, "> $submake");
print MAKEFILE <<'EOF';
inc: ; touch $@
-include inc
bar: ; @echo $(strip $(MAKEFLAGS))
EOF
close(MAKEFILE);
&run_make_with_options($topmake, '-n --no-print-directory', &get_logfile);
$answer = subst_make_string("#MAKEPATH# -f \"$submake\" bar\ntouch inc\necho n --no-print-directory\n");
&compare_output($answer, &get_logfile(1));
unlink('inc');
1;
@@ -0,0 +1,86 @@
# -*-perl-*-
$description = "Test the -q option.\n";
$details = "Try various uses of -q and ensure they all give the correct results.\n";
# TEST 0
run_make_test(qq!
one:
two: ;
three: ; :
four: ; \$(.XY)
five: ; \\
\$(.XY)
six: ; \\
\$(.XY)
\t\$(.XY)
seven: ; \\
\$(.XY)
\t: foo
\t\$(.XY)
!,
'-q one', '');
# TEST 1
run_make_test(undef, '-q two', '');
# TEST 2
run_make_test(undef, '-q three', '', 256);
# TEST 3
run_make_test(undef, '-q four', '');
# TEST 4
run_make_test(undef, '-q five', '');
# TEST 5
run_make_test(undef, '-q six', '');
# TEST 6
run_make_test(undef, '-q seven', '', 256);
# TEST 7 : Savannah bug # 7144
run_make_test('
one:: ; @echo one
one:: ; @echo two
',
'-q', '', 256);
# TEST 7 : Savannah bug # 42249
# Make sure we exit with 1 even for prerequisite updates
run_make_test('
build-stamp: ; echo $@
build-arch: build-stamp
build-x: build-arch
build-y: build-x
',
'-q build-y', '', 256);
# TEST 8
# Make sure we exit with 2 on error even with -q
run_make_test('
build-stamp: ; echo $@
build-arch: build-stamp-2
build-x: build-arch
build-y: build-x
',
'-q build-y', "#MAKE#: *** No rule to make target 'build-stamp-2', needed by 'build-arch'. Stop.\n", 512);
# TEST 9 : Savannah bug # 47151
# Make sure we exit with 1 when invoking a recursive make
run_make_test('
foo: bar ; echo foo
bar: ; @$(MAKE) -f #MAKEFILE# baz
baz: ; echo baz
',
'-q foo', '', 256);
1;
@@ -0,0 +1,44 @@
# -*-perl-*-
$description = "Test removing default rules and variables";
$details = "DETAILS";
touch('xxx.c');
# Simple check
run_make_test("\n", '-r COMPILE.c=echo xxx.o',
"#MAKE#: *** No rule to make target 'xxx.o'. Stop.", 512);
# Make sure we can set it from within the makefile too
run_make_test(q!
COMPILE.c = echo
MAKEFLAGS += -r
!,
'xxx.o',
"#MAKE#: *** No rule to make target 'xxx.o'. Stop.", 512);
unlink('xxx.c');
# Simple check for -R
run_make_test(q!
all:;$(info CC='$(CC)')
!,
'-sR', "CC=''");
# Make sure we can set -R from within the makefile too
run_make_test(q!
MAKEFLAGS += -R
all:;$(info CC='$(CC)')
!,
'-s', "CC=''");
# sv 62356.
# Setting -R in MAKEFLAGS sets -r.
run_make_test(q!
MAKEFLAGS := -R
.PHONY: hello.c
all: hello.o
!, '', "#MAKE#: *** No rule to make target 'hello.o', needed by 'all'. Stop.", 512);
1;
@@ -0,0 +1,26 @@
# -*-perl-*-
$description = "Test the -s (silent) and --no-silent options.\n";
run_make_test(q!
all: one two
one: ; @echo MAKEFLAGS=$$MAKEFLAGS
two: ; echo two
!,
'', "MAKEFLAGS=\necho two\ntwo");
run_make_test(undef, '-s', "MAKEFLAGS=s\ntwo");
run_make_test(undef, '--silent', "MAKEFLAGS=s\ntwo");
run_make_test(undef, '--quiet', "MAKEFLAGS=s\ntwo");
run_make_test(undef, '--no-silent', "MAKEFLAGS=\necho two\ntwo");
run_make_test(undef, '-s --no-silent', "MAKEFLAGS=\necho two\ntwo");
run_make_test(undef, '--silent --no-silent', "MAKEFLAGS=\necho two\ntwo");
run_make_test(undef, '--quiet --no-silent', "MAKEFLAGS=\necho two\ntwo");
run_make_test(undef, '--no-silent -s', "MAKEFLAGS=s\ntwo");
run_make_test(undef, '--no-silent --silent', "MAKEFLAGS=s\ntwo");
run_make_test(undef, '--no-silent --quiet', "MAKEFLAGS=s\ntwo");
1;
@@ -0,0 +1,58 @@
# -*-perl-*-
$description = "Test the -t option.\n";
$details = "Look out for regressions of prior bugs related to -t.\n";
# That means, nobody has even tried to make the tests below comprehensive
# TEST 0
# bug reported by Henning Makholm <henning@makholm.net> on 2001-11-03:
# make 3.79.1 touches only interm-[ab] but reports final-[a] as
# 'up to date' without touching them.
# The 'obvious' fix didn't work for double-colon rules, so pay special
# attention to them.
open(MAKEFILE, "> $makefile");
print MAKEFILE <<'EOMAKE';
final-a: interm-a ; echo >> $@
final-b: interm-b ; echo >> $@
interm-a:: orig1-a ; echo >> $@
interm-a:: orig2-a ; echo >> $@
interm-b:: orig1-b ; echo >> $@
interm-b:: orig2-b ; echo >> $@
EOMAKE
close(MAKEFILE);
&utouch(-30, 'orig1-a','orig2-b');
&utouch(-20, 'interm-a','interm-b');
&utouch(-10, 'final-a','final-b');
&touch('orig2-a','orig1-b');
&run_make_with_options($makefile, "-t final-a final-b", &get_logfile);
$answer = "touch interm-a\ntouch final-a\ntouch interm-b\ntouch final-b\n";
&compare_output($answer, &get_logfile(1));
unlink('orig1-a', 'orig2-a', 'interm-a', 'final-a');
unlink('orig1-b', 'orig2-b', 'interm-b', 'final-b');
# TEST 1
# -t should not touch files with no commands.
$makefile2 = &get_tmpfile;
open(MAKEFILE, "> $makefile2");
print MAKEFILE <<'EOMAKE';
PHOOEY: xxx
xxx: ; @:
EOMAKE
close(MAKEFILE);
&run_make_with_options($makefile2, "-t", &get_logfile);
$answer = "touch xxx\n";
&compare_output($answer, &get_logfile(1));
unlink('xxx');
1;
@@ -0,0 +1,44 @@
# -*-perl-*-
$description = "Test the --eval option.";
$details = "Verify that --eval options take effect,
and are passed to sub-makes.";
# Verify that --eval is evaluated first
run_make_test(q!
$(info infile)
BAR = bar
all: ; @echo all
recurse: ; @$(MAKE) -f #MAKEFILE# && echo recurse!,
['--eval=$(info eval)', 'FOO=$(BAR)'], "eval\ninfile\nall");
# Make sure that --eval is handled correctly during recursion
run_make_test(undef, ['--no-print-directory', '--eval=$(info eval)', 'recurse'],
"eval\ninfile\neval\ninfile\nall\nrecurse");
# Make sure that --eval is not passed in MAKEFLAGS
run_make_test(q!
all: ; @echo "MAKEFLAGS=$$MAKEFLAGS"
!,
['--eval=$(info eval)'],
"eval\n".'MAKEFLAGS= --eval=$$(info\ eval)');
# Make sure that --eval is handled correctly during restarting
run_make_test(q!
all: ; @echo $@
-include gen.mk
gen.mk: ; @echo > $@
!,
['--eval=$(info eval)'], "eval\neval\nall");
unlink('gen.mk');
# Check -E
run_make_test(q!
BAR = bar
all: ; @echo all
recurse: ; @$(MAKE) -f #MAKEFILE# && echo recurse!,
['-E', '$(info eval)', 'FOO=$(BAR)'], "eval\nall");
1;
@@ -0,0 +1,30 @@
# -*-perl-*-
$description = "Test generic option processing.\n";
# TEST 0
if (!$parallel_jobs) {
$answer = "#MAKE#: Parallel jobs (-j) are not supported on this platform.\n#MAKE#: Resetting to single job (-j1) mode.\n1foo\n";
}
else {
$answer = "1foo\n";
}
run_make_test(q!
foo 1foo: ; @echo $@
!,
"-j 1foo", $answer);
# TEST 1
# This test prints the usage string; I don't really know a good way to
# test it. I guess I could invoke make with a known-bad option to see
# what the usage looks like, then compare it to what I get here... :(
# On UNIX I can invoke it with 2>/dev/null, then just check the error code.
if ($port_type ne 'W32') {
run_make_test(undef, "-j1foo 2>/dev/null", '', 512);
}
1;
@@ -0,0 +1,70 @@
# -*-perl-*-
$description = "Test the -w option to GNU make.";
my $enter = "#MAKE#: Entering directory '#PWD#'";
my $leave = "#MAKE#: Leaving directory '#PWD#'";
# Simple test without -w
run_make_test(q!
all: ; @echo hi
!,
"", "hi\n");
my $ans = "$enter\nhi\n$leave\n";
# Simple test with -w
run_make_test(undef, "-w", $ans);
# Simple test with overriding -w
run_make_test(undef, "-w --no-print-directory", "hi\n");
# Simple test with overriding --no-print-directory
run_make_test(undef, "--no-print-directory --print-directory", $ans);
# Test makefile rebuild to ensure no enter/leave
run_make_test(q!
include foo
all: ;@:
foo: ; touch foo
!,
"", "touch foo\n");
unlink('foo');
$ans = "$enter\ntouch foo\n$leave\n";
# Test makefile rebuild with -w
run_make_test(undef, "-w", $ans);
unlink('foo');
# Test makefile rebuild with -w overridden
run_make_test(undef, "-w --no-print-directory", "touch foo\n");
unlink('foo');
# Test makefile rebuild with --no-print-directory overridden
run_make_test(undef, "--no-print-directory --print-directory", $ans);
unlink('foo');
my $enter1 = "#MAKE#[1]: Entering directory '#PWD#'";
my $leave1 = "#MAKE#[1]: Leaving directory '#PWD#'";
$ans = "$enter1\nhi\n$leave1\n";
# Test makefile recursion with default enter/leave
run_make_test(q!
all: ;@$(MAKE) -f #MAKEFILE# recurse
recurse: ; @echo hi
!,
"", $ans);
# Disable enter/leave
run_make_test(undef, "--no-print-directory", "hi\n");
# Re-enable enter/leave
$ans = "$enter\n$ans$leave\n";
run_make_test(undef, "--no-print-directory -w", $ans);
# Override enter/leave
run_make_test(undef, "-w --no-print-directory", "hi\n");
1;
@@ -0,0 +1,128 @@
# -*-perl-*-
$description = "Test the --shuffle option.";
$details = "Verify that --shuffle has expected effect on target order and argument order.";
#
# Test --shuffle=random
#
# TEST 1: Fixed seed should yield the same order from run to run.
$makefile = &get_tmpfile;
open(MAKEFILE, "> $makefile");
print MAKEFILE <<'EOF';
# More target prerequisites lower collision chance in TEST 2
all: a_ b_ c_ d_ e_ f_ g_ i_ j_ k_ l_
%: ; echo $@
EOF
close(MAKEFILE);
$log1 = &get_logfile;
$log2 = &get_logfile;
&run_make_with_options($makefile, "--shuffle=12345", $log1);
&run_make_with_options($makefile, "--shuffle=12345", $log2);
&compare_output(&read_file_into_string($log1), $log2);
# TEST 2: Sequential runs should produce different orders.
$log3 = &get_logfile;
$log4 = &get_logfile;
&run_make_with_options($makefile, "--shuffle", $log3);
&run_make_with_options($makefile, "--shuffle", $log4);
++$tests_run;
if (&read_file_into_string($log3) ne &read_file_into_string($log4)) {
print "ok\n" if $debug;
++$tests_passed;
}
#
# Test --shuffle=reverse
#
run_make_test('
%: ; @echo $@
all: a b c
',
'--shuffle=reverse', "c\nb\na\nall");
run_make_test('
%: ; @echo $@
all: a b c
',
'--shuffle=none', "a\nb\nc\nall");
run_make_test('
%: ; @echo $@
all: a b c
',
'--shuffle=identity', "a\nb\nc\nall");
# Make sure prerequisites get reverse order and commands don't get affected.
run_make_test('
all: foo.o ; @echo $@
%.o : %.c ; @echo cc -c -o $@ $<
foo.o : foo.c foo.h bar.h baz.h
%.h: ; @echo $@
%.c: ; @echo $@
',
'--shuffle=reverse',
"baz.h\nbar.h\nfoo.h\nfoo.c\ncc -c -o foo.o foo.c\nall");
# Make sure pattern prerequisites get reverse order and commands don't get
# affected.
run_make_test('
all: foo_ ; @echo $@
foo%: arg%1 arg%2 arg%3 arg%4 ; @echo bld $@ $< $(word 3,$^) $(word 2,$^) $(word 4,$^)
arg%: ; @echo $@
',
'--shuffle=reverse',
"arg_4\narg_3\narg_2\narg_1\nbld foo_ arg_1 arg_3 arg_2 arg_4\nall");
# Check if make can survive circular dependency.
run_make_test('
all: a_ b_ ; @echo $@
%_: ; @echo $@
a_: b_
b_: a_
',
'--shuffle=reverse', "#MAKE#: Circular a_ <- b_ dependency dropped.\na_\nb_\nall");
# Check if order-only dependencies get reordered.
run_make_test('
all: a_ ; @echo $@
%_: ; @echo $@
a_: b_ c_ | d_ e_
',
'--shuffle=reverse', "e_\nd_\nc_\nb_\na_\nall");
# Check if goals are reordered.
run_make_test('
%_: ; @echo $@
',
'--shuffle=reverse a_ b_ c_', "c_\nb_\na_");
# .NOTPARALLEL should prevent reordering from happening.
run_make_test('
%_: ; @echo $@
# disable shuffling
.NOTPARALLEL:
',
'--shuffle=reverse a_ b_ c_', "a_\nb_\nc_");
# Check if SECONDEXPANSION targets also get reshuffled.
run_make_test('
.SECONDEXPANSION:
all: $$(var)
%_: ; @echo $@
var = a_ b_ c_
',
'--shuffle=reverse', "c_\nb_\na_");
1;
@@ -0,0 +1,62 @@
# -*-perl-*-
$description = "Test the -L option.";
$details = "Verify that symlink handling with and without -L works properly.";
# Only run these tests if the system sypports symlinks
exists $FEATURES{'check-symlink'} or return -1;
use File::Spec;
# Set up a symlink sym -> dep
# We'll make both dep and targ older than sym
&utouch(-10, 'dep');
&utouch(-5, 'targ');
$dirnm = (File::Spec->splitdir($cwddir))[-1];
symlink(File::Spec->catfile(File::Spec->updir(), $dirnm, 'dep'), 'sym');
# Without -L, nothing should happen
# With -L, it should update targ
run_make_test('targ: sym ; @echo make $@ from $<', '',
"#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
# Now update dep; in all cases targ should be out of date.
&touch('dep');
run_make_test(undef, '', "make targ from sym");
run_make_test(undef, '-L', "make targ from sym");
# Now update targ; in all cases targ should be up to date.
&touch('targ');
run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "#MAKE#: 'targ' is up to date.");
# Add in a new link between sym and dep. Be sure it's newer than targ.
sleep(1);
rename('dep', 'dep1');
symlink('dep1', 'dep');
# Without -L, nothing should happen
# With -L, it should update targ
run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
rmfiles('targ', 'dep', 'sym', 'dep1');
# Check handling when symlinks point to non-existent files. Without -L we
# should get an error: with -L we should use the timestamp of the symlink.
symlink("../$dirnm/dep", 'sym');
run_make_test('targ: sym ; @echo make $@ from $<', '',
"#MAKE#: *** No rule to make target 'sym', needed by 'targ'. Stop.", 512);
run_make_test('targ: sym ; @echo make $@ from $<', '-L',
'make targ from sym');
rmfiles('targ', 'sym');
1;

Some files were not shown because too many files have changed in this diff Show More