diff options
Diffstat (limited to 'src/kmk/tests/scripts')
142 files changed, 13302 insertions, 0 deletions
diff --git a/src/kmk/tests/scripts/features/archives b/src/kmk/tests/scripts/features/archives new file mode 100644 index 0000000..a064dd4 --- /dev/null +++ b/src/kmk/tests/scripts/features/archives @@ -0,0 +1,213 @@ +# -*-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; + +# Create some .o files to work with +if ($osname eq 'VMS') { + use Cwd; + my $pwd = getcwd; + # 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)); +} + +my $ar = $CONFIG_FLAGS{AR}; + +# Fallback if configure did not find AR, such as VMS +# which does not run configure. +$ar = 'ar' if $ar eq ''; + +my $redir = '2>&1'; +$redir = '' if $osname eq 'VMS'; + +my $arflags = '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 U$arflags libxx.a a1.o $redir`; +if ($? == 0) { + $arflags = 'Urv'; + $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`; + +# 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 +my $answer = "$ar $arflags libxx.a a1.o\n$created"; +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("$pwd/artest"); +} else { + remove_directory_tree('artest'); +} + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/comments b/src/kmk/tests/scripts/features/comments new file mode 100644 index 0000000..9257955 --- /dev/null +++ b/src/kmk/tests/scripts/features/comments @@ -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)) diff --git a/src/kmk/tests/scripts/features/conditionals b/src/kmk/tests/scripts/features/conditionals new file mode 100644 index 0000000..78344b9 --- /dev/null +++ b/src/kmk/tests/scripts/features/conditionals @@ -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: diff --git a/src/kmk/tests/scripts/features/default_names b/src/kmk/tests/scripts/features/default_names new file mode 100644 index 0000000..2e83880 --- /dev/null +++ b/src/kmk/tests/scripts/features/default_names @@ -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/WIN32/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; diff --git a/src/kmk/tests/scripts/features/double_colon b/src/kmk/tests/scripts/features/double_colon new file mode 100644 index 0000000..58f126f --- /dev/null +++ b/src/kmk/tests/scripts/features/double_colon @@ -0,0 +1,220 @@ +# -*-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."; + +# The Contents of the MAKEFILE ... + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +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 + +EOF + +close(MAKEFILE); + +# TEST 0: A simple double-colon rule that isn't the goal target. + +&run_make_with_options($makefile, "all", &get_logfile, 0); +$answer = "aaa\nbbb\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 1: As above, in parallel + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 all", &get_logfile, 0); + $answer = "aaa\nbbb\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 2: A simple double-colon rule that is the goal target + +&run_make_with_options($makefile, "bar", &get_logfile, 0); +$answer = "aaa\naaa done\nbbb\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 3: As above, in parallel + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 bar", &get_logfile, 0); + $answer = "aaa\naaa done\nbbb\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 4: Each double-colon rule is supposed to be run individually + +&utouch(-5, 'f2.h'); +&touch('foo'); + +&run_make_with_options($makefile, "foo", &get_logfile, 0); +$answer = "f1.h\nfoo FIRST\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 5: Again, in parallel. + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 foo", &get_logfile, 0); + $answer = "f1.h\nfoo FIRST\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 6: Each double-colon rule is supposed to be run individually + +&utouch(-5, 'f1.h'); +unlink('f2.h'); +&touch('foo'); + +&run_make_with_options($makefile, "foo", &get_logfile, 0); +$answer = "f2.h\nfoo SECOND\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 7: Again, in parallel. + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 foo", &get_logfile, 0); + $answer = "f2.h\nfoo SECOND\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 8: Test circular dependency check; PR/1671 + +&run_make_with_options($makefile, "d", &get_logfile, 0); +$answer = "ok\n$make_name: Circular d <- d dependency dropped.\noops\n"; +&compare_output($answer, &get_logfile(1)); + +# 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_with_options($makefile, "-j10 biz", &get_logfile, 0); +# $answer = "aaa\ntwo\nbbb\n"; +# &compare_output($answer, &get_logfile(1)); +#} + +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(' +.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('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'); + +# 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: diff --git a/src/kmk/tests/scripts/features/echoing b/src/kmk/tests/scripts/features/echoing new file mode 100644 index 0000000..40debf5 --- /dev/null +++ b/src/kmk/tests/scripts/features/echoing @@ -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\@$delete_command $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', "$delete_command $example\n"); + + +# TEST #4 +# ------- + +run_make_test(undef, '-s', "This makefile did not clean the dir... good\n"); + + +1; diff --git a/src/kmk/tests/scripts/features/errors b/src/kmk/tests/scripts/features/errors new file mode 100644 index 0000000..ebd4383 --- /dev/null +++ b/src/kmk/tests/scripts/features/errors @@ -0,0 +1,107 @@ +# -*-perl-*- + +$description = "The following tests the -i option and the '-' in front of \n" + ."commands to test that make ignores errors in these commands\n" + ."and continues processing."; + +$details = "This test runs two makes. The first runs on a target with a \n" + ."command that has a '-' in front of it (and a command that is \n" + ."intended to fail) and then a delete command after that is \n" + ."intended to succeed. If make ignores the failure of the first\n" + ."command as it is supposed to, then the second command should \n" + ."delete a file and this is what we check for. The second make\n" + ."that is run in this test is identical except that the make \n" + ."command is given with the -i option instead of the '-' in \n" + ."front of the command. They should run the same. "; + +if ($vos) +{ + $rm_command = "delete_file"; +} +else +{ + $rm_command = "rm"; +} + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "clean:\n" + ."\t-$rm_command cleanit\n" + ."\t$rm_command foo\n" + ."clean2: \n" + ."\t$rm_command cleanit\n" + ."\t$rm_command foo\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("foo"); + +unlink("cleanit"); +$cleanit_error = `sh -c "$rm_command cleanit 2>&1"`; +chomp $cleanit_error; +$delete_error_code = $? >> 8; + +# TEST #1 +# ------- + +$answer = "$rm_command cleanit +$cleanit_error +$make_name: [$makefile:2: clean] Error $delete_error_code (ignored) +$rm_command foo\n"; + +&run_make_with_options($makefile,"",&get_logfile); + +# If make acted as planned, it should ignore the error from the first +# command in the target and execute the second which deletes the file "foo" +# This file, therefore, should not exist if the test PASSES. +if (-f "foo") { + $test_passed = 0; +} + +# The output for this on VOS is too hard to replicate, so we only check it +# on unix. +if (!$vos) +{ + &compare_output($answer,&get_logfile(1)); +} + + +&touch("foo"); + +# TEST #2 +# ------- + +$answer = "$rm_command cleanit +$cleanit_error +$make_name: [$makefile:5: clean2] Error $delete_error_code (ignored) +$rm_command foo\n"; + +&run_make_with_options($makefile,"clean2 -i",&get_logfile); + +if (-f "foo") { + $test_passed = 0; +} + +if (!$vos) { + &compare_output($answer,&get_logfile(1)); +} + +# Test that error line offset works + +run_make_test(q! +all: + @echo hi + @echo there + @exit 1 +!, + '', "hi\nthere\n#MAKE#: *** [#MAKEFILE#:5: all] Error 1", 512); + +1; + +### Local Variables: +### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) +### End: diff --git a/src/kmk/tests/scripts/features/escape b/src/kmk/tests/scripts/features/escape new file mode 100644 index 0000000..5fcb023 --- /dev/null +++ b/src/kmk/tests/scripts/features/escape @@ -0,0 +1,74 @@ +# -*-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(' +$(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, + 'path=pre:', + "#MAKEFILE#:2: *** target pattern contains no '%' (target 'foo'). Stop.", + 512); + +# TEST 3: This one should work, since we escape the ":". + +run_make_test(undef, + "'path=pre\\:'", + 'touch (pre:foo)'); + +# TEST 4: This one should fail, since the escape char is escaped. + +run_make_test(undef, + "'path=pre\\\\:'", + "#MAKEFILE#:2: *** target pattern contains no '%' (target 'foo'). 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"); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/export b/src/kmk/tests/scripts/features/export new file mode 100644 index 0000000..81bff0c --- /dev/null +++ b/src/kmk/tests/scripts/features/export @@ -0,0 +1,186 @@ +# -*-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 + +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 + +$extraENV{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 + +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 + +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 + +@extraENV{qw(A B C D E F G H I J)} = qw(1 2 3 4 5 6 7 8 9 10); + +&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 9: Check "export" as a target + +&run_make_test(' +a: export +export: ; @echo "$@" +', + '', "export\n"); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/ifcond b/src/kmk/tests/scripts/features/ifcond new file mode 100644 index 0000000..b492e77 --- /dev/null +++ b/src/kmk/tests/scripts/features/ifcond @@ -0,0 +1,950 @@ +# $Id: ifcond 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# if conditionals. +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the if conditionals"; + +$details = "..."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(if-expr 1+1,1,0),1) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - A more comprehensive, yet a bit large, test. + # ------------------------------------------------------ + run_make_test(' + +# +# Note! The testcase are ordered by ascending operator precedence +# with the exception of equal and not-equal because these +# are kind of useful for performing tests on non-logical ops. +# + +.PHONY: all +all: ; @: + +# +# Parenthesis +# +$(info unary operators: ( and )) +if (1) +else +$(error ) +endif + +if ((((1)))) +else +$(error ) +endif + + +# +# Equal and Not Equal w/ some fundamental bits thrown in. +# +$(info binary operators: == and !=) + +if 1 == 1 +else +$(error ) +endif + +if 2 == 3 +$(error ) +else +endif + +if 2 != 3 +else +$(error ) +endif + +if a != b +else +$(error ) +endif + +if asdf == asdf +else +$(error ) +endif + +if "asdf" == asdf +else +$(error ) +endif + +if \'asdf\' == asdf +else +$(error ) +endif + +if \'asdf\' == "asdf" +else +$(error ) +endif + +if \'asdf\' == \'asdf\' +else +$(error ) +endif + +if "asdf" == "asdf" +else +$(error ) +endif + +if 0x1 == 1 +else +$(error ) +endif + +if 0xfff == 4095 +else +$(error ) +endif + +if 0xfff == 4095 +else +$(error ) +endif + +if 0d10 == 10 +else +$(error ) +endif + +if 0d10 == 10 +else +$(error ) +endif + +if 0xa == 012 +else +$(error ) +endif + +if 0b1110 == 016 +else +$(error ) +endif + + +# +# Logical OR +# +$(info binary operator: ||) +if 1 +else +$(error busted) +endif + +if 1 || 1 +else +$(error ) +endif + +if 0 || 0 +$(error ) +else +endif + +if 1 || 0 +else +$(error ) +endif + +if 0 || 1 +else +$(error ) +endif + +if 0 || 0 || 0 || 0 || 0 || 0 || 0 +$(error ) +else +endif + +if 0 || 0 || 0 || 1 || 0 || 0 || 0 +else +$(error ) +endif + +if "asdf" || 0 +else +$(error ) +endif + +if 0 || "asdf" +else +$(error ) +endif + +if \'asdf\' || 0 +else +$(error ) +endif + +if "" || 0 +$(error ) +endif +if "" || 1 +else +$(error ) +endif +if \'\' || 0 +$(error ) +endif +if \'\' || 1 +else +$(error ) +endif + +if "" || \'\' +$(error ) +endif +if "1" || \'\' +else +$(error ) +endif +if "1" || \'1\' +else +$(error ) +endif +if "" || \'1\' +else +$(error ) +endif + + +# +# Logical AND +# +$(info binary operator: &&) +if 1 && 1 +else +$(error ) +endif +if 1 && 0 +$(error ) +endif +if 1234 && 0 +$(error ) +endif +if 123434 && 0 && 123435 && 1 +$(error ) +endif + +if "" && 1 +$(error ) +endif +if ("asdf" && 1) != 1 +$(error ) +endif +if "1" && \'asdf\' +else +$(error ) +endif +if "1" && \'asdf\' && 0 +$(error ) +endif + +if 0 || 1 && 0 +$(error ) +endif + + +# +# Bitwise OR +# +$(info binary operator: |) +if 1 | 0 +else +$(error ) +endif +if 1 | 1 +else +$(error ) +endif +if 11234 | 343423 +else +$(error ) +endif +if (1|2)!=3 +$(error ) +endif +if 1|2 != 3 +else +$(error ) +endif +if (1|2|4|8)!=0xf +$(error ) +endif + + +# +# Bitwise XOR +# +$(info binary operator: ^) +if 1 ^ 1 +$(error ) +endif + +if (2 ^ 1) != 3 +$(error ) +endif + +if 7 != (2 ^ 1 ^ 4) +$(error ) +endif + +if (2 ^ 1 | 2) != 3 +$(error ) +endif + + +# +# Bitwise AND +# +$(info binary operator: &) +if (4097 & 1) != 1 +$(error ) +endif +if (0xfff & 0x0f0) != 0xf0 +$(error ) +endif +if (0x1e3 & 0x100 | 3) != 0x103 +$(error ) +endif + + +# +# Greater than +# +$(info binary operator: >) +if 1 > 0 +else +$(error ) +endif + +if 1024 > 1023 +else +$(error ) +endif + +if 999 > 1023 +$(error ) +endif + +if (5 > 4 | 2) != 3 +$(error ) +endif + +if (1 & 8 > 4) != 1 +$(error ) +endif + +if (8 > 4 ^ 16) != 17 +$(error ) +endif + +if "b" > \'a\' +else +$(error ) +endif +if "abcdef" > \'ffdas\' +$(error ) +endif +if abcdef > ffdas +$(error ) +endif + + +# +# Greater or equal than +# +$(info binary operator: >=) +if 20 > 0 +else +$(error ) +endif + +if 20 >= 20 +else +$(error ) +endif + +if 19 >= 20 +$(error ) +endif + +if (1 & 8 >= 4) != 1 +$(error ) +endif + +if "x" >= \'x\' +else +$(error ) +endif +if "abdc" >= \'abcd\' +else +$(error ) +endif +if "ffdaaa" >= \'ffdasd\' +$(error ) +endif +if asdf >= asdf +else +$(error ) +endif + + +# +# Less than +# +if 1 < 1 +$(error ) +endif +if -123 < -134 +$(error ) +endif +if 123 <= 7777 +else +$(error ) +endif + +if "b" < \'a\' +$(error ) +endif +if b < a +$(error ) +endif +if \'foobar\' < \'a$\' +$(error ) +endif +if hhhh < ggggg +$(error ) +endif +if qwerty < qwerty0 +else +$(error ) +endif + + +# +# Less or equal than +# +$(info binary operator: >>) +if 1 <= 0 +$(error ) +endif +if 1 <= 1 +else +$(error ) +endif +if 123 <= 123 != 1 +$(error ) +endif +if 560 <= 456 +$(error ) +endif + +if "a" <= \'a\' +else +$(error ) +endif +if "abcdef" <= \'abcdef\' +else +$(error ) +endif +if q12345z6 <= q12345z +$(error ) +endif +if QWERTY <= ABCDE +$(error ) +endif + + +# +# Shift right +# +$(info binary operator: >>) +if 1 >> 0 != 1 +$(error ) +endif +if 1024 >> 2 != 256 +$(error ) +endif +if 102435 >> 4 > 1234 != 1 +$(error ) +endif + + +# +# Shift left +# +$(info binary operator: <<) +if 1 << 0 != 1 +$(error ) +endif +if 1 << 1 != 2 +$(error ) +endif +if 1 << 4 != 16 +$(error ) +endif +if 1 << 10 != 1024 +$(error ) +endif +if 34 << 10 != 0x8800 +$(error ) +endif +if 1099511627776 << 21 != 2305843009213693952 +$(error ) +endif +if 1 << 61 != 2305843009213693952 +$(error ) +endif + +if 2 << 60 > 123434323 != 1 +$(error ) +endif + + +# +# Subtraction +# +$(info binary operator: -) +if 1-1 != 0 +$(error ) +endif +if 1023-511 != 512 +$(error ) +endif +if 4 - 3 << 3 != 8 +$(error ) +endif + + +# +# Addition +# +$(info binary operator: +) +if 1+1 != 2 +$(error ) +endif +if 1234+1000 != 2234 +$(error ) +endif +if 2 + 2 << 4 != 64 +$(error ) +endif + + +# +# Modulus +# +$(info binary operator: %) +if 0%2 != 0 +$(error ) +endif +if 10%7 != 3 +$(error ) +endif +if 10 + 100%70 - 3 != 37 +$(error ) +endif + + +# +# Division +# +$(info binary operator: /) +if 0/1 != 0 +$(error ) +endif +if 1000/2 != 500 +$(error ) +endif +if 1000/2 + 4 != 504 +$(error ) +endif +if 5 + 1000/4 != 255 +$(error ) +endif + + +# +# Multiplication +# +$(info binary operator: *) +if 1*1 != 1 +$(error ) +endif +if 10*10 != 100 +$(error ) +endif +if 1024*64 != 65536 +$(error ) +endif +if 10*10 - 10 != 90 +$(error ) +endif +if 1000 - 10*10 != 900 +$(error ) +endif + + +# +# Logical NOT +# +$(info unary operator: !) +if !1 +$(error ) +endif + +if !42 == 0 +else +$(error ) +endif + +if !0 == 1 +else +$(error ) +endif + +if !!0 == 0 +else +$(error ) +endif + +if !0 * 123 != 123 +$(error ) +endif +if !!!0 * 512 != 512 +$(error ) +endif + + +# +# Bitwise NOT +# +$(info unary operator: ~) +if ~0xfff != 0xfffffffffffff000 +$(error ) +endif + + +# +# Pluss +# +$(info unary operator: +) +if +2 != 2 +$(error ) +endif +if 1++++++++++++2134 != 2135 +$(error ) +endif + + +# +# Minus (negation) +# +$(info unary operator: -) +if --2 != 2 +$(error ) +endif + +if 1 - -2 != 3 +$(error ) +endif + + +# +# target +# +trg_deps_only: foobar +trg_with_cmds: foobar + echo $@ + +$(info unary operator: target) # This flushes stuff in read.c + +if target trg_with_cmds +else +$(error target trg_with_cmds) +endif +if target(trg_deps_only) +$(error target trg_deps_only) +endif +if target ( foobar ) +$(error target foobar) +endif + + +# +# defined +# +$(info unary operator: defined) +var_defined := 1 +var_not_defined := + +if defined var_defined +else +$(error ) +endif +if defined(var_defined) +else +$(error ) +endif +if defined (var_defined) +else +$(error ) +endif +if !defined(var_defined) +$(error ) +endif +if defined (var_not_defined) +$(error ) +endif + + +# +# bool +# +$(info unary operator: bool) +if bool("Asdf") != 1 +$(error ) +endif +if bool("") != 0 +$(error ) +endif + + +# +# bool +# +$(info unary operator: num) +if num("1234") != 1235 - 1 +$(error ) +endif +if num(\'1234\') != 1233 + 1 +$(error ) +endif + + +# +# str +# +$(info unary operator: str) +if str(a < b) != 1 +$(error ) +endif +if str(a < b) != \'1\' +$(error ) +endif +if str( 1 ) != "1" +$(error ) +endif +if str( 1 ) != "1" +$(error ) +endif +if str( num(0x1000) ) != "4096" +$(error ) +endif +if str(0x1000) != 0x1000 +$(error ) +endif + + + +# +# Quick check of $(if-expr ) and $(expr ). +# +$(info $$(if-expr ,,)) +ifeq ($(if-expr 0 || 2,42,500),42) +else +$(error ) +endif +ifeq ($(if-expr 5+3 == 231,42,500),42) +$(error ) +endif + +$(info $$(expr )) +ifeq ($(expr 5+3),8) +else +$(error expr:$(expr 5+3) expected 8) +endif +ifeq ($(expr 25*25),625) +else +$(error expr:$(expr 25*25) expected 625) +endif +ifeq ($(expr 100/3),3) +$(error ) +endif +', +'', +'unary operators: ( and ) +binary operators: == and != +binary operator: || +binary operator: && +binary operator: | +binary operator: ^ +binary operator: & +binary operator: > +binary operator: >= +binary operator: >> +binary operator: >> +binary operator: << +binary operator: - +binary operator: + +binary operator: % +binary operator: / +binary operator: * +unary operator: ! +unary operator: ~ +unary operator: + +unary operator: - +unary operator: target +unary operator: defined +unary operator: bool +unary operator: num +unary operator: str +$(if-expr ,,) +$(expr ) +'); + +} + + + # TEST #2 - A bug. + # ------------------------------------------------------ + run_make_test(' +.PHONY: all +all: ; @: + +# +# Assert sanity first on simple strings. +# +if abcd != "abcd" +$(error ) +endif + +if \'abcd\' != abcd +$(error ) +endif + +if abcd != abcd +$(error ) +endif + + +# +# String by reference, start with a few simple cases. +# +STR1 = abcd + +if "$(STR1)" != "abcd" +$(error ) +endif + +if \'$(STR1)\' == "abcd" # not expanded. +$(error ) +endif + +if \'$(STR1)\' != \'$(STR1)\' +$(error ) +endif + +if "$(STR1)" != "$(STR1)" +$(error ) +endif + +# +# Now for the kmk 0.1.4 bug... +# +if $(STR1) != "$(STR1)" +$(error ) +endif + +if "$(STR1)" != $(STR1) +$(error ) +endif + +if $(STR1) != $(STR1) +$(error ) +endif + +# +# And some extra for good measure. +# +STR2 = STR +NUM1 = 1 + +if $($(STR2)$(NUM1)) != "abcd" +$(error ) +endif + +if "abcd" != $($(STR2)$(NUM1)) +$(error ) +endif + +if "abcd" != $(${STR2}$(NUM1)) +$(error ) +endif + +if "abcd" != ${$(STR2)$(NUM1)} +$(error ) +endif + +if "abcd" != ${${STR2}${NUM1}} +$(error ) +endif + +if ${${STR2}${NUM1}} != \'abcd\' +$(error ) +endif + +if "${${STR2}${NUM1}}" != \'abcd\' +$(error ) +endif + + +', +'', +''); + + + +# Indicate that we're done. +1; + + diff --git a/src/kmk/tests/scripts/features/include b/src/kmk/tests/scripts/features/include new file mode 100644 index 0000000..f78563f --- /dev/null +++ b/src/kmk/tests/scripts/features/include @@ -0,0 +1,243 @@ +# -*-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."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The contents of the Makefile ... + +print MAKEFILE <<EOF; +\#Extra space at the end of the following file name +include $makefile2 +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 +EOF + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE "ANOTHER: ; \@echo This is another included makefile\n"; + +close(MAKEFILE); + +# Create the answer to what should be produced by this Makefile +&run_make_with_options($makefile, "all", &get_logfile); +$answer = "There should be no errors for this makefile.\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile, "ANOTHER", &get_logfile); +$answer = "This is another included makefile\n"; +&compare_output($answer, &get_logfile(1)); + +$makefile = undef; + +# 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 + ); + +# 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 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: No such file or directory +#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 > inc2\necho > inc1\nDONE\n"); + +rmfiles('inc1', 'inc2'); + +# 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 +!, + '', "#MAKEFILE#:7: inc2: No such file or directory\n#MAKE#: *** No rule to make target 'inc2'. Stop.\n", 512); + +rmfiles('inc1'); + +# Include same file multiple times + +run_make_test(q! +default:; @echo DEFAULT +include inc1 +inc1:; echo > $@ +include inc1 +!, + '', "echo > inc1\nDEFAULT\n"); + +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: No such file or directory\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: No such file or directory\n#MAKE#: *** No rule to make target 'foo', needed by 'inc1'. Stop.\n", 512); + +rmfiles('inc1'); + +# include a directory + +if ($all_tests) { + # Test that include of a rebuild-able file doesn't show a warning + # Savannah bug #102 + run_make_test(q! +include foo +foo: ; @echo foo = bar > $@ +!, + '', "#MAKE#: 'foo' is up to date.\n"); + rmfiles('foo'); +} + +1; diff --git a/src/kmk/tests/scripts/features/jobserver b/src/kmk/tests/scripts/features/jobserver new file mode 100644 index 0000000..7da4a65 --- /dev/null +++ b/src/kmk/tests/scripts/features/jobserver @@ -0,0 +1,107 @@ +# -*-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 +$extraENV{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"); +delete $extraENV{MAKEFLAGS}; + +# Test override of -jN +$extraENV{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: -jN forced in submake: disabling jobserver mode.\nrecurse2: /-j3 --jobserver-auth=<auth> $np/\nall: /-j3 --jobserver-auth=<auth> $np/\n"); +delete $extraENV{MAKEFLAGS}; + +# 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: -jN forced in submake: disabling 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! +-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: -jN forced in submake: disabling jobserver mode.\nall\n"); + +unlink('inc.mk'); + +# Test recursion when make doesn't think it exists. +# See Savannah bug #39934 +# Or Red Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=885474 + +open(MAKEFILE,"> Makefile2"); +print MAKEFILE ' +vpath %.c ../ +foo: +'; +close(MAKEFILE); + +run_make_test(q! +default: ; @ #MAKEPATH# -f Makefile2 +!, + "-j2 $np", +"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule. +#MAKE#[1]: Nothing to be done for 'foo'."); + +rmfiles('Makefile2'); + +1; + +### Local Variables: +### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) +### End: diff --git a/src/kmk/tests/scripts/features/load b/src/kmk/tests/scripts/features/load new file mode 100644 index 0000000..2e9318d --- /dev/null +++ b/src/kmk/tests/scripts/features/load @@ -0,0 +1,110 @@ +# -*-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; + +# 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 <string.h> +#include <stdio.h> + +#include "gnumake.h" + +int plugin_is_GPL_compatible; + +int +testload_gmk_setup (gmk_floc *pos) +{ + (void)pos; + gmk_eval ("TESTLOAD = implicit", 0); + return 1; +} + +int +explicit_setup (gmk_floc *pos) +{ + (void)pos; + gmk_eval ("TESTLOAD = explicit", 0); + return 1; +} +EOF +close($F) or die "close: testload.c: $!\n"; + +# Make sure we can compile +# CONFIG_FLAGS are loaded from config-flags.pm and set by configure + +my $sobuild = "$CONFIG_FLAGS{CC} ".($srcdir? "-I$srcdir":'')." $CONFIG_FLAGS{CPPFLAGS} $CONFIG_FLAGS{CFLAGS} -shared -fPIC $CONFIG_FLAGS{LDFLAGS} -o testload.so testload.c"; + +my $clog = `$sobuild 2>&1`; +if ($? != 0) { + $verbose and print "Failed to build testload.so:\n$sobuild\n$_"; + 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 4 +# 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 5 +# 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"); + +unlink(qw(testload.c testload.so)) unless $keep; + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/loadapi b/src/kmk/tests/scripts/features/loadapi new file mode 100644 index 0000000..8c824c0 --- /dev/null +++ b/src/kmk/tests/scripts/features/loadapi @@ -0,0 +1,116 @@ +# -*-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; + +# 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" + +int plugin_is_GPL_compatible; + +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 () +{ + 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); + return 1; +} +EOF +close($F) or die "close: testapi.c: $!\n"; + +my $sobuild = "$CONFIG_FLAGS{CC} ".($srcdir? "-I$srcdir":'')." $CONFIG_FLAGS{CPPFLAGS} $CONFIG_FLAGS{CFLAGS} -shared -fPIC $CONFIG_FLAGS{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"); + +unlink(qw(testapi.c testapi.so)) unless $keep; + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/mult_rules b/src/kmk/tests/scripts/features/mult_rules new file mode 100644 index 0000000..e706e17 --- /dev/null +++ b/src/kmk/tests/scripts/features/mult_rules @@ -0,0 +1,78 @@ +$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"); + +1; + + + + + + diff --git a/src/kmk/tests/scripts/features/mult_targets b/src/kmk/tests/scripts/features/mult_targets new file mode 100644 index 0000000..c8ff418 --- /dev/null +++ b/src/kmk/tests/scripts/features/mult_targets @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/features/order_only b/src/kmk/tests/scripts/features/order_only new file mode 100644 index 0000000..4ebdc2b --- /dev/null +++ b/src/kmk/tests/scripts/features/order_only @@ -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; diff --git a/src/kmk/tests/scripts/features/output-sync b/src/kmk/tests/scripts/features/output-sync new file mode 100644 index 0000000..7237e65 --- /dev/null +++ b/src/kmk/tests/scripts/features/output-sync @@ -0,0 +1,349 @@ +# -*-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; + + +if ($vos) { + $sleep_command = "sleep -seconds"; +} +else { + $sleep_command = "sleep"; +} + +# 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 "while [ ! -f ../mksync.$_[0] ]; do :; done; rm -f ../mksync.$_[0].wait; $sleep_command 1"; +} +sub output_sync_set { + return "date > ../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. +unlink(@syncfiles); +run_make_test(qq! +all: make-foo make-bar + +make-foo: ; \$(MAKE) -C foo + +make-bar: ; \$(MAKE) -C bar!, + '-j -Orecurse', +"#MAKEPATH# -C foo +#MAKE#[1]: Entering directory '#PWD#/foo' +foo: start +foo: end +#MAKE#[1]: Leaving directory '#PWD#/foo' +#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: ; $sleep_command 1 ; \$(MAKE) -C bar!, + '-j --output-sync=target', +"#MAKEPATH# -C foo +$sleep_command 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 +$sleep_command 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: ; $sleep_command 1 ; \$(MAKE) -C bar bar!, + '-j -O', +"#MAKEPATH# -C foo foo-fail +$sleep_command 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: ; $sleep_command 1 ; \$(MAKE) -C bar bar-job!, + '-j --output-sync=line', +"#MAKEPATH# -C foo foo-job +$sleep_command 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 +# Is "127" not always the same everywhere? We may have to detect it? + +run_make_test(q! +all:: ; @./foo bar baz +!, + '-O', "#MAKE#: ./foo: Command not found\n#MAKE#: *** [#MAKEFILE#:2: all] Error 127\n", 512); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/override b/src/kmk/tests/scripts/features/override new file mode 100644 index 0000000..fff6c4e --- /dev/null +++ b/src/kmk/tests/scripts/features/override @@ -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; diff --git a/src/kmk/tests/scripts/features/parallelism b/src/kmk/tests/scripts/features/parallelism new file mode 100644 index 0000000..ee3846d --- /dev/null +++ b/src/kmk/tests/scripts/features/parallelism @@ -0,0 +1,231 @@ +# -*-perl-*- + +$description = "Test parallelism (-j) option."; + + +$details = "This test creates a makefile with two double-colon default +rules. The first rule has a series of sleep and echo commands +intended to run in series. The second and third have just an +echo statement. When make is called in this test, it is given +the -j option with a value of 4. This tells make that it may +start up to four jobs simultaneously. In this case, since the +first command is a sleep command, the output of the second +and third commands will appear before the first if indeed +make is running all of these commands in parallel."; + +if (!$parallel_jobs) { + return -1; +} + +if ($vos) { + $sleep_command = "sleep -seconds"; +} +else { + $sleep_command = "sleep"; +} + + +run_make_test(" +all : def_1 def_2 def_3 +def_1 : ; \@echo ONE; $sleep_command 3 ; echo TWO +def_2 : ; \@$sleep_command 2 ; echo THREE +def_3 : ; \@$sleep_command 1 ; echo FOUR", + '-j4', "ONE\nFOUR\nTHREE\nTWO"); + +# 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(" +all: 1 2; \@echo success +-include 1.inc 2.inc +1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@ +2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@", + "-j4", + "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7); + +rmfiles(qw(1.inc 2.inc)); + + +# Test parallelism with included files--this time recurse first and make +# sure the jobserver works. +run_make_test(" +recurse: ; \@\$(MAKE) --no-print-directory -f #MAKEFILE# INC=yes all +all: 1 2; \@echo success + +INC = no +ifeq (\$(INC),yes) +-include 1.inc 2.inc +endif + +1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@ +2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@", + "-j4", + "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7); + +rmfiles(qw(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. +# We have to increase the timeout from the default (5s) on this test. + +run_make_test(" +export HI = \$(shell \$(\$\@.CMD)) +first.CMD = echo hi +second.CMD = $sleep_command 4; echo hi + +.PHONY: all first second +all: first second + +first second: ; \@echo \$\@; $sleep_command 1; echo \$\@", + '-j2', "first\nfirst\nsecond\nsecond", 0, 7); + +# 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(" +.PHONY: all fail.1 fail.2 fail.3 ok +all: fail.1 ok fail.2 fail.3 + +fail.1 fail.2 fail.3: + \@$sleep_command \$(patsubst fail.%,%,\$\@) + \@echo Fail + \@exit 1 + +ok: + \@$sleep_command 4 + \@echo Ok done", + '-rR -j5', (!$is_kmk) ? "Fail +#MAKE#: *** [#MAKEFILE#:8: fail.1] Error 1 +#MAKE#: *** Waiting for unfinished jobs.... +Fail +#MAKE#: *** [#MAKEFILE#:8: fail.2] Error 1 +Fail +#MAKE#: *** [#MAKEFILE#:8: fail.3] Error 1 +Ok done" : 'Fail +#MAKE#: *** [fail.1] Error 1 +The failing command: +@exit 1 +#MAKE#: *** Waiting for unfinished jobs.... +Fail +#MAKE#: *** [fail.2] Error 1 +The failing command: +@exit 1 +Fail +#MAKE#: *** [fail.3] Error 1 +The failing command: +@exit 1 +Ok done +#MAKE#: *** Exiting with status 2', + 512); + + +# Test for Savannah bug #15641. +# +run_make_test(' +.PHONY: all +all:; @: + +-include foo.d + +foo.d: comp + @echo building $@ + +comp: mod_a.o mod_b.o; @: + +mod_a.o mod_b.o: + @exit 1 +', '-j2', ''); + + +# 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 ; touch $@ + +.INTERMEDIATE: intermed +intermed: | phony ; touch $@ + +.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 + +$extraENV{MAKEFLAGS} = '-j4'; + +run_make_test(q! +things = thing1 thing2 +all: $(things) +thing1:; @sleep 1; echo '$@ start'; sleep 2; echo '$@ end' +thing2:; @echo '$@ start'; sleep 2; echo '$@ end' +-include inc.mk +inc.mk: ; @touch $@ +!, + '', "thing2 start\nthing1 start\nthing2 end\nthing1 end\n"); + +delete $extraENV{MAKEFLAGS}; +rmfiles('inc.mk'); + +# 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'); + +# 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; + +### Local Variables: +### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) +### End: diff --git a/src/kmk/tests/scripts/features/patspecific_vars b/src/kmk/tests/scripts/features/patspecific_vars new file mode 100644 index 0000000..bbeda64 --- /dev/null +++ b/src/kmk/tests/scripts/features/patspecific_vars @@ -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, "-j1", &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, "-j1 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, "-j1 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, "-j1 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 +', '-j1', '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 +', +'-j1', +'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 +'-j1 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; diff --git a/src/kmk/tests/scripts/features/patternrules b/src/kmk/tests/scripts/features/patternrules new file mode 100644 index 0000000..9aa4f62 --- /dev/null +++ b/src/kmk/tests/scripts/features/patternrules @@ -0,0 +1,232 @@ +# -*-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 + +# 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: +!, '', ''); + +# 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 +foo.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 +touch $dir/foo.c +$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", +(!$is_kmk) ? +"#MAKE#: *** [#MAKEFILE#:6: $dir/foo.bar] Error 1": +"#MAKE#: *** [$dir/foo.bar] Error 1" . ' +The failing command: + @touch $@ && exit 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 $@ + +', +'-j1', +'touch foo.in +touch foo.h +touch foo.c +echo foo.c foo.h >foo.o'); + +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(q! +BIN = xyz +COPY = $(BIN).cp +SRC = $(BIN).c +allbroken: $(COPY) $(BIN) ; @echo ok +$(SRC): ; @echo 'main(){}' > $@ +%.cp: % ; @cp $< $@ +% : %.c ; @cp $< $@ +clean: ; @rm -rf $(SRC) $(COPY) $(BIN) +!, + '', "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"); + +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: diff --git a/src/kmk/tests/scripts/features/quoting b/src/kmk/tests/scripts/features/quoting new file mode 100644 index 0000000..916681c --- /dev/null +++ b/src/kmk/tests/scripts/features/quoting @@ -0,0 +1,32 @@ +# -*-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'; +SHELL = /bin/sh +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; diff --git a/src/kmk/tests/scripts/features/recursion b/src/kmk/tests/scripts/features/recursion new file mode 100644 index 0000000..862b6c4 --- /dev/null +++ b/src/kmk/tests/scripts/features/recursion @@ -0,0 +1,55 @@ +# -*-perl-*- +$description = "Test recursion."; + +$details = "DETAILS"; + +# Test some basic recursion. +run_make_test(' +all: + $(MAKE) -f #MAKEFILE# foo +foo: + @echo $(MAKE) + @echo MAKELEVEL = $('. (!$is_kmk ? 'MAKELEVEL' : 'KMK_LEVEL') .') + $(MAKE) -f #MAKEFILE# last +last: + @echo $(MAKE) + @echo MAKELEVEL = $('. (!$is_kmk ? 'MAKELEVEL' : 'KMK_LEVEL') .') + @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 = $('. (!$is_kmk ? 'MAKEOVERRIDES' : 'KMK_OVERRIDES') .')" +', + 'a=ZZ', + 'MAKEOVERRIDES = a=ZZ +MAKEOVERRIDES = a=AA +'); + +1; diff --git a/src/kmk/tests/scripts/features/reinvoke b/src/kmk/tests/scripts/features/reinvoke new file mode 100644 index 0000000..eb1a349 --- /dev/null +++ b/src/kmk/tests/scripts/features/reinvoke @@ -0,0 +1,80 @@ +# -*-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(' +SHELL = /bin/sh + +all: ; @echo hello + +a : b ; echo >> $@ + +b : c ; [ -f $@ ] || echo >> $@ + +c: ; echo >> $@ + +include $(F)', + 'F=a', "[ -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', "[ -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'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/rule_glob b/src/kmk/tests/scripts/features/rule_glob new file mode 100644 index 0000000..2d377e7 --- /dev/null +++ b/src/kmk/tests/scripts/features/rule_glob @@ -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; diff --git a/src/kmk/tests/scripts/features/se_explicit b/src/kmk/tests/scripts/features/se_explicit new file mode 100644 index 0000000..ab7c26f --- /dev/null +++ b/src/kmk/tests/scripts/features/se_explicit @@ -0,0 +1,169 @@ +# -*-perl-*- +$description = "Test second expansion in ordinary rules."; + +$details = ""; + +# TEST #0: Test handing of '$' in prerequisites with and without second +# expansion. +# bird: Modified this test to use ${PRE} instead of $(PRE) as it failes +# when make is built with NO_ARCHIVES defined. + +# 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 + +!, +'-j1', +'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: ; @: +!, +'-j1', +'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"); + +1; diff --git a/src/kmk/tests/scripts/features/se_implicit b/src/kmk/tests/scripts/features/se_implicit new file mode 100644 index 0000000..e40270f --- /dev/null +++ b/src/kmk/tests/scripts/features/se_implicit @@ -0,0 +1,260 @@ +# -*-perl-*- +$description = "Test second expansion in ordinary 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 '$@' + +!, +'-j1', +'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: ; @: +!, + '-j1', +'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"); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/se_statpat b/src/kmk/tests/scripts/features/se_statpat new file mode 100644 index 0000000..828afa2 --- /dev/null +++ b/src/kmk/tests/scripts/features/se_statpat @@ -0,0 +1,109 @@ +# -*-perl-*- +$description = "Test second expansion in static pattern rules."; + +$details = ""; + +# Test #1: automatic variables. +# +# bird: Had to add -j1 here earlier... +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. +# +# bird: Had to add -j1 here earlier... +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 +'); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/features/shell_assignment b/src/kmk/tests/scripts/features/shell_assignment new file mode 100644 index 0000000..686e4bd --- /dev/null +++ b/src/kmk/tests/scripts/features/shell_assignment @@ -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; diff --git a/src/kmk/tests/scripts/features/statipattrules b/src/kmk/tests/scripts/features/statipattrules new file mode 100644 index 0000000..6b3c565 --- /dev/null +++ b/src/kmk/tests/scripts/features/statipattrules @@ -0,0 +1,111 @@ +# -*-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 $@ +', + '-j1', ".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(' +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(' +.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'); + +1; diff --git a/src/kmk/tests/scripts/features/targetvars b/src/kmk/tests/scripts/features/targetvars new file mode 100644 index 0000000..a9b8dbe --- /dev/null +++ b/src/kmk/tests/scripts/features/targetvars @@ -0,0 +1,273 @@ +# -*-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(' +SHELL = /bin/sh +export FOO = foo +export BAR = bar +one: override FOO = one +one two: ; @echo $(FOO) $(BAR) +two: BAR = two +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 [ -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 #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; diff --git a/src/kmk/tests/scripts/features/utf8 b/src/kmk/tests/scripts/features/utf8 new file mode 100644 index 0000000..54bc471 --- /dev/null +++ b/src/kmk/tests/scripts/features/utf8 @@ -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; diff --git a/src/kmk/tests/scripts/features/varnesting b/src/kmk/tests/scripts/features/varnesting new file mode 100644 index 0000000..d8f3ffb --- /dev/null +++ b/src/kmk/tests/scripts/features/varnesting @@ -0,0 +1,35 @@ +# -*-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; + + + + + + diff --git a/src/kmk/tests/scripts/features/vpath b/src/kmk/tests/scripts/features/vpath new file mode 100644 index 0000000..530d9e5 --- /dev/null +++ b/src/kmk/tests/scripts/features/vpath @@ -0,0 +1,82 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the \n" + ."vpath directive which allows you to specify a search \n" + ."path for a particular class of filenames, those that\n" + ."match a particular pattern."; + +$details = "This tests the vpath directive by specifying search directories\n" + ."for one class of filenames with the form: vpath pattern directories" + ."\nIn this test, we specify the working directory for all files\n" + ."that end in c or h. We also test the variables $@ (which gives\n" + ."target name) and $^ (which is a list of all dependencies \n" + ."including the directories in which they were found). It also\n" + ."uses the function firstword used to extract just the first\n" + ."dependency from the entire list."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "vpath %.c foo\n"; +print MAKEFILE "vpath %.c $workdir\n"; +print MAKEFILE "vpath %.h $workdir\n"; +print MAKEFILE "objects = main.o kbd.o commands.o display.o insert.o\n"; +print MAKEFILE "edit: \$(objects)\n"; +print MAKEFILE "\t\@echo cc -o \$@ \$^\n"; +print MAKEFILE "main.o : main.c defs.h\n"; +print MAKEFILE "\t\@echo cc -c \$(firstword \$^)\n"; +print MAKEFILE "kbd.o : kbd.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c kbd.c\n"; +print MAKEFILE "commands.o : command.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c commands.c\n"; +print MAKEFILE "display.o : display.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c display.c\n"; +print MAKEFILE "insert.o : insert.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c insert.c\n"; + +# END of Contents of MAKEFILE + +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); + +# kmk: this requires -j1 because of ordering. +&run_make_with_options($makefile,"-j1",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c $workdir${pathsep}main.c\ncc -c kbd.c\ncc -c commands.c\n" + ."cc -c display.c\n" + ."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; +} + +# 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'); + +1; diff --git a/src/kmk/tests/scripts/features/vpath2 b/src/kmk/tests/scripts/features/vpath2 new file mode 100644 index 0000000..7e970a7 --- /dev/null +++ b/src/kmk/tests/scripts/features/vpath2 @@ -0,0 +1,45 @@ +$description = "This is part 2 in a series to test the vpath directive\n" + ."It tests the three forms of the directive:\n" + ." vpath pattern directive\n" + ." vpath pattern (clears path associated with pattern)\n" + ." vpath (clears all paths specified with vpath)\n"; + +$details = "This test simply adds many search paths using various vpath\n" + ."directive forms and clears them afterwards. It has a simple\n" + ."rule to print a message at the end to confirm that the makefile\n" + ."ran with no errors.\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $workdir:$sourcedir\n"; +print MAKEFILE "vpath %.c foo\n"; +print MAKEFILE "vpath %.c $workdir\n"; +print MAKEFILE "vpath %.c $sourcedir\n"; +print MAKEFILE "vpath %.h $workdir\n"; +print MAKEFILE "vpath %.c\n"; +print MAKEFILE "vpath\n"; +print MAKEFILE "all:\n"; +print MAKEFILE "\t\@echo ALL IS WELL\n"; +# 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 = "ALL IS WELL\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/src/kmk/tests/scripts/features/vpath3 b/src/kmk/tests/scripts/features/vpath3 new file mode 100644 index 0000000..839fb72 --- /dev/null +++ b/src/kmk/tests/scripts/features/vpath3 @@ -0,0 +1,41 @@ +# -*-perl-*- + +$description = "Test the interaction of the -lfoo feature and vpath"; +$details = ""; + +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); +} + +1; diff --git a/src/kmk/tests/scripts/features/vpathgpath b/src/kmk/tests/scripts/features/vpathgpath new file mode 100644 index 0000000..5e6217b --- /dev/null +++ b/src/kmk/tests/scripts/features/vpathgpath @@ -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 touchfiles { + foreach (@_) { + ($f = $_) =~ s,VP/,$VP,g; + &utouch($off, $f); + $off += 10; + push(@touchedfiles, $f); + } +} + +# Run the general-case test + +&touchfiles("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; diff --git a/src/kmk/tests/scripts/features/vpathplus b/src/kmk/tests/scripts/features/vpathplus new file mode 100644 index 0000000..9ade3f0 --- /dev/null +++ b/src/kmk/tests/scripts/features/vpathplus @@ -0,0 +1,132 @@ +# -*-perl-*- +$description = "Tests the new VPATH+ functionality added in 3.76."; + +$details = ""; + +$VP = "$workdir$pathsep"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $VP\n"; + +print MAKEFILE <<'EOMAKE'; + +SHELL = /bin/sh + +.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 + +EOMAKE + +close(MAKEFILE); + +@touchedfiles = (); + +$off = -500; + +sub touchfiles { + foreach (@_) { + &utouch($off, $_); + $off += 10; + push(@touchedfiles, $_); + } +} + +# Run the general-case test + +&touchfiles("$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 = "cat bar.d > bar.c +cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1 +"; +&compare_output($answer,&get_logfile(1)); + +# Test rules that don't make the target correctly + +&touchfiles("$VP/notarget.c", "notarget.b", "notarget.d"); + +&run_make_with_options($makefile,"notarget",&get_logfile,512); + +$answer = "not creating notarget.c from notarget.d +cat notarget.c > notarget.b 2>/dev/null || exit 1 +$make_name: *** [$makefile:16: notarget.b] Error 1 +"; + +&compare_output($answer,&get_logfile(1)); + +# Test intermediate file handling (part 1) + +&touchfiles("$VP/inter.d"); + +&run_make_with_options($makefile,"intermediate",&get_logfile); + +push(@touchedfiles, "inter.a", "inter.b"); + +$answer = "cat ${VP}inter.d > inter.c +cat inter.c > inter.b 2>/dev/null || exit 1 +cat inter.b > inter.a +rm inter.b inter.c +"; +&compare_output($answer,&get_logfile(1)); + +# Test intermediate file handling (part 2) + +&utouch(-20, "inter.a"); +&utouch(-10, "$VP/inter.b"); +&touch("$VP/inter.d"); + +push(@touchedfiles, "$VP/inter.b", "$VP/inter.d"); + +&run_make_with_options($makefile,"intermediate",&get_logfile); + +$answer = "cat ${VP}inter.d > inter.c +cat inter.c > inter.b 2>/dev/null || exit 1 +cat inter.b > inter.a +rm inter.c +"; +&compare_output($answer,&get_logfile(1)); + +unlink @touchedfiles unless $keep; + +1; + +### Local Variables: +### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) +### End: diff --git a/src/kmk/tests/scripts/functions/abspath b/src/kmk/tests/scripts/functions/abspath new file mode 100644 index 0000000..84c30ab --- /dev/null +++ b/src/kmk/tests/scripts/functions/abspath @@ -0,0 +1,81 @@ +# -*-perl-*- +$description = "Test the abspath functions."; + +$details = ""; + +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; diff --git a/src/kmk/tests/scripts/functions/addprefix b/src/kmk/tests/scripts/functions/addprefix new file mode 100644 index 0000000..1845552 --- /dev/null +++ b/src/kmk/tests/scripts/functions/addprefix @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/functions/addsuffix b/src/kmk/tests/scripts/functions/addsuffix new file mode 100644 index 0000000..da4fbb7 --- /dev/null +++ b/src/kmk/tests/scripts/functions/addsuffix @@ -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; diff --git a/src/kmk/tests/scripts/functions/andor b/src/kmk/tests/scripts/functions/andor new file mode 100644 index 0000000..62e0c2e --- /dev/null +++ b/src/kmk/tests/scripts/functions/andor @@ -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; diff --git a/src/kmk/tests/scripts/functions/basename b/src/kmk/tests/scripts/functions/basename new file mode 100644 index 0000000..08f2ea5 --- /dev/null +++ b/src/kmk/tests/scripts/functions/basename @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/functions/call b/src/kmk/tests/scripts/functions/call new file mode 100644 index 0000000..dc1a623 --- /dev/null +++ b/src/kmk/tests/scripts/functions/call @@ -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: diff --git a/src/kmk/tests/scripts/functions/dir b/src/kmk/tests/scripts/functions/dir new file mode 100644 index 0000000..f48fb8c --- /dev/null +++ b/src/kmk/tests/scripts/functions/dir @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/functions/error b/src/kmk/tests/scripts/functions/error new file mode 100644 index 0000000..998afe4 --- /dev/null +++ b/src/kmk/tests/scripts/functions/error @@ -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: diff --git a/src/kmk/tests/scripts/functions/eval b/src/kmk/tests/scripts/functions/eval new file mode 100644 index 0000000..90513bd --- /dev/null +++ b/src/kmk/tests/scripts/functions/eval @@ -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); + +$extraENV{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; diff --git a/src/kmk/tests/scripts/functions/evalcall b/src/kmk/tests/scripts/functions/evalcall new file mode 100644 index 0000000..f0213c2 --- /dev/null +++ b/src/kmk/tests/scripts/functions/evalcall @@ -0,0 +1,119 @@ +# $Id: evalcall 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(evalcall var,argN...) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(evalcall ) function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +FUNC = local .RETURN = $2 $1 +ifneq ($(evalcall FUNC,a,b),b a) +$(error sub-test 0 failed: $(evalcall FUNC,a,b)) +endif + +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' + +FUNC = local .RETURN = $2 $1 +ifneq ($(evalcall FUNC,a,b),b a) +$(error sub-test 0 failed) +endif + +ADD = local .RETURN = $(expr $1 + $2) +ifneq ($(evalcall ADD,1,2),3) +$(error sub-test 1 failed) +endif + +define POP +local words := $(words $($1)) +local .RETURN := $(word $(words), $($1)) +$1 := $(wordlist 1, $(expr $(words) - 1), $($1)) +endef +stack-var = a b c d +ifneq ($(evalcall POP,stack-var),d) +$(error sub-test 2d failed) +endif +ifneq ($(evalcall POP,stack-var),c) +$(error sub-test 2c failed) +endif +ifneq ($(evalcall POP,stack-var),b) +$(error sub-test 2b failed) +endif +ifneq ($(evalcall POP,stack-var),a) +$(error sub-test 2a failed) +endif + + +# Negative tests: + +.RETURN = $2 $1 +FUNC = +ifneq ($(evalcall FUNC,a,b),) +$(error sub-test 10 failed) +endif + +.RETURN = +FUNC = .RETURN = $2 $1 +ifneq ($(evalcall FUNC,a,b),) +$(error sub-test 11 failed) +endif + + +# Test .ARGC: + +FUNC = local .RETURN = $(.ARGC) +ifneq ($(evalcall FUNC,a,b),2) +$(error sub-test 20 failed) +endif +ifneq ($(evalcall FUNC),0) +$(error sub-test 21 failed) +endif +ifneq ($(evalcall FUNC,aasdfasdf),1) +$(error sub-test 22 failed) +endif + + +.PHONY: all +all: ; @: +', +'', +''); +} + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/expr b/src/kmk/tests/scripts/functions/expr new file mode 100644 index 0000000..a68205f --- /dev/null +++ b/src/kmk/tests/scripts/functions/expr @@ -0,0 +1,74 @@ +# $Id: expr 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(expr expr) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the \$(expr ) function"; + +$details = "Much of the basic testing is taken care of by features/ifcond. +We only make sure \$(expr ) works here)."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(expr 1+1),2) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - basics, the $(expr test checks the rest). + # --------------------------------------------------- + run_make_test(' +ifneq ($(expr 1==1),1) +$(error sub-test 0 failed) +endif +ifneq ($(expr 1!=1),0) +$(error sub-test 1 failed) +endif +ifneq ($(expr 2*2),4) +$(error sub-test 1 failed) +endif +ifneq ($(expr 25*25),625) +$(error sub-test 1 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); + +} + + + +# Indicate that we're done. +1; + + diff --git a/src/kmk/tests/scripts/functions/file b/src/kmk/tests/scripts/functions/file new file mode 100644 index 0000000..904db79 --- /dev/null +++ b/src/kmk/tests/scripts/functions/file @@ -0,0 +1,161 @@ +# -*-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 +touch('file.out'); +chmod(0444, 'file.out'); + +# Find the error that will be printed +# This seems complicated, but we need the message from the C locale +my $loc = undef; +if ($has_POSIX) { + $loc = POSIX::setlocale(POSIX::LC_MESSAGES); + POSIX::setlocale(POSIX::LC_MESSAGES, 'C'); +} +my $e; +open(my $F, '>', 'file.out') and die "Opened read-only file!\n"; +$e = "$!"; +$loc and POSIX::setlocale(POSIX::LC_MESSAGES, $loc); + +run_make_test(q! +define A +a +b +endef +$(file > file.out,$(A)) +x:;@cat file.out +!, + '', "#MAKEFILE#:6: *** open: file.out: $e. 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'); + +# 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; diff --git a/src/kmk/tests/scripts/functions/filter-out b/src/kmk/tests/scripts/functions/filter-out new file mode 100644 index 0000000..1fe4819 --- /dev/null +++ b/src/kmk/tests/scripts/functions/filter-out @@ -0,0 +1,42 @@ +# -*-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"); + +# 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; diff --git a/src/kmk/tests/scripts/functions/findstring b/src/kmk/tests/scripts/functions/findstring new file mode 100644 index 0000000..48abede --- /dev/null +++ b/src/kmk/tests/scripts/functions/findstring @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/functions/flavor b/src/kmk/tests/scripts/functions/flavor new file mode 100644 index 0000000..80d6be7 --- /dev/null +++ b/src/kmk/tests/scripts/functions/flavor @@ -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; diff --git a/src/kmk/tests/scripts/functions/for b/src/kmk/tests/scripts/functions/for new file mode 100644 index 0000000..0152395 --- /dev/null +++ b/src/kmk/tests/scripts/functions/for @@ -0,0 +1,69 @@ +# $Id: for 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(for init,condition,next,body) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(for ) loop function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(for local i=0, $i <= 10, local i := $(expr $i + 1),$i),0 1 2 3 4 5 6 7 8 9 10) +$(error sub-test 0 failed:$(for local i=0, $i <= 10, local i := $(expr $i + 1),$i)) +endif + +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(for local i=0, $i <= 10, local i := $(expr $i + 1),$i),0 1 2 3 4 5 6 7 8 9 10) +$(error sub-test 0 failed) +endif +ifneq (.$(for local i=0, $i <= 3, local i := $(expr $i + 1), $i ).,. 0 1 2 3 .) +$(error sub-test 1 failed) +endif +ifneq (.$(foreach i,0 1 2 3, $i ).,. 0 1 2 3 .) +$(error sub-test 1b failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/foreach b/src/kmk/tests/scripts/functions/foreach new file mode 100644 index 0000000..88ef0a7 --- /dev/null +++ b/src/kmk/tests/scripts/functions/foreach @@ -0,0 +1,97 @@ +# -*-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. +# kmk: CC isn't a default. +$extraENV{FOOFOO} = 'foo foo'; +$CC_origin = $is_kmk ? "undefined" : "default"; + +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)', + '-j1 -e WHITE=WHITE CFLAGS=', + "undefined file ". $CC_origin ." file environment default file command line override automatic automatic +foo.o bletch.o null.o @.o garf.o .o .o undefined.o file.o ". $CC_origin .".o file.o environment.o default.o file.o command.o line.o override.o automatic.o automatic.o"); + +delete $extraENV{FOOFOO}; + +# 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; diff --git a/src/kmk/tests/scripts/functions/guile b/src/kmk/tests/scripts/functions/guile new file mode 100644 index 0000000..c63bec9 --- /dev/null +++ b/src/kmk/tests/scripts/functions/guile @@ -0,0 +1,99 @@ +# -*-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; + +# 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 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; diff --git a/src/kmk/tests/scripts/functions/if b/src/kmk/tests/scripts/functions/if new file mode 100644 index 0000000..8604e4f --- /dev/null +++ b/src/kmk/tests/scripts/functions/if @@ -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; diff --git a/src/kmk/tests/scripts/functions/if-expr b/src/kmk/tests/scripts/functions/if-expr new file mode 100644 index 0000000..764522d --- /dev/null +++ b/src/kmk/tests/scripts/functions/if-expr @@ -0,0 +1,84 @@ +# $Id: if-expr 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(if-expr expr, if-expand, else-expand) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the \$(if-expr ) function"; + +$details = "A few simple tests, nothing spectacular. More comprehensive testing +is preformed by functions/expr and features/ifcond."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(if-expr 1+1,1,0),1) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - basics, the $(expr test checks the rest). + # --------------------------------------------------- + run_make_test(' +IF-EXPAND = 7 +ELSE-EXPAND = -7 +ifneq ($(if-expr 1==1,$(IF-EXPAND),$(ELSE-EXPAND)),7) +$(error sub-test 0 failed) +endif +ifneq ($(if-expr 1!=1,$(IF-EXPAND),$(ELSE-EXPAND)),-7) +$(error sub-test 1 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + + # TEST #2 - Checks that the optional 3 argument can be omitted. + # ------------------------------------------------------------- + run_make_test(' +ifneq ($(if-expr 1==1,true),true) +$(error sub-test 0 failed) +endif +ifneq ($(if-expr 2==1,true),) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/insert b/src/kmk/tests/scripts/functions/insert new file mode 100644 index 0000000..6a597c6 --- /dev/null +++ b/src/kmk/tests/scripts/functions/insert @@ -0,0 +1,106 @@ +# $Id: insert 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(insert in, str[, n[, length[, pad]]]) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(insert ) function"; + +$details = "Testing edges and some simple stuff."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(insert a,b),ab) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(insert a,b,1),ab) +$(error sub-test 0 failed) +endif +ifneq ($(insert a,b,2),ba) +$(error sub-test 1 failed) +endif +ifneq ($(insert a,b,3),b a) +$(error sub-test 2 failed) +endif +ifneq ($(insert a,b,0),ba) +$(error sub-test 3 failed) +endif +ifneq ($(insert a,b,-1),ab) +$(error sub-test 4 failed) +endif +ifneq ($(insert a,b,-2),ab) +$(error sub-test 5 failed) +endif +ifneq ($(insert a,b,-10),ab) +$(error sub-test 6 failed) +endif + +ifneq ($(insert a,b,-10,0),b) +$(error sub-test 10 failed) +endif +ifneq ($(insert aAAA,b,4,1),b a) +$(error sub-test 11 failed) +endif +ifneq ($(insert a,bBbBbBb,4,4),bBba BbBb) +$(error sub-test 12 failed) +endif + +ifneq ($(insert a,bBbBbBb,4,4,z),bBbazzzBbBb) +$(error sub-test 20 failed) +endif +ifneq ($(insert a,bBbBbBb,4,4,xy),bBbaxyxBbBb) +$(error sub-test 21 failed) +endif +ifneq ($(insert a,bBbBbBb,4,4,xyz),bBbaxyzBbBb) +$(error sub-test 22 failed) +endif +ifneq ($(insert a,bBbBbBb,4,4,xyzXYZ),bBbaxyzBbBb) +$(error sub-test 23 failed) +endif +ifneq ($(insert a,bBbBbBb,4,4,),bBba BbBb) +$(error sub-test 24 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/intersects b/src/kmk/tests/scripts/functions/intersects new file mode 100644 index 0000000..8d136fb --- /dev/null +++ b/src/kmk/tests/scripts/functions/intersects @@ -0,0 +1,94 @@ +# $Id: intersects 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(intersects set-a,set-b) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(intersecs ) predicate function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(intersects a b c d e f, a),1) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(intersects a b c d e f, f),1) +$(error sub-test 0 failed) +endif +ifneq ($(intersects a b c d e f, f),1) +$(error sub-test 1 failed) +endif +ifneq ($(intersects a b c d e f, d),1) +$(error sub-test 2 failed) +endif +ifneq ($(intersects b c d e f, a),) +$(error sub-test 3 failed) +endif +ifneq ($(intersects a b c d e f, a b c d e f),1) +$(error sub-test 4 failed) +endif +ifneq ($(intersects a b c d e f, f e d c b a),1) +$(error sub-test 5 failed) +endif +ifneq ($(intersects f e d c b a, a b c d e f),1) +$(error sub-test 6 failed) +endif + +SET-A = make foo bar +SET-B = $(SET-A) +ifeq ($(intersects $(SET-A),$(SET-B)),) +$(error sub-test 7 failed) +endif +SET-B = foo +ifeq ($(intersects $(SET-A),$(SET-B)),) +$(error sub-test 8 failed) +endif +SET-B = foobar +ifneq ($(intersects $(SET-A),$(SET-B)),) +$(error sub-test 9 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/join b/src/kmk/tests/scripts/functions/join new file mode 100644 index 0000000..302c307 --- /dev/null +++ b/src/kmk/tests/scripts/functions/join @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/functions/lastpos b/src/kmk/tests/scripts/functions/lastpos new file mode 100644 index 0000000..248db2b --- /dev/null +++ b/src/kmk/tests/scripts/functions/lastpos @@ -0,0 +1,118 @@ +# $Id: lastpos 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(lastpos needle, haystack[, start]) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(lastpos ) function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(lastpos b,abc),2) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(lastpos t,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 0 failed) +endif +ifneq ($(lastpos tu,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 1 failed) +endif +ifneq ($(lastpos tuv,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 2 failed) +endif +ifneq ($(lastpos tuvw,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 3 failed) +endif +ifneq ($(lastpos tuvwx,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 4 failed) +endif +ifneq ($(lastpos tuvwxy,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 5 failed) +endif +ifneq ($(lastpos tuvwxyz,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 6 failed) +endif +ifneq ($(lastpos tuvwxyz!,abcdefghijklmnopqrstuvwxyz),0) +$(error sub-test 7 failed) +endif + +ifneq ($(lastpos a,ababababab),9) +$(error sub-test 10 failed) +endif +ifneq ($(lastpos a,ababababab,8),7) +$(error sub-test 11 failed) +endif +ifneq ($(lastpos a,ababababab,7),7) +$(error sub-test 12 failed) +endif +ifneq ($(lastpos a,ababababab,4),3) +$(error sub-test 13 failed) +endif +ifneq ($(lastpos a,ababababab,3),3) +$(error sub-test 14 failed) +endif +ifneq ($(lastpos a,ababababab,2),1) +$(error sub-test 15 failed) +endif +ifneq ($(lastpos a,ababababab,1),1) +$(error sub-test 16 failed) +endif +ifneq ($(lastpos a,ababababab,-1),9) +$(error sub-test 17 failed) +endif +ifneq ($(lastpos a,ababababab,-2),9) +$(error sub-test 18 failed) +endif +ifneq ($(lastpos a,ababababab,-10),1) +$(error sub-test 19 failed) +endif +ifneq ($(lastpos a,ababababab,-11),0) +$(error sub-test 20 failed) +endif + + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/length b/src/kmk/tests/scripts/functions/length new file mode 100644 index 0000000..c8ea34d --- /dev/null +++ b/src/kmk/tests/scripts/functions/length @@ -0,0 +1,71 @@ +# $Id: length 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(length text) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(length ) function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(length abcd),4) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(length asdf),4) +$(error sub-test 0 failed) +endif +ifneq ($(length a),1) +$(error sub-test 1 failed) +endif +ifneq ($(length 0123456789),10) +$(error sub-test 2 failed) +endif +ifneq ($(length 0123456789 ),11) +$(error sub-test 3 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/length-var b/src/kmk/tests/scripts/functions/length-var new file mode 100644 index 0000000..0583713 --- /dev/null +++ b/src/kmk/tests/scripts/functions/length-var @@ -0,0 +1,75 @@ +# $Id: length-var 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(length-var var) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(length-var ) function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(length-var non-existing-variable),0) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +VAR0 := asdf +ifneq ($(length-var VAR0),4) +$(error sub-test 0 failed) +endif +VAR1 = a +ifneq ($(length-var VAR1),1) +$(error sub-test 1 failed) +endif +VAR2 = 0123456789 +ifneq ($(length-var VAR2),10) +$(error sub-test 2 failed) +endif +VAR2 = $(VAR1) $(VAR0) +ifneq ($(length-var VAR2),15) +$(error sub-test 3 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/notdir b/src/kmk/tests/scripts/functions/notdir new file mode 100644 index 0000000..4ed8f9c --- /dev/null +++ b/src/kmk/tests/scripts/functions/notdir @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/functions/origin b/src/kmk/tests/scripts/functions/origin new file mode 100644 index 0000000..7a6a9fa --- /dev/null +++ b/src/kmk/tests/scripts/functions/origin @@ -0,0 +1,54 @@ +# -*-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"; + +# kmk: CC isn't a default. +$CC_origin = $is_kmk ? "undefined" : "default"; + +# Set an environment variable +$extraENV{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 +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 '. $CC_origin .' environment default file command line override automatic +undefined +'. $CC_origin .' +environment +default +file +command line +override +automatic'); + +# Reset an environment variable +delete $extraENV{MAKETEST}; + +1; diff --git a/src/kmk/tests/scripts/functions/pos b/src/kmk/tests/scripts/functions/pos new file mode 100644 index 0000000..bdc3d40 --- /dev/null +++ b/src/kmk/tests/scripts/functions/pos @@ -0,0 +1,118 @@ +# $Id: pos 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(pos needle, haystack[, start]) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(pos ) function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(pos b,abc),2) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(pos t,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 0 failed) +endif +ifneq ($(pos tu,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 1 failed) +endif +ifneq ($(pos tuv,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 2 failed) +endif +ifneq ($(pos tuvw,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 3 failed) +endif +ifneq ($(pos tuvwx,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 4 failed) +endif +ifneq ($(pos tuvwxy,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 5 failed) +endif +ifneq ($(pos tuvwxyz,abcdefghijklmnopqrstuvwxyz),20) +$(error sub-test 6 failed) +endif +ifneq ($(pos tuvwxyz!,abcdefghijklmnopqrstuvwxyz),0) +$(error sub-test 7 failed) +endif + +ifneq ($(pos a,ababababab),1) +$(error sub-test 10 failed) +endif +ifneq ($(pos a,ababababab,2),3) +$(error sub-test 11 failed) +endif +ifneq ($(pos a,ababababab,3),3) +$(error sub-test 12 failed) +endif +ifneq ($(pos a,ababababab,8),9) +$(error sub-test 13 failed) +endif +ifneq ($(pos a,ababababab,8),9) +$(error sub-test 14 failed) +endif +ifneq ($(pos a,ababababab,9),9) +$(error sub-test 15 failed) +endif +ifneq ($(pos a,ababababab,10),0) +$(error sub-test 16 failed) +endif +ifneq ($(pos a,ababababab,-1),0) +$(error sub-test 17 failed) +endif +ifneq ($(pos a,ababababab,-2),9) +$(error sub-test 18 failed) +endif +ifneq ($(pos a,ababababab,-10),1) +$(error sub-test 19 failed) +endif +ifneq ($(pos a,ababababab,-11),0) +$(error sub-test 20 failed) +endif + + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/printf b/src/kmk/tests/scripts/functions/printf new file mode 100644 index 0000000..cb20168 --- /dev/null +++ b/src/kmk/tests/scripts/functions/printf @@ -0,0 +1,80 @@ +# $Id: printf 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(printf fmt[,args...]) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(printf ) function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(printf abcd),abcd) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(printf %s,abcde),abcde) +$(error sub-test 0 failed) +endif +ifneq ($(printf %.4s,abcde),abcd) +$(error sub-test 1 failed) +endif +ifneq ($(printf %.8s,abc),abc) +$(error sub-test 2 failed) +endif +ifneq ($(printf %.2s%.3s,abc,zde),abzde) +$(error sub-test 3 failed) +endif +define HASH +# +endef +ifneq ($(printf %$(HASH)x,127),0x7f) +$(error sub-test 4 failed) +endif +ifneq ($(printf %$(HASH)X,127),0X7F) +$(error sub-test 5 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/realpath b/src/kmk/tests/scripts/functions/realpath new file mode 100644 index 0000000..9b503b4 --- /dev/null +++ b/src/kmk/tests/scripts/functions/realpath @@ -0,0 +1,82 @@ +# -*-perl-*- +$description = "Test the realpath functions."; + +$details = ""; + +run_make_test(' +ifneq ($(realpath .),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath ./),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath .///),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath /),/) + $(error ) +endif + +ifneq ($(realpath /.),/) + $(error ) +endif + +ifneq ($(realpath /./),/) + $(error ) +endif + +ifneq ($(realpath /.///),/) + $(error ) +endif + +ifneq ($(realpath /..),/) + $(error ) +endif + +ifneq ($(realpath /../),/) + $(error ) +endif + +ifneq ($(realpath /..///),/) + $(error ) +endif + +ifneq ($(realpath . /..),$(CURDIR) /) + $(error ) +endif + +.PHONY: all +all: ; @: +', + '', + ''); + +# On Windows platforms, "//" means something special. So, don't do these +# tests there. + +if ($port_type ne 'W32') { + run_make_test(' +ifneq ($(realpath ///),/) + $(error ) +endif + +ifneq ($(realpath ///.),/) + $(error ) +endif + +ifneq ($(realpath ///..),/) + $(error ) +endif + +.PHONY: all +all: ; @:', + '', + ''); +} + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/functions/root b/src/kmk/tests/scripts/functions/root new file mode 100644 index 0000000..46abbd1 --- /dev/null +++ b/src/kmk/tests/scripts/functions/root @@ -0,0 +1,172 @@ +# $Id: root 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(root path...) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(path ) function"; + +$details = "Testing edges and some simple stuff."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(root /a),/) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(root /asdf/asdf/adsf),/) +$(error sub-test 0 failed:$(root /asdf/asdf/adsf)) +endif +ifneq ($(root asdf/asdf/adsf),) +$(error sub-test 1 failed) +endif +ifneq ($(root asdf/asdf/adsf/),) +$(error sub-test 2 failed) +endif +ifneq ($(root asdf/asdf/adsf/),) +$(error sub-test 3 failed) +endif +ifneq ($(root a),) +$(error sub-test 4 failed) +endif +ifneq ($(root ),) +$(error sub-test 5 failed) +endif +ifneq ($(root //a),//) +$(error sub-test 6 failed) +endif +ifneq ($(root /a),/) +$(error sub-test 7 failed) +endif +ifneq ($(root ///a),///) +$(error sub-test 8 failed) +endif +ifneq ($(root /a /b /c d /e),/ / / /) +$(error sub-test 9 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); + + + # TEST #2 - DOS PATH stuff. + # ------------------------ + if ($port_type eq 'W32' || $port_type eq 'OS/2' || $port_type eq 'DOS') { + run_make_test(' +ifneq ($(root D:),D:) +$(error sub-test 0 failed) +endif +ifneq ($(root D:/),D:/) +$(error sub-test 1 failed) +endif +ifneq ($(root D:\\),D:\\) +$(error sub-test 2 failed) +endif +ifneq ($(root D:\\\\),D:\\\\) +$(error sub-test 3 failed) +endif +ifneq ($(root D:\\\\a),D:\\\\) +$(error sub-test 4 failed) +endif +ifneq ($(root D:\\/a),D:\\/) +$(error sub-test 5 failed) +endif +ifneq ($(root a:\\\\//asdf/asdf\\asdf),a:\\\\//) +$(error sub-test 6 failed) +endif +ifneq ($(root z://\\\\asdf/asdf\\asdf),z://\\\\) +$(error sub-test 7 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); + } + + # TEST #3 - UNC PATH stuff. + # ------------------------ + if ($port_type eq 'W32' || $port_type eq 'OS/2') { + run_make_test(' +ifneq ($(root //./),//./) +$(error sub-test 0 failed) +endif +ifneq ($(root \\\\.\\),\\\\.\\) +$(error sub-test 1 failed) +endif +ifneq ($(root \\\\\\.\\),\\\\\\) +$(error sub-test 2 failed) +endif +ifneq ($(root ///.\\),///) +$(error sub-test 3 failed) +endif +ifneq ($(root /\\.\\),/\\.\\) +$(error sub-test 4 failed) +endif +ifneq ($(root \\/.\\),\\/.\\) +$(error sub-test 5 failed) +endif +ifneq ($(root //srv/),//srv/) +$(error sub-test 6 failed) +endif +ifneq ($(root //srv),) +$(error sub-test 7 failed) +endif +ifneq ($(root //srv/share),//srv/share) +$(error sub-test 8 failed) +endif +ifneq ($(root //srv/share/),//srv/share/) +$(error sub-test 9 failed) +endif +ifneq ($(root //srv/share/asdf),//srv/share/) +$(error sub-test 10 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); + } + +} + + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/select b/src/kmk/tests/scripts/functions/select new file mode 100644 index 0000000..843ff2e --- /dev/null +++ b/src/kmk/tests/scripts/functions/select @@ -0,0 +1,96 @@ +# $Id: select 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(select when1-cond, when1-body[,whenN-cond, whenN-body]) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(select ) conditional function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(select 0,failed,1,success),success) +$(error sub-test 0 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' + +ifneq ($(select 0,failed,1-1,failed2,otherwise,success),success) +$(error sub-test 0 failed) +endif +ifneq ($(select 0,failed,1-1,failed2,otherwise:,success),success) +$(error sub-test 1 failed) +endif +ifneq ($(select 0,failed,1-1,failed2, otherwise:,success),success) +$(error sub-test 2 failed) +endif +ifneq ($(select 0,failed,1-1,failed2, otherwise: ,success),success) +$(error sub-test 3 failed) +endif +ifneq ($(select 0,failed,1-1,failed2, otherwise : ,success),success) +$(error sub-test 4 failed) +endif +ifneq ($(select 0,failed,1-1,failed2, default: ,success),success) +$(error sub-test 5 failed) +endif +ifneq ($(select 0,failed,1-1,failed2,default,success),success) +$(error sub-test 6 failed) +endif + +ifneq ($(select 0,failed),) +$(error sub-test 10 failed) +endif +ifneq ($(select 1,works),works) +$(error sub-test 11 failed) +endif +ifneq ($(select 0,failed,1,success,1,failed3,otherwise,failed4),success) +$(error sub-test 12 failed) +endif + + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + + + + diff --git a/src/kmk/tests/scripts/functions/shell b/src/kmk/tests/scripts/functions/shell new file mode 100644 index 0000000..809c77f --- /dev/null +++ b/src/kmk/tests/scripts/functions/shell @@ -0,0 +1,60 @@ +# -*-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 +if ($all_tests) { + run_make_test(q! +FOO := $(shell echo '#') +foo: ; echo '$(FOO)' +!, + '', "#\n"); +} + +# Test shells inside exported environment variables. +# This is the test that fails if we try to put make exported variables into +# the environment for a $(shell ...) call. +run_make_test(' +export HI = $(shell echo hi) +.PHONY: all +all: ; @echo $$HI + ','','hi'); + +# Test shell errors in recipes including offset +run_make_test(' +all: + @echo hi + $(shell ./basdfdfsed there) + @echo there +', + '', "#MAKE#: ./basdfdfsed: Command not found\nhi\nthere\n"); + +1; + +### Local Variables: +### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) +### End: diff --git a/src/kmk/tests/scripts/functions/sort b/src/kmk/tests/scripts/functions/sort new file mode 100644 index 0000000..e6e1343 --- /dev/null +++ b/src/kmk/tests/scripts/functions/sort @@ -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: diff --git a/src/kmk/tests/scripts/functions/strip b/src/kmk/tests/scripts/functions/strip new file mode 100644 index 0000000..8222433 --- /dev/null +++ b/src/kmk/tests/scripts/functions/strip @@ -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; diff --git a/src/kmk/tests/scripts/functions/substitution b/src/kmk/tests/scripts/functions/substitution new file mode 100644 index 0000000..0d2f6a2 --- /dev/null +++ b/src/kmk/tests/scripts/functions/substitution @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/functions/substr b/src/kmk/tests/scripts/functions/substr new file mode 100644 index 0000000..bf0eba9 --- /dev/null +++ b/src/kmk/tests/scripts/functions/substr @@ -0,0 +1,125 @@ +# $Id: substr 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(substr str, start[, length[, pad]]) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(substr ) function"; + +$details = "A few simple tests and edge cases."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(substr asdf,4),f) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,20),tuvwxyz) +$(error sub-test 0 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,20,1),t) +$(error sub-test 1 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,20,2),tu) +$(error sub-test 2 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,20,0),) +$(error sub-test 3 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-1),z) +$(error sub-test 4 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-2),yz) +$(error sub-test 5 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-2,2),yz) +$(error sub-test 6 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-2,3),yz) +$(error sub-test 7 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-2,5,XYZ),yzXYZ) +$(error sub-test 8 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-25,1),b) +$(error sub-test 9 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-26,1),a) +$(error sub-test 10 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-27,1),) +$(error sub-test 11 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-27,2),a) +$(error sub-test 12 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-27,3),ab) +$(error sub-test 13 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-27,3,_),_ab) +$(error sub-test 14 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-28,4,.^),.^ab) +$(error sub-test 15 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-50,4),) +$(error sub-test 16 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,-50,4,.^),.^.^) +$(error sub-test 17 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,27,4,.^),.^.^) +$(error sub-test 18 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,28,3,.^),.^.) +$(error sub-test 19 failed) +endif +SP := $(subst ., ,.) +ifneq (.$(substr abcdefghijklmnopqrstuvwxyz,100,3, ).,. .) +$(error sub-test 20 failed) +endif +ifneq ($(substr abcdefghijklmnopqrstuvwxyz,100,3, ),$(SP)$(SP)$(SP)) +$(error sub-test 21 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/suffix b/src/kmk/tests/scripts/functions/suffix new file mode 100644 index 0000000..0c4f919 --- /dev/null +++ b/src/kmk/tests/scripts/functions/suffix @@ -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; + + + + + + diff --git a/src/kmk/tests/scripts/functions/translate b/src/kmk/tests/scripts/functions/translate new file mode 100644 index 0000000..2dcf83f --- /dev/null +++ b/src/kmk/tests/scripts/functions/translate @@ -0,0 +1,76 @@ +# $Id: translate 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(translate string, from-set[, to-set[, pad-char]]) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(translate ) function"; + +$details = "A few simple tests and edge cases."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +ifneq ($(translate abcdefghijklmnopqrstuvwxyz,abcde,01234),01234fghijklmnopqrstuvwxyz) +$(error sub-test 0 failed) +endif +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +ifneq ($(translate abcdefghijklmnopqrstuvwxyz,abcde,01234),01234fghijklmnopqrstuvwxyz) +$(error sub-test 0 failed) +endif +ifneq ($(translate abcdefghijklmnopqrstuvwxyz,abcde,,.),.....fghijklmnopqrstuvwxyz) +$(error sub-test 1 failed) +endif +ifneq ($(translate abcdefghijklmnopqrstuvwxyz,abcde,),fghijklmnopqrstuvwxyz) +$(error sub-test 2 failed) +endif +ifneq ($(translate abcdefghijklmnopqrstuvwxyz,abcde,x1),x1fghijklmnopqrstuvwxyz) +$(error sub-test 3 failed) +endif +ifneq ($(translate abcdefghijklmnopqrstuvwxyz,bfh),acdegijklmnopqrstuvwxyz) +$(error sub-test 4 failed) +endif +ifneq ($(translate abcdefghijklmnopqrstuvwxyz,z,Z),abcdefghijklmnopqrstuvwxyZ) +$(error sub-test 5 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + +# Indicate that we're done. +1; + diff --git a/src/kmk/tests/scripts/functions/value b/src/kmk/tests/scripts/functions/value new file mode 100644 index 0000000..8e1a6f0 --- /dev/null +++ b/src/kmk/tests/scripts/functions/value @@ -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; diff --git a/src/kmk/tests/scripts/functions/warning b/src/kmk/tests/scripts/functions/warning new file mode 100644 index 0000000..16eb83b --- /dev/null +++ b/src/kmk/tests/scripts/functions/warning @@ -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: diff --git a/src/kmk/tests/scripts/functions/while b/src/kmk/tests/scripts/functions/while new file mode 100644 index 0000000..c0e6481 --- /dev/null +++ b/src/kmk/tests/scripts/functions/while @@ -0,0 +1,73 @@ +# $Id: while 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# $(while condition,body) +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the $(while ) loop function"; + +$details = "A few simple tests, nothing spectacular."; + +if ($is_kmk) { + + # TEST #0 - check that the feature is present. + # -------------------------------------------- + run_make_test(' +VAR := 0 +OUTPUT := $(while $(VAR)==0,$(eval VAR=1)works) +ifneq ($(OUTPUT),works) +$(error sub-test 0 failed:$(OUTPUT)) +endif + +.PHONY: all +all: ; @: +', +'', +''); + + # TEST #1 - the real test. + # ------------------------ + run_make_test(' +VAR := 0 +OUTPUT := $(while $(VAR) < 3,$(eval VAR:=$(expr $(VAR) + 1))$(VAR)) +ifneq ($(OUTPUT),1 2 3) +$(error sub-test 0 failed:$(OUTPUT)) +endif + +ifneq (.$(while 0,asdfasdfadsf).,..) +$(error sub-test 1 failed) +endif + +.PHONY: all +all: ; @: +', +'', +''); +} + + + +# Indicate that we're done. +1; + + + diff --git a/src/kmk/tests/scripts/functions/wildcard b/src/kmk/tests/scripts/functions/wildcard new file mode 100644 index 0000000..bcd84ad --- /dev/null +++ b/src/kmk/tests/scripts/functions/wildcard @@ -0,0 +1,103 @@ +# -*-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"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOM; +.PHONY: print1 print2 clean +print1: ;\@echo \$(sort \$(wildcard example.*)) +print2: +\t\@echo \$(sort \$(wildcard example.?)) +\t\@echo \$(sort \$(wildcard example.[a-z0-9])) +\t\@echo \$(sort \$(wildcard example.[!A-Za-z_\\!])) +clean: +\t$delete_command \$(sort \$(wildcard example.*)) +EOM + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("example.1"); +&touch("example.two"); +&touch("example.3"); +&touch("example.for"); +&touch("example._"); + +# TEST #1 +# ------- + +$answer = "example.1 example.3 example._ example.for example.two\n"; + +&run_make_with_options($makefile,"print1",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- + +$answer = "example.1 example.3 example._\n" + ."example.1 example.3\n" + ."example.1 example.3\n"; + +&run_make_with_options($makefile,"print2",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 +# ------- + +$answer = "$delete_command example.1 example.3 example._ example.for example.two"; +if ($vos) +{ + $answer .= " \n"; +} +else +{ + $answer .= "\n"; +} + +&run_make_with_options($makefile,"clean",&get_logfile); + +if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for")) { + $test_passed = 0; +} + +&compare_output($answer,&get_logfile(1)); + +# 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"); + +1; diff --git a/src/kmk/tests/scripts/functions/word b/src/kmk/tests/scripts/functions/word new file mode 100644 index 0000000..4dcc940 --- /dev/null +++ b/src/kmk/tests/scripts/functions/word @@ -0,0 +1,167 @@ +# -*-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"; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<'EOF'; +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) +all: + @echo $(words $(string)) + @echo $(words $(string4)) + @echo $(word 1, $(string)) + @echo $(word 100, $(string)) + @echo $(word 1, $(string)) + @echo $(word 1000, $(string3)) + @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)) +EOF +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "6\n" + ."2058\n" + ."word.pl\n" + ."\n" + ."word.pl\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"; +&compare_output($answer, &get_logfile(1)); + + +# 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)) + +wordlist-e1: ; @echo $(wordlist ,,$(FOO)) +wordlist-e2: ; @echo $(wordlist abc ,,$(FOO)) +wordlist-e3: ; @echo $(wordlist 1, 12a ,$(FOO))', + 'word-e1', + "#MAKEFILE#:3: *** non-numeric first argument to 'word' function: ''. Stop.", + 512); + +run_make_test(undef, + 'word-e2', + "#MAKEFILE#:4: *** non-numeric first argument to 'word' function: 'abc '. Stop.", + 512); + +run_make_test(undef, + 'word-e3', + "#MAKEFILE#:5: *** non-numeric first argument to 'word' function: '1a'. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e1', + "#MAKEFILE#:7: *** non-numeric first argument to 'wordlist' function: ''. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e2', + "#MAKEFILE#:8: *** non-numeric first argument to 'wordlist' function: 'abc '. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e3', + "#MAKEFILE#:9: *** non-numeric 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: *** non-numeric first argument to 'word' function: ''. Stop.", + 512); + +run_make_test(undef, + 'word-e x=abc', + "#MAKEFILE#:3: *** non-numeric 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: *** non-numeric first argument to 'wordlist' function: ''. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e s=abc e=', + "#MAKEFILE#:4: *** non-numeric first argument to 'wordlist' function: 'abc'. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e s=4 e=12a', + "#MAKEFILE#:4: *** non-numeric 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); + + +# 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; diff --git a/src/kmk/tests/scripts/misc/bs-nl b/src/kmk/tests/scripts/misc/bs-nl new file mode 100644 index 0000000..fc323ce --- /dev/null +++ b/src/kmk/tests/scripts/misc/bs-nl @@ -0,0 +1,227 @@ +# -*-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'); + +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'); + +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: +x = y +var = he \ +llo +var:;@echo '|$(var)|'!, + '', "|he llo|"); + +# POSIX: One space per bs-nl +run_make_test(q! +.POSIX: +x = y +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/\\v/\v/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; diff --git a/src/kmk/tests/scripts/misc/close_stdout b/src/kmk/tests/scripts/misc/close_stdout new file mode 100644 index 0000000..18606c3 --- /dev/null +++ b/src/kmk/tests/scripts/misc/close_stdout @@ -0,0 +1,9 @@ +# -*-perl-*- + +$description = "Make sure make exits with an error if stdout is full."; + +if (-e '/dev/full') { + run_make_test('', '-v > /dev/full', '/^#MAKE#: write error/', 256); +} + +1; diff --git a/src/kmk/tests/scripts/misc/fopen-fail b/src/kmk/tests/scripts/misc/fopen-fail new file mode 100644 index 0000000..2ec9810 --- /dev/null +++ b/src/kmk/tests/scripts/misc/fopen-fail @@ -0,0 +1,18 @@ +# -*-perl-*- + +$description = "Make sure make exits with an error if fopen fails."; + +# 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; diff --git a/src/kmk/tests/scripts/misc/general1 b/src/kmk/tests/scripts/misc/general1 new file mode 100644 index 0000000..352fc6a --- /dev/null +++ b/src/kmk/tests/scripts/misc/general1 @@ -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; diff --git a/src/kmk/tests/scripts/misc/general2 b/src/kmk/tests/scripts/misc/general2 new file mode 100644 index 0000000..d4e008a --- /dev/null +++ b/src/kmk/tests/scripts/misc/general2 @@ -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,"-j1",&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; diff --git a/src/kmk/tests/scripts/misc/general3 b/src/kmk/tests/scripts/misc/general3 new file mode 100644 index 0000000..7bbff1c --- /dev/null +++ b/src/kmk/tests/scripts/misc/general3 @@ -0,0 +1,315 @@ +# -*-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 +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' +", + '', '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(" +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"); + +1; diff --git a/src/kmk/tests/scripts/misc/general4 b/src/kmk/tests/scripts/misc/general4 new file mode 100644 index 0000000..dd9475c --- /dev/null +++ b/src/kmk/tests/scripts/misc/general4 @@ -0,0 +1,85 @@ +# -*-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 +# kmk: No default implicit rules. + +&touch('foo.c'); +run_make_test('foo: foo.o', + 'CC="@echo cc" OUTPUT_OPTION=', + !$is_kmk ? 'cc -c foo.c +cc foo.o -o foo' : +"#MAKE#: *** No rule to make target `foo.o', needed by `foo'. Stop.", +!$is_kmk ? 0 : 512); +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"); + +1; diff --git a/src/kmk/tests/scripts/misc/utf8 b/src/kmk/tests/scripts/misc/utf8 new file mode 100644 index 0000000..2adcd07 --- /dev/null +++ b/src/kmk/tests/scripts/misc/utf8 @@ -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; diff --git a/src/kmk/tests/scripts/options/dash-B b/src/kmk/tests/scripts/options/dash-B new file mode 100644 index 0000000..4c4c4cf --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-B @@ -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: diff --git a/src/kmk/tests/scripts/options/dash-C b/src/kmk/tests/scripts/options/dash-C new file mode 100644 index 0000000..42d0a8b --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-C @@ -0,0 +1,71 @@ +# -*-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 <<EOF; +all: ; \@echo This makefile did not clean the dir ... good +clean: ; $delete_command EXAMPLE\$(ext) +EOF +close(MAKEFILE); + +# TEST #1 +# ------- +&touch($example); + +&run_make_with_options("${testname}.mk", + "-C $workdir clean", + &get_logfile); + +chdir $workdir; +$wpath = &get_this_pwd; +chdir $pwd; + +if (-f $example) { + $test_passed = 0; +} + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: Entering directory '$wpath'\n" + . "$delete_command 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); + +chdir $workdir; +$wpath = &get_this_pwd; +chdir $pwd; + +if (-f $example) { + $test_passed = 0; +} + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: Entering directory '$wpath'\n" + . "$delete_command EXAMPLEslash\n" + . "$make_name: Leaving directory '$wpath'\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/src/kmk/tests/scripts/options/dash-I b/src/kmk/tests/scripts/options/dash-I new file mode 100644 index 0000000..d47a8d8 --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-I @@ -0,0 +1,59 @@ +# -*-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."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +$mf2 = substr ($makefile2, index ($makefile2, $pathsep) + 1); +print MAKEFILE <<EOF; +include $mf2 +all: +\t\@echo There should be no errors for this makefile. +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<EOF; +ANOTHER: +\t\@echo This is another included makefile +recurse: +\t\$(MAKE) ANOTHER -f $makefile +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile,"-I $workdir all",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "There should be no errors for this makefile.\n"; +&compare_output($answer,&get_logfile(1)); + + +$answer = "This is another included makefile\n"; +&run_make_with_options($makefile,"-I $workdir ANOTHER",&get_logfile); +&compare_output($answer,&get_logfile(1)); + + +$answer = "$mkpath ANOTHER -f $makefile +${make_name}[1]: Entering directory '$pwd' +This is another included makefile +${make_name}[1]: Leaving directory '$pwd'\n"; + +&run_make_with_options($makefile,"-I $workdir recurse",&get_logfile); +&compare_output($answer,&get_logfile(1)); diff --git a/src/kmk/tests/scripts/options/dash-W b/src/kmk/tests/scripts/options/dash-W new file mode 100644 index 0000000..857b1cc --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-W @@ -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: diff --git a/src/kmk/tests/scripts/options/dash-e b/src/kmk/tests/scripts/options/dash-e new file mode 100644 index 0000000..17c3fc8 --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-e @@ -0,0 +1,24 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to ..."; + +$details = ""; + +$extraENV{GOOGLE} = 'boggle'; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +GOOGLE = bazzle +all:; @echo "$(GOOGLE)" +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, '-e' ,&get_logfile); + +$answer = "boggle\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/src/kmk/tests/scripts/options/dash-f b/src/kmk/tests/scripts/options/dash-f new file mode 100644 index 0000000..3aa4746 --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-f @@ -0,0 +1,85 @@ +$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)); + + + + + + + + + + diff --git a/src/kmk/tests/scripts/options/dash-k b/src/kmk/tests/scripts/options/dash-k new file mode 100644 index 0000000..e2bb7c9 --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-k @@ -0,0 +1,114 @@ +# -*-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, "-j1 -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. + +run_make_test('all: ; @echo hi +include ifile +ifile: no-such-file; @false +', + '-k', + "#MAKEFILE#:2: ifile: No such file or directory +#MAKE#: *** No rule to make target 'no-such-file', needed by 'ifile'. +#MAKE#: Failed to remake makefile 'ifile'. +hi\n", + 512); + +1; diff --git a/src/kmk/tests/scripts/options/dash-l b/src/kmk/tests/scripts/options/dash-l new file mode 100644 index 0000000..0b0f196 --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-l @@ -0,0 +1,56 @@ +# -*-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."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOF'; +SHELL = /bin/sh + +define test +if [ ! -f test-file ]; then \ + echo >> test-file; sleep 2; rm -f test-file; \ +else \ + echo $@ FAILED; \ +fi +endef + +all : ONE TWO THREE +ONE : ; @$(test) +TWO : ; @$(test) +THREE : ; @$(test) +EOF + + +# END of Contents of MAKEFILE + +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/) { + &compare_output("", &get_logfile(1)); +} + +1; diff --git a/src/kmk/tests/scripts/options/dash-n b/src/kmk/tests/scripts/options/dash-n new file mode 100644 index 0000000..02ae4a9 --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-n @@ -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 = "$make_command -f \"$submake\" bar\ntouch inc\necho n --no-print-directory\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('inc'); + +1; diff --git a/src/kmk/tests/scripts/options/dash-q b/src/kmk/tests/scripts/options/dash-q new file mode 100644 index 0000000..e67b55d --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-q @@ -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; diff --git a/src/kmk/tests/scripts/options/dash-t b/src/kmk/tests/scripts/options/dash-t new file mode 100644 index 0000000..ec27d7a --- /dev/null +++ b/src/kmk/tests/scripts/options/dash-t @@ -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; diff --git a/src/kmk/tests/scripts/options/eval b/src/kmk/tests/scripts/options/eval new file mode 100644 index 0000000..0f82409 --- /dev/null +++ b/src/kmk/tests/scripts/options/eval @@ -0,0 +1,29 @@ +# -*-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! +BAR = bar +all: ; @echo all +recurse: ; @$(MAKE) -f #MAKEFILE# && echo recurse!, + '--eval=\$\(info\ eval\) FOO=\$\(BAR\)', "eval\nall"); + +# Make sure that --eval is handled correctly during recursion +run_make_test(undef, '--no-print-directory --eval=\$\(info\ eval\) recurse', + "eval\neval\nall\nrecurse"); + +# 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'); + +1; diff --git a/src/kmk/tests/scripts/options/general b/src/kmk/tests/scripts/options/general new file mode 100644 index 0000000..d35bb35 --- /dev/null +++ b/src/kmk/tests/scripts/options/general @@ -0,0 +1,35 @@ +# -*-perl-*- +$description = "Test generic option processing.\n"; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo 1foo: ; \@echo \$\@\n"; + +close(MAKEFILE); + +# TEST 0 + +&run_make_with_options($makefile, "-j 1foo", &get_logfile); +if (!$parallel_jobs) { + $answer = "$make_name: Parallel jobs (-j) are not supported on this platform.\n$make_name: Resetting to single job (-j1) mode.\n1foo\n"; +} +else { + $answer = "1foo\n"; +} + +# 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... :( + +# If I were always on UNIX, I could invoke it with 2>/dev/null, then +# just check the error code. + +&run_make_with_options($makefile, "-j1foo 2>/dev/null", &get_logfile, 512); +$answer = ""; +&compare_output($answer, &get_logfile(1)); + +1; diff --git a/src/kmk/tests/scripts/options/print-directory b/src/kmk/tests/scripts/options/print-directory new file mode 100644 index 0000000..db762b2 --- /dev/null +++ b/src/kmk/tests/scripts/options/print-directory @@ -0,0 +1,33 @@ +# -*-perl-*- + +$description = "Test the -w option to GNU make."; + +# Simple test without -w +run_make_test(q! +all: ; @echo hi +!, + "", "hi\n"); + +# Simple test with -w +run_make_test(undef, "-w", + "#MAKE#: Entering directory '#PWD#'\nhi\n#MAKE#: Leaving directory '#PWD#'\n"); + +# Test makefile rebuild to ensure no enter/leave +run_make_test(q! +include foo +all: ;@: +foo: ; touch foo +!, + "", "touch foo\n"); +unlink('foo'); + +# Test makefile rebuild with -w +run_make_test(q! +include foo +all: ;@: +foo: ; touch foo +!, + "-w", "#MAKE#: Entering directory '#PWD#'\ntouch foo\n#MAKE#: Leaving directory '#PWD#'\n"); +unlink('foo'); + +1; diff --git a/src/kmk/tests/scripts/options/symlinks b/src/kmk/tests/scripts/options/symlinks new file mode 100644 index 0000000..a1bfce0 --- /dev/null +++ b/src/kmk/tests/scripts/options/symlinks @@ -0,0 +1,68 @@ +# -*-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 + +# Apparently the Windows port of Perl reports that it does support symlinks +# (in that the symlink() function doesn't fail) but it really doesn't, so +# check for it explicitly. + +if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) { + # This test is N/A + -1; +} else { + + # Set up a symlink sym -> dep + # We'll make both dep and targ older than sym + $pwd =~ m%/([^/]+)$%; + $dirnm = $1; + &utouch(-10, 'dep'); + &utouch(-5, 'targ'); + symlink("../$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("../$dirname/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; +} diff --git a/src/kmk/tests/scripts/options/warn-undefined-variables b/src/kmk/tests/scripts/options/warn-undefined-variables new file mode 100644 index 0000000..ce15507 --- /dev/null +++ b/src/kmk/tests/scripts/options/warn-undefined-variables @@ -0,0 +1,25 @@ +# -*-perl-*- + +$description = "Test the --warn-undefined-variables option."; + +$details = "Verify that warnings are printed for referencing undefined variables."; + +# Without --warn-undefined-variables, nothing should happen +run_make_test(' +EMPTY = +EREF = $(EMPTY) +UREF = $(UNDEFINED) + +SEREF := $(EREF) +SUREF := $(UREF) + +all: ; @echo ref $(EREF) $(UREF)', + '', 'ref'); + +# With --warn-undefined-variables, it should warn me +run_make_test(undef, '--warn-undefined-variables', + "#MAKEFILE#:7: warning: undefined variable 'UNDEFINED' +#MAKEFILE#:9: warning: undefined variable 'UNDEFINED' +ref"); + +1; diff --git a/src/kmk/tests/scripts/targets/DEFAULT b/src/kmk/tests/scripts/targets/DEFAULT new file mode 100644 index 0000000..f3d5148 --- /dev/null +++ b/src/kmk/tests/scripts/targets/DEFAULT @@ -0,0 +1,53 @@ +$description = "The following test creates a makefile to override part\n" + ."of one Makefile with Another Makefile with the .DEFAULT\n" + ."rule."; + +$details = "This tests the use of the .DEFAULT special target to say that \n" + ."to remake any target that cannot be made fram the information\n" + ."in the containing makefile, make should look in another makefile\n" + ."This test gives this makefile the target bar which is not \n" + ."defined here but passes the target bar on to another makefile\n" + ."which does have the target bar defined.\n"; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo:\n"; +print MAKEFILE "\t\@echo Executing rule FOO\n\n"; +print MAKEFILE ".DEFAULT:\n"; +print MAKEFILE "\t\@\$(MAKE) -f $makefile2 \$\@ \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE "bar:\n"; +print MAKEFILE "\t\@echo Executing rule BAR\n\n"; + +close(MAKEFILE); + +&run_make_with_options($makefile,'bar',&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "${make_name}[1]: Entering directory '$pwd'\n" + . "Executing rule BAR\n" + . "${make_name}[1]: Leaving directory '$pwd'\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/src/kmk/tests/scripts/targets/DELETE_ON_ERROR b/src/kmk/tests/scripts/targets/DELETE_ON_ERROR new file mode 100644 index 0000000..f0d9f9b --- /dev/null +++ b/src/kmk/tests/scripts/targets/DELETE_ON_ERROR @@ -0,0 +1,22 @@ +#! -*-perl-*- + +$description = "Test the behaviour of the .DELETE_ON_ERROR target."; + +$details = ""; + +run_make_test(' +.DELETE_ON_ERROR: +all: ; exit 1 > $@ +', + '', "exit 1 > all\n#MAKE#: *** [#MAKEFILE#:3: all] Error 1\n#MAKE#: *** Deleting file 'all'", 512); + +run_make_test(' +.DELETE_ON_ERROR: +all: foo.x ; +%.x : %.q ; echo > $@ +%.q : ; exit 1 > $@ +', + '', "exit 1 > foo.q\n#MAKE#: *** [#MAKEFILE#:5: foo.q] Error 1\n#MAKE#: *** Deleting file 'foo.q'", 512); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/targets/FORCE b/src/kmk/tests/scripts/targets/FORCE new file mode 100644 index 0000000..eb8f251 --- /dev/null +++ b/src/kmk/tests/scripts/targets/FORCE @@ -0,0 +1,40 @@ +# -*-perl-*- + +$description = "The following tests rules without Commands or Dependencies."; + +$details = "If the rule ...\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".IGNORE :\n"; +print MAKEFILE "clean: FORCE\n"; +print MAKEFILE "\t$delete_command clean\n"; +print MAKEFILE "FORCE:\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +# Create a file named "clean". This is the same name as the target clean +# and tricks the target into thinking that it is up to date. (Unless you +# use the .PHONY target. +&touch("clean"); + +$answer = "$delete_command clean\n"; +&run_make_with_options($makefile,"clean",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/src/kmk/tests/scripts/targets/INTERMEDIATE b/src/kmk/tests/scripts/targets/INTERMEDIATE new file mode 100644 index 0000000..e2f08bf --- /dev/null +++ b/src/kmk/tests/scripts/targets/INTERMEDIATE @@ -0,0 +1,112 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .INTERMEDIATE target."; + +$details = "\ +Test the behavior of the .INTERMEDIATE special target. +Create a makefile where a file would not normally be considered +intermediate, then specify it as .INTERMEDIATE. Build and ensure it's +deleted properly. Rebuild to ensure that it's not created if it doesn't +exist but doesn't need to be built. Change the original and ensure +that the intermediate file and the ultimate target are both rebuilt, and +that the intermediate file is again deleted. + +Try this with implicit rules and explicit rules: both should work.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +.INTERMEDIATE: foo.e bar.e + +# Implicit rule test +%.d : %.e ; cp $< $@ +%.e : %.f ; cp $< $@ + +foo.d: foo.e + +# Explicit rule test +foo.c: foo.e bar.e; cat $^ > $@ +EOF + +close(MAKEFILE); + +# TEST #0 + +&utouch(-20, 'foo.f', 'bar.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #1 + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "$make_name: 'foo.d' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 + +&utouch(-10, 'foo.d'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 +# kmk+fast: differs because of different hashing. + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\n" + . (!$is_kmk && !$is_fast ? "rm bar.e foo.e\n" : "rm foo.e bar.e\n"); +&compare_output($answer, &get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "$make_name: 'foo.c' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #5 +# kmk+fast: differs because of different hashing. + +&utouch(-10, 'foo.c'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\n" + . (!$is_kmk && !$is_fast ? "rm bar.e foo.e\n" : "rm foo.e bar.e\n"); +&compare_output($answer, &get_logfile(1)); + +# TEST #6 -- added for PR/1669: don't remove files mentioned on the cmd line. + +&run_make_with_options($makefile,'foo.e',&get_logfile); +$answer = "cp foo.f foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo.f', 'foo.e', 'foo.d', 'foo.c', 'bar.f', 'bar.e', 'bar.d', 'bar.c'); + +# TEST #7 -- added for PR/1423 + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); + +print MAKEFILE <<'EOF'; +all: foo +foo.a: ; touch $@ +%: %.a ; touch $@ +.INTERMEDIATE: foo.a +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, '-R', &get_logfile); +$answer = "touch foo.a\ntouch foo\nrm foo.a\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/targets/ONESHELL b/src/kmk/tests/scripts/targets/ONESHELL new file mode 100644 index 0000000..87713da --- /dev/null +++ b/src/kmk/tests/scripts/targets/ONESHELL @@ -0,0 +1,88 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .ONESHELL target."; + +$details = ""; + +# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in +# separate arguments. +my $t = `/bin/sh -e -c true 2>/dev/null`; +my $multi_ok = $? == 0; + +# Simple + +run_make_test(q! +.ONESHELL: +all: + a=$$$$ + [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', 'a=$$ +[ 0"$a" -eq "$$" ] || echo fail +'); + +# Simple but use multi-word SHELLFLAGS + +if ($multi_ok) { + run_make_test(q! +.ONESHELL: +.SHELLFLAGS = -e -c +all: + a=$$$$ + [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', 'a=$$ +[ 0"$a" -eq "$$" ] || echo fail +'); +} + +# Again, but this time with inner prefix chars + +run_make_test(q! +.ONESHELL: +all: + a=$$$$ + @-+ [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', 'a=$$ +[ 0"$a" -eq "$$" ] || echo fail +'); + +# This time with outer prefix chars + +run_make_test(q! +.ONESHELL: +all: + @a=$$$$ + [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', ''); + + +# This time with outer and inner prefix chars + +run_make_test(q! +.ONESHELL: +all: + @a=$$$$ + -@ +[ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', ''); + + +# Now try using a different interpreter + +run_make_test(q! +.RECIPEPREFIX = > +.ONESHELL: +SHELL = #PERL# +.SHELLFLAGS = -e +all: +> @$$a=5 +> +7; +> @y=qw(a b c); +>print "a = $$a, y = (@y)\n"; +!, + '', "a = 12, y = (a b c)\n"); + +1; diff --git a/src/kmk/tests/scripts/targets/PHONY b/src/kmk/tests/scripts/targets/PHONY new file mode 100644 index 0000000..c8e2110 --- /dev/null +++ b/src/kmk/tests/scripts/targets/PHONY @@ -0,0 +1,54 @@ +# -*-perl-*- + +$description = "The following tests the use of a PHONY target. It makes\n" + ."sure that the rules under a target get executed even if\n" + ."a filename of the same name of the target exists in the\n" + ."directory.\n"; + +$details = "This makefile in this test declares the target clean to be a \n" + ."PHONY target. We then create a file named \"clean\" in the \n" + ."directory. Although this file exists, the rule under the target\n" + ."clean should still execute because of it's phony status."; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".PHONY : clean \n"; +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command $example clean\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +# Create a file named "clean". This is the same name as the target clean +# and tricks the target into thinking that it is up to date. (Unless you +# use the .PHONY target. +&touch("clean"); + +$answer = "$delete_command $example clean\n"; +&run_make_with_options($makefile,"clean",&get_logfile); + +if (-f $example) { + $test_passed = 0; +} + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/src/kmk/tests/scripts/targets/POSIX b/src/kmk/tests/scripts/targets/POSIX new file mode 100644 index 0000000..5c3c7f8 --- /dev/null +++ b/src/kmk/tests/scripts/targets/POSIX @@ -0,0 +1,56 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .POSIX target."; + +$details = ""; + + +# Ensure turning on .POSIX enables the -e flag for the shell +# We can't assume the exit value of "false" because on different systems it's +# different. + +my $script = 'false; true'; +my $flags = '-ec'; +my $out = `/bin/sh $flags '$script' 2>&1`; +my $err = $? >> 8; +run_make_test(qq! +.POSIX: +all: ; \@$script +!, + '', "#MAKE#: *** [#MAKEFILE#:3: all] Error $err\n", 512); + +# User settings must override .POSIX +$flags = '-xc'; +$out = `/bin/sh $flags '$script' 2>&1`; +run_make_test(qq! +.SHELLFLAGS = $flags +.POSIX: +all: ; \@$script +!, + '', $out); + +# Test the default value of various POSIX-specific variables +my %POSIX = (AR => 'ar', ARFLAGS => '-rv', + YACC => 'yacc', YFLAGS => '', + LEX => 'lex', LFLAGS => '', + LDFLAGS => '', + CC => 'c99', CFLAGS => '-O', + FC => 'fort77', FFLAGS => '-O 1', + GET => 'get', GFLAGS => '', + SCCSFLAGS => '', SCCSGETFLAGS => '-s'); +my $make = join('', map { "\t\@echo '$_=\$($_)'\n" } sort keys %POSIX); +my $r = join('', map { "$_=$POSIX{$_}\n"} sort keys %POSIX); +run_make_test(qq! +.POSIX: +all: +$make +!, + '', $r); + +# Make sure that local settings take precedence +%extraENV = map { $_ => "xx-$_" } keys %POSIX; +$r = join('', map { "$_=xx-$_\n"} sort keys %POSIX); +run_make_test(undef, '', $r); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/targets/SECONDARY b/src/kmk/tests/scripts/targets/SECONDARY new file mode 100644 index 0000000..447c275 --- /dev/null +++ b/src/kmk/tests/scripts/targets/SECONDARY @@ -0,0 +1,190 @@ +#! -*-perl-*- + +$description = "Test the behaviour of the .SECONDARY target."; + +$details = "\ +Test the behavior of the .SECONDARY special target. +Create a makefile where a file would not normally be considered +intermediate, then specify it as .SECONDARY. Build and note that it's +not automatically deleted. Delete the file. Rebuild to ensure that +it's not created if it doesn't exist but doesn't need to be built. +Change the original and ensure that the secondary file and the ultimate +target are both rebuilt, and that the secondary file is not deleted. + +Try this with implicit rules and explicit rules: both should work.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +.SECONDARY: foo.e + +# Implicit rule test +%.d : %.e ; cp $< $@ +%.e : %.f ; cp $< $@ + +foo.d: foo.e + +# Explicit rule test +foo.c: foo.e ; cp $< $@ +EOF + +close(MAKEFILE); + +# TEST #1 + +&utouch(-20, 'foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 + +unlink('foo.e'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "$make_name: 'foo.d' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 + +&utouch(-10, 'foo.d'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.e foo.c\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #5 + +unlink('foo.e'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "$make_name: 'foo.c' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #6 + +&utouch(-10, 'foo.c'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.c\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo.f', 'foo.e', 'foo.d', 'foo.c'); + +# TEST #7 -- test the "global" .SECONDARY, with no targets. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); + +print MAKEFILE <<'EOF'; +.SECONDARY: + +final: intermediate +intermediate: source + +final intermediate source: + echo $< > $@ +EOF + +close(MAKEFILE); + +&utouch(-10, 'source'); +touch('final'); + +&run_make_with_options($makefile2, '', &get_logfile); +$answer = "$make_name: 'final' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('source', 'final', 'intermediate'); + + +# TEST #8 -- test the "global" .SECONDARY, with .PHONY. + +touch('version2'); +run_make_test(' +.PHONY: version +.SECONDARY: +version2: version ; @echo GOOD +all: version2', + 'all', 'GOOD'); + +unlink('version2'); + +# TEST #9 -- Savannah bug #15919 +# The original fix for this bug caused a new bug, shown here. + +touch(qw(1.a 2.a)); + +run_make_test(' +%.c : %.b ; cp $< $@ +%.b : %.a ; cp $< $@ +all : 1.c 2.c +2.a: 1.c', '-rR -j', +'cp 1.a 1.b +cp 1.b 1.c +cp 2.a 2.b +cp 2.b 2.c +rm 1.b 2.b'); + +unlink(qw(1.a 2.a 1.c 2.c)); + +# TEST #10 -- Savannah bug #15919 +touch('test.0'); +run_make_test(' +.SECONDARY : test.1 test.2 test.3 + +test : test.4 + +%.4 : %.int %.3 ; touch $@ + +%.int : %.3 %.2 ; touch $@ + +%.3 : | %.2 ; touch $@ + +%.2 : %.1 ; touch $@ + +%.1 : %.0 ; touch $@', '-rR -j 2', +'touch test.1 +touch test.2 +touch test.3 +touch test.int +touch test.4 +rm test.int'); + +# After a touch of test.0 it should give the same output, except we don't need +# to rebuild test.3 (order-only) +sleep(1); +touch('test.0'); +run_make_test(undef, '-rR -j 2', +'touch test.1 +touch test.2 +touch test.int +touch test.4 +rm test.int'); + +# With both test.0 and test.3 updated it should still build everything except +# test.3 +sleep(1); +touch('test.0', 'test.3'); +run_make_test(undef, '-rR -j 2', +'touch test.1 +touch test.2 +touch test.int +touch test.4 +rm test.int'); + +unlink(qw(test.0 test.1 test.2 test.3 test.4)); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/targets/SILENT b/src/kmk/tests/scripts/targets/SILENT new file mode 100644 index 0000000..4bb0a0f --- /dev/null +++ b/src/kmk/tests/scripts/targets/SILENT @@ -0,0 +1,42 @@ +# -*-perl-*- + +$description = "The following tests the special target .SILENT. By simply\n" + ."mentioning this as a target, it tells make not to print\n" + ."commands before executing them."; + +$details = "This test is the same as the clean test except that it should\n" + ."not echo its command before deleting the specified file.\n"; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".SILENT : clean\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +$answer = ""; +&run_make_with_options($makefile,"clean",&get_logfile,0); +if (-f $example) { + $test_passed = 0; +} +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/src/kmk/tests/scripts/targets/clean b/src/kmk/tests/scripts/targets/clean new file mode 100644 index 0000000..b32c976 --- /dev/null +++ b/src/kmk/tests/scripts/targets/clean @@ -0,0 +1,50 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to delete a \n" + ."file in the directory. It tests to see if make will \n" + ."NOT execute the command unless the rule is given in \n" + ."the make command line."; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "This makefile did not clean the dir... good\n"; + +&compare_output($answer,&get_logfile(1)) || &error ("abort"); + + +$answer = "$delete_command $example\n"; +&run_make_with_options($makefile,"clean",&get_logfile,0); +if (-f $example) { + $test_passed = 0; +} +&compare_output($answer,&get_logfile(1)) || &error ("abort"); + +1; + + + + + + + + + diff --git a/src/kmk/tests/scripts/test_template b/src/kmk/tests/scripts/test_template new file mode 100644 index 0000000..3fd3f95 --- /dev/null +++ b/src/kmk/tests/scripts/test_template @@ -0,0 +1,29 @@ +# -*-perl-*- + +$description = "<FILL IN SHORT DESCRIPTION HERE>"; +$details = "<FILL IN DETAILS OF HOW YOU TEST WHAT YOU SAY YOU ARE TESTING>"; + +# Run a make test. See the documentation of run_make_test() in +# run_make_tests.pl, but briefly the first argument is a string with the +# contents of a makefile to be tested, the second is a string containing the +# arguments to be passed to the make invocation, the third is a string +# containing the expected output. The fourth is the expected exit code for +# make. If not specified, it's assumed that the make program should succeed +# (exit with 0). + +run_make_test('Your test makefile goes here', + 'Arguments to pass to make go here', + 'Expected output from the invocation goes here'); + +# There are various special tokens, options, etc. See the full documentation +# in run_make_tests.pl. + + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/src/kmk/tests/scripts/variables/CURDIR b/src/kmk/tests/scripts/variables/CURDIR new file mode 100644 index 0000000..ee7cacb --- /dev/null +++ b/src/kmk/tests/scripts/variables/CURDIR @@ -0,0 +1,20 @@ +# -*-perl-*- + +$description = "This tests the CURDIR varaible."; + +$details = "Echo CURDIR both with and without -C. Also ensure overrides work."; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "all: ; \@echo \$(CURDIR)\n"; +close(MAKEFILE); + + +# TEST #1 +# ------- + +&run_make_with_options($makefile,"",&get_logfile); +$answer = "$pwd\n"; +&compare_output($answer,&get_logfile(1)); + + +1; diff --git a/src/kmk/tests/scripts/variables/DEFAULT_GOAL b/src/kmk/tests/scripts/variables/DEFAULT_GOAL new file mode 100644 index 0000000..8188ce7 --- /dev/null +++ b/src/kmk/tests/scripts/variables/DEFAULT_GOAL @@ -0,0 +1,87 @@ +# -*-perl-*- +$description = "Test the .DEFAULT_GOAL special variable."; + +$details = ""; + + +# Test #1: basic logic. +# +run_make_test(' +# Basics. +# +foo: ; @: + +ifneq ($(.DEFAULT_GOAL),foo) +$(error ) +endif + +# Reset to empty. +# +.DEFAULT_GOAL := + +bar: ; @: + +ifneq ($(.DEFAULT_GOAL),bar) +$(error ) +endif + +# Change to a different goal. +# + +.DEFAULT_GOAL := baz + +baz: ; @echo $@ +', +'', +'baz'); + + +# Test #2: unknown goal. +# +run_make_test(' +.DEFAULT_GOAL = foo +', +'', +"#MAKE#: *** No rule to make target 'foo'. Stop.", +512); + + +# Test #3: more than one goal. +# +run_make_test(' +.DEFAULT_GOAL := foo bar +', +'', +'#MAKE#: *** .DEFAULT_GOAL contains more than one target. Stop.', +512); + + +# Test #4: Savannah bug #12226. +# +run_make_test(' +define rule +foo: ; @echo $$@ +endef + +define make-rule +$(eval $(rule)) +endef + +$(call make-rule) + +', +'', +'foo'); + +# TEST #5: .DEFAULT_GOAL containing just whitespace (Savannah bug #25697) + +run_make_test(' +N = +.DEFAULT_GOAL = $N $N # Just whitespace + +foo: ; @echo "boo" +', + '', "#MAKE#: *** No targets. Stop.\n", 512); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/variables/GNUMAKEFLAGS b/src/kmk/tests/scripts/variables/GNUMAKEFLAGS new file mode 100644 index 0000000..6e50794 --- /dev/null +++ b/src/kmk/tests/scripts/variables/GNUMAKEFLAGS @@ -0,0 +1,42 @@ +# -*-perl-*- + +$description = "Test proper behavior of GNUMAKEFLAGS"; + +# Accept flags from GNUMAKEFLAGS as well as MAKEFLAGS +# Results always go in MAKEFLAGS + +$extraENV{'GNUMAKEFLAGS'} = '-e -r -R'; + +run_make_test(q! +all: ; @echo $(MAKEFLAGS) +!, + '', 'erR'); + +# Long arguments mean everything is prefixed with "-" + +$extraENV{'GNUMAKEFLAGS'} = '--no-print-directory -e -r -R --trace'; + +run_make_test(q! +all: ; @echo $(MAKEFLAGS) +!, + '', "#MAKEFILE#:2: target 'all' does not exist +echo erR --trace --no-print-directory +erR --trace --no-print-directory"); + +# Verify that re-exec / recursion doesn't duplicate flags from GNUMAKEFLAGS + +unlink('x.mk'); + +$extraENV{GNUMAKEFLAGS} = '-Itst/bad'; + +run_make_test(q! +recurse: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS; #MAKEPATH# -f #MAKEFILE# all +all: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS +-include x.mk +x.mk: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS; echo > $@ +!, + "", "x.mk\nMAKEFLAGS = -Itst/bad\nGNUMAKEFLAGS =\nrecurse\nMAKEFLAGS = -Itst/bad\nGNUMAKEFLAGS =\n#MAKE#[1]: Entering directory '#PWD#'\nall\nMAKEFLAGS = w -Itst/bad\nGNUMAKEFLAGS =\n#MAKE#[1]: Leaving directory '#PWD#'\n"); + +unlink('x.mk'); + +1; diff --git a/src/kmk/tests/scripts/variables/INCLUDE_DIRS b/src/kmk/tests/scripts/variables/INCLUDE_DIRS new file mode 100644 index 0000000..c9662e9 --- /dev/null +++ b/src/kmk/tests/scripts/variables/INCLUDE_DIRS @@ -0,0 +1,46 @@ +# -*-perl-*- +$description = "Test the .INCLUDE_DIRS special variable."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + +# Test #1: The content of .INCLUDE_DIRS depends on the platform for which +# make was built. What we know for sure is that it shouldn't be +# empty. +# +run_make_test(' +ifeq ($(.INCLUDE_DIRS),) +$(warning .INCLUDE_DIRS is empty) +endif + +.PHONY: all +all:;@: +', +'', +''); + + +# Test #2: Make sure -I paths end up in .INCLUDE_DIRS. +# +run_make_test(' +ifeq ($(dir),) +$(warning dir is empty) +endif + +ifeq ($(filter $(dir),$(.INCLUDE_DIRS)),) +$(warning .INCLUDE_DIRS does not contain $(dir)) +endif + +.PHONY: all +all:;@: +', +"-I$dir dir=$dir", +''); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/src/kmk/tests/scripts/variables/LIBPATTERNS b/src/kmk/tests/scripts/variables/LIBPATTERNS new file mode 100644 index 0000000..9182954 --- /dev/null +++ b/src/kmk/tests/scripts/variables/LIBPATTERNS @@ -0,0 +1,38 @@ +# -*-perl-*- + +$description = "Test .LIBPATTERNS special variable."; + +$details = ""; + +# TEST 0: basics + +touch('mtest_foo.a'); + +run_make_test(' +.LIBPATTERNS = mtest_%.a +all: -lfoo ; @echo "build $@ from $<" +', + '', "build all from mtest_foo.a\n"); + +# TEST 1: Handle elements that are not patterns. + +run_make_test(' +.LIBPATTERNS = mtest_foo.a mtest_%.a +all: -lfoo ; @echo "build $@ from $<" +', + '', "#MAKE#: .LIBPATTERNS element 'mtest_foo.a' is not a pattern +build all from mtest_foo.a\n"); + +# TEST 2: target-specific override + +# Uncomment this when we add support, see Savannah bug #25703 +# run_make_test(' +# .LIBPATTERNS = mbad_%.a +# all: .LIBPATTERNS += mtest_%.a +# all: -lfoo ; @echo "build $@ from $<" +# ', +# '', "build all from mtest_foo.a\n"); + +unlink('mtest_foo.a'); + +1; diff --git a/src/kmk/tests/scripts/variables/MAKE b/src/kmk/tests/scripts/variables/MAKE new file mode 100644 index 0000000..dc62160 --- /dev/null +++ b/src/kmk/tests/scripts/variables/MAKE @@ -0,0 +1,24 @@ +# -*-perl-*- + +$description = "Test proper behavior of the MAKE variable"; + +$details = "DETAILS"; + +run_make_test(q! +TMP := $(MAKE) +MAKE := $(subst X=$(X),,$(MAKE)) +all: + @echo $(TMP) + $(MAKE) -f #MAKEFILE# foo + +foo: + @echo $(MAKE) +!, + '', + "#MAKEPATH#\n#MAKEPATH# -f #MAKEFILE# foo\n" + . "#MAKE#[1]: Entering directory '#PWD#'\n" + . "#MAKEPATH#\n#MAKE#[1]: Leaving directory '#PWD#'\n"); + +rmfiles("foo"); + +1; diff --git a/src/kmk/tests/scripts/variables/MAKECMDGOALS b/src/kmk/tests/scripts/variables/MAKECMDGOALS new file mode 100644 index 0000000..879283b --- /dev/null +++ b/src/kmk/tests/scripts/variables/MAKECMDGOALS @@ -0,0 +1,52 @@ +# -*-perl-*- + +$description = "Test the MAKECMDGOALS variable."; + +$details = "\ +We construct a makefile with various targets, all of which print out +\$(MAKECMDGOALS), then call it different ways."; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "\ +.DEFAULT all: + \@echo \$(MAKECMDGOALS) +"; +close(MAKEFILE); + +# TEST #1 + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); +$answer = "\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #2 + +&run_make_with_options($makefile, + "all", + &get_logfile, + 0); +$answer = "all\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 + +&run_make_with_options($makefile, + "foo bar baz yaz", + &get_logfile, + 0); +$answer = "foo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\n"; +&compare_output($answer,&get_logfile(1)); + + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/src/kmk/tests/scripts/variables/MAKEFILES b/src/kmk/tests/scripts/variables/MAKEFILES new file mode 100644 index 0000000..b23da8e --- /dev/null +++ b/src/kmk/tests/scripts/variables/MAKEFILES @@ -0,0 +1,53 @@ +# -*-perl-*- + +$description = "Test the MAKEFILES variable."; + +$makefile2 = &get_tmpfile; +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE 'all: ; @echo DEFAULT RULE: M2=$(M2) M3=$(M3)', "\n"; +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); +print MAKEFILE <<EOF; +M2 = m2 +NDEF: ; \@echo RULE FROM MAKEFILE 2 +EOF +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile3"); +print MAKEFILE <<EOF; +M3 = m3 +NDEF3: ; \@echo RULE FROM MAKEFILE 3 +EOF +close(MAKEFILE); + + +&run_make_with_options($makefile, "MAKEFILES='$makefile2 $makefile3'", + &get_logfile); +$answer = "DEFAULT RULE: M2=m2 M3=m3\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST 2: Verify that included makefiles don't set the default goal. +# See Savannah bug #13401. + +create_file('xx-inc.mk', ' +include_goal: ; @echo $@ +include xx-ind.mk +'); + +create_file('xx-ind.mk', ' +indirect_goal: ; @echo $@ +'); + +run_make_test(q! +top: ; @echo $@ +!, + 'MAKEFILES=xx-inc.mk', "top\n"); + +unlink(qw(xx-inc.mk xx-ind.mk)); + +1; diff --git a/src/kmk/tests/scripts/variables/MAKEFILE_LIST b/src/kmk/tests/scripts/variables/MAKEFILE_LIST new file mode 100644 index 0000000..076e42d --- /dev/null +++ b/src/kmk/tests/scripts/variables/MAKEFILE_LIST @@ -0,0 +1,30 @@ +# -*-perl-*- + +$description = "Test the MAKEFILE_LIST variable."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<EOF; +m1 := \$(MAKEFILE_LIST) +include $makefile2 +m3 := \$(MAKEFILE_LIST) + +all: +\t\@echo \$(m1) +\t\@echo \$(m2) +\t\@echo \$(m3) +EOF +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); +print MAKEFILE "m2 := \$(MAKEFILE_LIST)\n"; +close(MAKEFILE); + + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "$makefile\n$makefile $makefile2\n$makefile $makefile2\n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/src/kmk/tests/scripts/variables/MAKEFLAGS b/src/kmk/tests/scripts/variables/MAKEFLAGS new file mode 100644 index 0000000..0fac74a --- /dev/null +++ b/src/kmk/tests/scripts/variables/MAKEFLAGS @@ -0,0 +1,45 @@ +# -*-perl-*- + +$description = "Test proper behavior of MAKEFLAGS"; + +$details = "DETAILS"; + +# Normal flags aren't prefixed with "-" +run_make_test(q! +all: ; @echo $(MAKEFLAGS) +!, + '-e -r -R', 'erR'); + +# Long arguments mean everything is prefixed with "-" +run_make_test(q! +all: ; @echo $(MAKEFLAGS) +!, + '--no-print-directory -e -r -R --trace', "#MAKEFILE#:2: target 'all' does not exist +echo erR --trace --no-print-directory +erR --trace --no-print-directory"); + + +# Recursive invocations of make should accumulate MAKEFLAGS values. +# Savannah bug #2216 +run_make_test(q! +MSG = Fails +all: + @echo '$@: MAKEFLAGS=$(MAKEFLAGS)' + @MSG=Works $(MAKE) -e -f #MAKEFILE# jump +jump: + @echo '$@ $(MSG): MAKEFLAGS=$(MAKEFLAGS)' + @$(MAKE) -f #MAKEFILE# print +print: + @echo '$@ $(MSG): MAKEFLAGS=$(MAKEFLAGS)' +.PHONY: all jump print +!, + '--no-print-directory', + 'all: MAKEFLAGS= --no-print-directory +jump Works: MAKEFLAGS=e --no-print-directory +print Works: MAKEFLAGS=e --no-print-directory'); + +1; + +### Local Variables: +### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) +### End: diff --git a/src/kmk/tests/scripts/variables/MAKELEVEL b/src/kmk/tests/scripts/variables/MAKELEVEL new file mode 100644 index 0000000..0db3a68 --- /dev/null +++ b/src/kmk/tests/scripts/variables/MAKELEVEL @@ -0,0 +1,45 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test +makelevels in Make. It prints \$(MAKELEVEL) and then +prints the environment variable MAKELEVEL"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +if (!$is_kmk) { + print MAKEFILE <<EOF; +all: +\t\@echo MAKELEVEL is \$(MAKELEVEL) +\techo \$\$MAKELEVEL +EOF +} else { + print MAKEFILE <<EOF; +all: +\t\@echo KMK_LEVEL is \$(KMK_LEVEL) +\techo \$\$KMK_LEVEL +EOF +} + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# RUN MAKE + +&run_make_with_options($makefile,"",&get_logfile); + +# SET ANSWER + +if (!$is_kmk) { + $answer = "MAKELEVEL is 0\necho \$MAKELEVEL\n1\n"; +} else { + $answer = "KMK_LEVEL is 0\necho \$KMK_LEVEL\n1\n"; +} + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/src/kmk/tests/scripts/variables/MAKE_RESTARTS b/src/kmk/tests/scripts/variables/MAKE_RESTARTS new file mode 100644 index 0000000..01bf55e --- /dev/null +++ b/src/kmk/tests/scripts/variables/MAKE_RESTARTS @@ -0,0 +1,61 @@ +# -*-perl-*- + +$description = "Test the MAKE_RESTARTS variable."; + +# Test basic capability + +run_make_test(' +all: ; @: +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @touch $@ +', + '', 'MAKE_RESTARTS= +MAKE_RESTARTS=1'); + +rmfiles('foo.x'); + +# Test multiple restarts + +run_make_test(' +all: ; @: +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @echo "include bar.x" > $@ +bar.x: ; @touch $@ +', + '', 'MAKE_RESTARTS= +MAKE_RESTARTS=1 +MAKE_RESTARTS=2'); + +rmfiles('foo.x', 'bar.x'); + +# Test multiple restarts and make sure the variable is cleaned up + +run_make_test(' +recurse: + @echo recurse MAKE_RESTARTS=$$MAKE_RESTARTS + @$(MAKE) -f #MAKEFILE# all +all: + @echo all MAKE_RESTARTS=$$MAKE_RESTARTS +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @echo "include bar.x" > $@ +bar.x: ; @touch $@ +', + '', "MAKE_RESTARTS= +MAKE_RESTARTS=1 +MAKE_RESTARTS=2 +recurse MAKE_RESTARTS= +#MAKE#[1]: Entering directory '#PWD#' +MAKE_RESTARTS= +all MAKE_RESTARTS= +#MAKE#[1]: Leaving directory '#PWD#'"); + +rmfiles('foo.x', 'bar.x'); + +1; + +### Local Variables: +### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) +### End: diff --git a/src/kmk/tests/scripts/variables/MFILE_LIST b/src/kmk/tests/scripts/variables/MFILE_LIST new file mode 100644 index 0000000..076e42d --- /dev/null +++ b/src/kmk/tests/scripts/variables/MFILE_LIST @@ -0,0 +1,30 @@ +# -*-perl-*- + +$description = "Test the MAKEFILE_LIST variable."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<EOF; +m1 := \$(MAKEFILE_LIST) +include $makefile2 +m3 := \$(MAKEFILE_LIST) + +all: +\t\@echo \$(m1) +\t\@echo \$(m2) +\t\@echo \$(m3) +EOF +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); +print MAKEFILE "m2 := \$(MAKEFILE_LIST)\n"; +close(MAKEFILE); + + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "$makefile\n$makefile $makefile2\n$makefile $makefile2\n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/src/kmk/tests/scripts/variables/SHELL b/src/kmk/tests/scripts/variables/SHELL new file mode 100644 index 0000000..9d56796 --- /dev/null +++ b/src/kmk/tests/scripts/variables/SHELL @@ -0,0 +1,103 @@ +# -*-perl-*- + +$description = "Test proper handling of SHELL."; + +# Find the default value when SHELL is not set. On UNIX it will be /bin/sh, +# but on other platforms who knows? +resetENV(); +delete $ENV{SHELL}; +$mshell = `echo 'all:;\@echo \$(SHELL)' | $make_path -f-`; +chop $mshell; + +# According to POSIX, the value of SHELL in the environment has no impact on +# the value in the makefile. +# Note %extraENV takes precedence over the default value for the shell. + +$extraENV{SHELL} = '/dev/null'; +run_make_test('all:;@echo "$(SHELL)"', '', $mshell); + +# According to POSIX, any value of SHELL set in the makefile should _NOT_ be +# exported to the subshell! I wanted to set SHELL to be $^X (perl) in the +# makefile, but make runs $(SHELL) -c 'commandline' and that doesn't work at +# all when $(SHELL) is perl :-/. So, we just add an extra initial /./ which +# works well on UNIX and seems to work OK on at least some non-UNIX systems. + +$extraENV{SHELL} = $mshell; + +run_make_test("SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell $mshell"); + +# As a GNU make extension, if make's SHELL variable is explicitly exported, +# then we really _DO_ export it. + +$extraENV{SHELL} = $mshell; + +run_make_test("export SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell /./$mshell"); + + +# Test out setting of SHELL, both exported and not, as a target-specific +# variable. + +$extraENV{SHELL} = $mshell; + +run_make_test("all: SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell $mshell"); + +$extraENV{SHELL} = $mshell; + +# bird: This was wrong at some point, see Savannah bug #24655. Was first fixed in kBuild. +run_make_test(" +SHELL := /././$mshell +one: two +two: export SHELL := /./$mshell\n".' +one two:;@echo "$@: $(SHELL) $$SHELL" +', '', "two: /./$mshell /./$mshell\none: /././$mshell $mshell\n"); + +# Test .SHELLFLAGS + +# We don't know the output here: on Solaris for example, every line printed +# by the shell in -x mode has a trailing space (!!) +my $script = 'true; true'; +my $flags = '-xc'; +my $out = `/bin/sh $flags '$script' 2>&1`; + +run_make_test(qq! +.SHELLFLAGS = $flags +all: ; \@$script +!, + '', $out); + +# Do it again but add spaces to SHELLFLAGS + +# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in +# separate arguments. +my $t = `/bin/sh -e -c true 2>/dev/null`; +my $multi_ok = $? == 0; + +if ($multi_ok) { + $flags = '-x -c'; + run_make_test(qq! +.SHELLFLAGS = $flags +all: ; \@$script +!, + '', $out); +} + +# We can't just use "false" because on different systems it provides a +# different exit code--once again Solaris: false exits with 255 not 1 +$script = 'true; false; true'; +$flags = '-xec'; +$out = `/bin/sh $flags '$script' 2>&1`; +my $err = $? >> 8; + +run_make_test(qq! +.SHELLFLAGS = $flags +all: ; \@$script +!, + '', "$out#MAKE#: *** [#MAKEFILE#:3: all] Error $err\n", 512); + +1; diff --git a/src/kmk/tests/scripts/variables/automatic b/src/kmk/tests/scripts/variables/automatic new file mode 100644 index 0000000..2304fa0 --- /dev/null +++ b/src/kmk/tests/scripts/variables/automatic @@ -0,0 +1,122 @@ +# -*-perl-*- + +$description = "Test automatic variable setting."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + +open(MAKEFILE, "> $makefile"); +print MAKEFILE "dir = $dir\n"; +print MAKEFILE <<'EOF'; +.SUFFIXES: +.SUFFIXES: .x .y .z +$(dir)/foo.x : baz.z $(dir)/bar.y baz.z + @echo '$$@ = $@, $$(@D) = $(@D), $$(@F) = $(@F)' + @echo '$$* = $*, $$(*D) = $(*D), $$(*F) = $(*F)' + @echo '$$< = $<, $$(<D) = $(<D), $$(<F) = $(<F)' + @echo '$$^ = $^, $$(^D) = $(^D), $$(^F) = $(^F)' + @echo '$$+ = $+, $$(+D) = $(+D), $$(+F) = $(+F)' + @echo '$$? = $?, $$(?D) = $(?D), $$(?F) = $(?F)' + touch $@ + +$(dir)/bar.y baz.z : ; touch $@ +EOF +close(MAKEFILE); + +# TEST #0 -- simple test +# ------- + +# Touch these into the past +&utouch(-10, qw(foo.x baz.z)); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "touch $dir/bar.y +\$\@ = $dir/foo.x, \$(\@D) = $dir, \$(\@F) = foo.x +\$* = $dir/foo, \$(*D) = $dir, \$(*F) = foo +\$< = baz.z, \$(<D) = ., \$(<F) = baz.z +\$^ = baz.z $dir/bar.y, \$(^D) = . $dir, \$(^F) = baz.z bar.y +\$+ = baz.z $dir/bar.y baz.z, \$(+D) = . $dir ., \$(+F) = baz.z bar.y baz.z +\$? = $dir/bar.y, \$(?D) = $dir, \$(?F) = bar.y +touch $dir/foo.x\n"; +&compare_output($answer, &get_logfile(1)); + +unlink(qw(foo.x bar.y baz.z)); + +# TEST #1 -- test the SysV emulation of $$@ etc. +# ------- + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE "dir = $dir\n"; +print MAKEFILE <<'EOF'; +.SECONDEXPANSION: +.SUFFIXES: +.DEFAULT: ; @echo '$@' + +$(dir)/foo $(dir)/bar: $@.x $$@.x $$$@.x $$$$@.x $$(@D).x $$(@F).x + +$(dir)/x.z $(dir)/y.z: $(dir)/%.z : $@.% $$@.% $$$@.% $$$$@.% $$(@D).% $$(@F).% + +$(dir)/biz: $$(@).x $${@}.x $${@D}.x $${@F}.x +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "-j1 $dir/foo $dir/bar", &get_logfile); +$answer = ".x\n$dir/foo.x\nx\n\$@.x\n$dir.x\nfoo.x\n$dir/bar.x\nbar.x\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile2, "-j1 $dir/x.z $dir/y.z", &get_logfile); +$answer = ".x\n$dir/x.z.x\nx\n\$@.x\n$dir.x\nx.z.x\n.y\n$dir/y.z.y\n\y\n\$@.y\n$dir.y\ny.z.y\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile2, "-j1 $dir/biz", &get_logfile); +$answer = "$dir/biz.x\n$dir.x\nbiz.x\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 -- test for Savannah bug #12320. +# +run_make_test(' +.SUFFIXES: .b .src + +mbr.b: mbr.src + @echo $* + +mbr.src: ; @:', + '', + 'mbr'); + +# TEST #3 -- test for Savannah bug #8154 +# Make sure that nonexistent prerequisites are listed in $?, since they are +# considered reasons for the target to be rebuilt. +# +# See also Savannah bugs #16002 and #16051. + +touch('foo'); + +run_make_test(' +foo: bar ; @echo "\$$? = $?" +bar: ;', + '', + '$? = bar'); + +unlink('foo'); + +# TEST #4: ensure prereq ordering is correct when the commmand target has none +# See Savannah bug #21198 + +run_make_test(' +all : A B +all : ; @echo $@ -- $^ -- $< +all : C D +all : E F +A B C D E F G H : ; @: +', + '', "all -- A B C D E F -- A\n"); + +1; diff --git a/src/kmk/tests/scripts/variables/define b/src/kmk/tests/scripts/variables/define new file mode 100644 index 0000000..7324cbc --- /dev/null +++ b/src/kmk/tests/scripts/variables/define @@ -0,0 +1,282 @@ +# -*-perl-*- + +$description = "Test define/endef variable assignments."; + +$details = ""; + +# TEST 0: old-style basic define/endef + +run_make_test(' +define multi +@echo hi +echo there +endef + +all: ; $(multi) +', + '', "hi\necho there\nthere\n"); + +# TEST 1: Various new-style define/endef + +run_make_test(' +FOO = foo + +define multi = +echo hi +@echo $(FOO) +endef # this is the end + +define simple := +@echo $(FOO) +endef + +define posix ::= +@echo $(FOO) +endef + +append = @echo a + +define append += + +@echo b +endef + +define cond ?= # this is a conditional +@echo first +endef + +define cond ?= +@echo second +endef + +FOO = there + +all: ; $(multi) + $(simple) + $(posix) + $(append) + $(cond) +', + '', "echo hi\nhi\nthere\nfoo\nfoo\na\nb\nfirst\n"); + +# TEST 1a: Various new-style define/endef, with no spaces + +run_make_test(' +FOO = foo + +define multi= +echo hi +@echo $(FOO) +endef # this is the end + +define simple:= +@echo $(FOO) +endef + +define posix::= +@echo $(FOO) +endef + +append = @echo a + +define append+= + +@echo b +endef + +define cond?= # this is a conditional +@echo first +endef + +define cond?= +@echo second +endef + +FOO = there + +all: ; $(multi) + $(simple) + $(posix) + $(append) + $(cond) +', + '', "echo hi\nhi\nthere\nfoo\nfoo\na\nb\nfirst\n"); + +# TEST 2: define in true section of conditional (containing conditional) + +run_make_test(' +FOO = foo +NAME = def +def = +ifdef BOGUS + define $(subst e,e,$(NAME)) = + ifeq (1,1) + FOO = bar + endif + endef +endif + +$(eval $(def)) +all: ; @echo $(FOO) +', + 'BOGUS=1', "bar\n"); + +# TEST 3: define in false section of conditional (containing conditional) + +run_make_test(undef, '', "foo\n"); + +# TEST 4: nested define (supported?) + +run_make_test(' +define outer + define inner + A = B + endef +endef + +$(eval $(outer)) + +outer: ; @echo $(inner) +', + '', "A = B\n"); + +# TEST 5: NEGATIVE: Missing variable name + +run_make_test(' +NAME = +define $(NAME) = +ouch +endef +all: ; @echo ouch +', + '', "#MAKEFILE#:3: *** empty variable name. Stop.\n", 512); + +# TEST 6: NEGATIVE: extra text after define + +run_make_test(' +NAME = +define NAME = $(NAME) +ouch +endef +all: ; @echo ok +', + '', "#MAKEFILE#:3: extraneous text after 'define' directive\nok\n"); + +# TEST 7: NEGATIVE: extra text after endef + +run_make_test(' +NAME = +define NAME = +ouch +endef $(NAME) +all: ; @echo ok +', + '', "#MAKEFILE#:5: extraneous text after 'endef' directive\nok\n"); + +# TEST 8: NEGATIVE: missing endef + +run_make_test(' +NAME = +all: ; @echo ok +define NAME = +ouch +endef$(NAME) +', + '', "#MAKEFILE#:4: *** missing 'endef', unterminated 'define'. Stop.\n", 512); + +# ------------------------- +# Make sure that prefix characters apply properly to define/endef values. +# +# There's a bit of oddness here if you try to use a variable to hold the +# prefix character for a define. Even though something like this: +# +# define foo +# echo bar +# endef +# +# all: ; $(V)$(foo) +# +# (where V=@) can be seen by the user to be obviously different than this: +# +# define foo +# $(V)echo bar +# endef +# +# all: ; $(foo) +# +# and the user thinks it should behave the same as when the "@" is literal +# instead of in a variable, that can't happen because by the time make +# expands the variables for the command line and sees it begins with a "@" it +# can't know anymore whether the prefix character came before the variable +# reference or was included in the first line of the variable reference. + +# TEST #5 +# ------- + +run_make_test(' +define FOO +$(V1)echo hello +$(V2)echo world +endef +all: ; @$(FOO) +', '', 'hello +world'); + +# TEST #6 +# ------- + +run_make_test(undef, 'V1=@ V2=@', 'hello +world'); + +# TEST #7 +# ------- + +run_make_test(' +define FOO +$(V1)echo hello +$(V2)echo world +endef +all: ; $(FOO) +', 'V1=@', 'hello +echo world +world'); + +# TEST #8 +# ------- + +run_make_test(undef, 'V2=@', 'echo hello +hello +world'); + +# TEST #9 +# ------- + +run_make_test(undef, 'V1=@ V2=@', 'hello +world'); + +# TEST #10 +# ------- +# Test the basics; a "@" internally to the variable applies to only one line. +# A "@" before the variable applies to the entire variable. + +run_make_test(' +define FOO +@echo hello +echo world +endef +define BAR +echo hello +echo world +endef + +all: foo bar +foo: ; $(FOO) +bar: ; @$(BAR) +', '', 'hello +echo world +world +hello +world +'); + +1; diff --git a/src/kmk/tests/scripts/variables/flavors b/src/kmk/tests/scripts/variables/flavors new file mode 100644 index 0000000..ba133ea --- /dev/null +++ b/src/kmk/tests/scripts/variables/flavors @@ -0,0 +1,96 @@ +# -*-perl-*- + +$description = "Test various flavors of make variable setting."; + +$details = ""; + +# TEST 0: Recursive + +run_make_test(' +ugh = Goodbye +foo = $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +# TEST 1: Simple + +run_make_test(' +bar = Goodbye +foo := $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Goodbye\n"); + +# TEST 2: Append to recursive + +run_make_test(' +foo = Hello +ugh = Goodbye +foo += $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello Hello\n"); + +# TEST 3: Append to simple + +run_make_test(' +foo := Hello +ugh = Goodbye +bar = ${ugh} +foo += $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello Goodbye\n"); + +# TEST 4: Conditional pre-set + +run_make_test(' +foo = Hello +ugh = Goodbye +bar = ${ugh} +foo ?= $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +# TEST 5: Conditional unset + +run_make_test(' +ugh = Goodbye +bar = ${ugh} +foo ?= $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +# TEST 6: Simple using POSIX syntax +run_make_test(' +bar = Goodbye +foo ::= $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Goodbye\n"); + +# TEST 7: POSIX syntax no spaces +run_make_test(' +bar = Goodbye +foo::=$(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Goodbye\n"); + +1; diff --git a/src/kmk/tests/scripts/variables/must_make b/src/kmk/tests/scripts/variables/must_make new file mode 100644 index 0000000..83a8275 --- /dev/null +++ b/src/kmk/tests/scripts/variables/must_make @@ -0,0 +1,81 @@ +# $Id: must_make 2413 2010-09-11 17:43:04Z bird $ -*-perl-*- +## @file +# .MUST_MAKE target variable. +# + +# +# Copyright (c) 2008-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net> +# +# This file is part of kBuild. +# +# kBuild is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# kBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kBuild. If not, see <http://www.gnu.org/licenses/> +# +# + +$description = "Tests the .MUST_MAKE target variable"; + +$details = "The .MUST_MAKE target variable is expanded when make is deciding +whether a file needs to be made or not. If it returns a non-empty string, +when stripped, it will force the file to be made. If it returns an empty +string GNU make decides the normal way. Note that .MUST_MAKE does NOT have +to be expanded if make already knows the file needs building. Also, note +that for multi target rules it may be invoked for each file."; + +if ($is_kmk) { + + # TEST #0 - check to see that it gets called and is made. + # ------------------------------------------------------- + &touch('foobar.1'); + run_make_test(' + +foobar.1: .MUST_MAKE = $(info mustmake:{@=$@,<=$<})FORCE +foobar.1: ;touch $@ +', +'', +'mustmake:{@=foobar.1,<=} +touch foobar.1' +); + unlink('foobar.1'); + + # TEST #1 - check to see that it gets called and isn't made. + # ---------------------------------------------------------- + &touch('foobar.1'); + run_make_test(' + +foobar.1: .MUST_MAKE = $(info mustmake:{@=$@,<=$<}) +foobar.1: ;touch $@ +', +'', +'mustmake:{@=foobar.1,<=} +#MAKE#: `foobar.1\' is up to date.' +); + unlink('foobar.1'); + + # TEST #2 - check to see that it doesn't get called unnecessary. + # -------------------------------------------------------------- + run_make_test(' +foobar.1: .MUST_MAKE = $(info mustmake:{@=$@,<=$})FORCE +foobar.1: ;@echo making $@ +', +'', +'making foobar.1'); + +} + + + +# Indicate that we're done. +1; + + diff --git a/src/kmk/tests/scripts/variables/negative b/src/kmk/tests/scripts/variables/negative new file mode 100644 index 0000000..16a72b8 --- /dev/null +++ b/src/kmk/tests/scripts/variables/negative @@ -0,0 +1,46 @@ +# -*-perl-*- + +$description = "Run some negative tests (things that should fail)."; + +# TEST #0 +# Check that non-terminated variable references are detected (and +# reported using the best filename/lineno info +run_make_test(' +foo = bar +x = $(foo +y = $x + +all: ; @echo $y +', + '', '#MAKEFILE#:3: *** unterminated variable reference. Stop.', + 512); + +# TEST #1 +# Bogus variable value passed on the command line. +run_make_test(undef, + 'x=\$\(other', + '#MAKEFILE#:4: *** unterminated variable reference. Stop.', + 512); + +# TEST #2 +# Again, but this time while reading the makefile. +run_make_test(' +foo = bar +x = $(foo +y = $x + +z := $y + +all: ; @echo $y +', + '', '#MAKEFILE#:3: *** unterminated variable reference. Stop.', + 512); + +# TEST #3 +# Bogus variable value passed on the command line. +run_make_test(undef, + 'x=\$\(other', + '#MAKEFILE#:4: *** unterminated variable reference. Stop.', + 512); + +1; diff --git a/src/kmk/tests/scripts/variables/private b/src/kmk/tests/scripts/variables/private new file mode 100644 index 0000000..8967ffb --- /dev/null +++ b/src/kmk/tests/scripts/variables/private @@ -0,0 +1,122 @@ +# -*-perl-*- + +$description = "Test 'private' variables."; + +$details = ""; + +# 1: Simple verification that private variables are not inherited +&run_make_test(' +a: +F = g +a: F = a +b: private F = b + +a b c: ; @echo $@: F=$(F) +a: b +b: c +', + '', "c: F=a\nb: F=b\na: F=a\n"); + +# 2: Again, but this time we start with "b" so "a"'s variable is not in scope +&run_make_test(undef, 'b', "c: F=g\nb: F=b\n"); + +# 3: Verification with pattern-specific variables +&run_make_test(' +t.a: + +F1 = g +F2 = g +%.a: private F1 = a +%.a: F2 = a + +t.a t.b: ; @echo $@: F1=$(F1) / F2=$(F2) +t.a: t.b +', + '', "t.b: F1=g / F2=a\nt.a: F1=a / F2=a\n"); + +# 4: Test private global variables +&run_make_test(' +a: +private F = g +G := $(F) +a: +b: F = b + +a b: ; @echo $@: F=$(F) / G=$(G) +a: b +', + '', "b: F=b / G=g\na: F= / G=g\n"); + +# 5: Multiple conditions on the same variable. Test export. +delete $ENV{'_X'}; +&run_make_test(' +_X = x +a: export override private _X = a +a: ; @echo _X=$(_X) / _X=$$_X +', + '', "_X=a / _X=a"); + +# 6: Test override. +&run_make_test(undef, '_X=c', "_X=a / _X=a\n"); + +# 7: Ensure keywords still work as targets +&run_make_test(' +a: export override private foo bar +foo bar export override private: ; @echo $@ +', + '', "export\noverride\nprivate\nfoo\nbar\n"); + +# 8: Ensure keywords still work as variables +&run_make_test(' +private = g +a: private = a +a: b +a b: ; @echo $@=$(private) +', + '', "b=a\na=a\n"); + +# 9: make sure private suppresses inheritance +run_make_test(q! +DEFS = FOO +all: bar1 +bar1: private DEFS += 1 +bar3: private DEFS += 3 +bar1: bar2 +bar2: bar3 +bar1 bar2 bar3: ; @echo '$@: $(DEFS)' +!, + '', "bar3: FOO 3\nbar2: FOO\nbar1: FOO 1\n"); + +# 10: Test append with pattern-specific variables and private + +run_make_test(q! +IA = global +PA = global +PS = global +S = global +PS = global +SV = global +b%: IA += b% +b%: private PA += b% +b%: private PS = b% +bar: all +bar: IA += bar +bar: private PA += bar +bar: private PS = bar +a%: IA += a% +a%: private PA += a% +a%: private PS = a% +all: IA += all +all: private PA += all +all: private PS = all + +bar all: ; @echo '$@: IA=$(IA)'; echo '$@: PA=$(PA)'; echo '$@: PS=$(PS)' +!, + '', "all: IA=global b% bar a% all +all: PA=global a% all +all: PS=all +bar: IA=global b% bar +bar: PA=global b% bar +bar: PS=bar\n"); + +1; diff --git a/src/kmk/tests/scripts/variables/special b/src/kmk/tests/scripts/variables/special new file mode 100644 index 0000000..7e8a64f --- /dev/null +++ b/src/kmk/tests/scripts/variables/special @@ -0,0 +1,150 @@ +# -*-perl-*- + +$description = "Test special GNU make variables."; + +$details = ""; + +&run_make_test(' + +X1 := $(sort $(filter FOO BAR,$(.VARIABLES))) + +FOO := foo + +X2 := $(sort $(filter FOO BAR,$(.VARIABLES))) + +BAR := bar + +all: ; @echo X1 = $(X1); echo X2 = $(X2); echo LAST = $(sort $(filter FOO BAR,$(.VARIABLES))) +', + '', "X1 =\nX2 = FOO\nLAST = BAR FOO\n"); + +# SV 45728: Test that undefining a variable is reflected properly + +&run_make_test(' +FOO := foo +BAR := bar +$(info one: $(sort $(filter FOO BAR BAZ,$(.VARIABLES)))) +undefine BAR +BAZ := baz +$(info two: $(sort $(filter FOO BAR BAZ,$(.VARIABLES)))) +all:;@: +', + '', "one: BAR FOO\ntwo: BAZ FOO\n"); + +# $makefile2 = &get_tmpfile; +# open(MAKEFILE, "> $makefile2"); + +# print MAKEFILE <<'EOF'; + +# X1 := $(sort $(.TARGETS)) + +# all: foo +# @echo X1 = $(X1) +# @echo X2 = $(X2) +# @echo LAST = $(sort $(.TARGETS)) + +# X2 := $(sort $(.TARGETS)) + +# foo: + +# EOF + +# close(MAKEFILE); + +# # TEST #2 +# # ------- + +# &run_make_with_options($makefile2, "", &get_logfile); +# $answer = "X1 =\nX2 = all\nLAST = all foo\n"; +# &compare_output($answer, &get_logfile(1)); + +# Test the .RECIPEPREFIX variable +# kmk: This test isn't -j1 safe, haven't bother looking into why yet. +&run_make_test(' +define foo +: foo-one\ +foo-two +: foo-three + : foo-four +endef + +orig: ; : orig-one + : orig-two \ +orig-three \ + orig-four \ + orig-five \\\\ + : orig-six + $(foo) + +.RECIPEPREFIX = > +test: ; : test-one +>: test-two \ +test-three \ +>test-four \ +> test-five \\\\ +>: test-six +>$(foo) + +.RECIPEPREFIX = +reset: ; : reset-one + : reset-two \ +reset-three \ + reset-four \ + reset-five \\\\ + : reset-six + $(foo) +', + '-j1 orig test reset', + ': orig-one +: orig-two \ +orig-three \ +orig-four \ + orig-five \\\\ +: orig-six +: foo-one foo-two +: foo-three +: foo-four +: test-one +: test-two \ +test-three \ +test-four \ + test-five \\\\ +: test-six +: foo-one foo-two +: foo-three +: foo-four +: reset-one +: reset-two \ +reset-three \ +reset-four \ + reset-five \\\\ +: reset-six +: foo-one foo-two +: foo-three +: foo-four'); + +# Test that the "did you mean TAB" message is printed properly + +run_make_test(q! +$x. +!, + '', '#MAKEFILE#:2: *** missing separator. Stop.', 512); + +run_make_test(q! +foo: + bar +!, + '', '#MAKEFILE#:3: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.', 512); + +run_make_test(q! +.RECIPEPREFIX = : +foo: + bar +!, + '', '#MAKEFILE#:4: *** missing separator. Stop.', 512); + +1; + +### Local Variables: +### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) +### End: diff --git a/src/kmk/tests/scripts/variables/undefine b/src/kmk/tests/scripts/variables/undefine new file mode 100644 index 0000000..38707b8 --- /dev/null +++ b/src/kmk/tests/scripts/variables/undefine @@ -0,0 +1,73 @@ +# -*-perl-*- + +$description = "Test variable undefine."; + +$details = ""; + +# TEST 0: basic undefine functionality + +run_make_test(' +a = a +b := b +define c +c +endef + +$(info $(flavor a) $(flavor b) $(flavor c)) + +n := b + +undefine a +undefine $n +undefine c + +$(info $(flavor a) $(flavor b) $(flavor c)) + + +all: ;@: +', +'', "recursive simple recursive\nundefined undefined undefined"); + + +# TEST 1: override + +run_make_test(' +undefine a +override undefine b + +$(info $(flavor a) $(flavor b)) + + +all: ;@: +', +'a=a b=b', "recursive undefined"); + +1; + +# TEST 2: undefine in eval (make sure we undefine from the global var set) + +run_make_test(' +define undef +$(eval undefine $$1) +endef + +a := a +$(call undef,a) +$(info $(flavor a)) + + +all: ;@: +', +'', "undefined"); + + +# TEST 3: Missing variable name + +run_make_test(' +a = +undefine $a +all: ;@echo ouch +', +'', "#MAKEFILE#:3: *** empty variable name. Stop.\n", 512); + +1; diff --git a/src/kmk/tests/scripts/vms/library b/src/kmk/tests/scripts/vms/library new file mode 100644 index 0000000..9a64951 --- /dev/null +++ b/src/kmk/tests/scripts/vms/library @@ -0,0 +1,73 @@ +# -*-mode: perl-*- + +$description = "Test GNU make's VMS Library management features."; + +$details = "\ +This only works on VMS systems."; + +return -1 if $osname ne 'VMS'; + +# Help library +$mk_string = "help : help.hlb(file1.hlp)\n\n" . +"file1.hlp :\n" . +"\t\@pipe open/write xxx file1.hlp ; write xxx \"1 help\" ; close xxx\n"; + +my $answer = "library /replace help.hlb file1.hlp"; + +run_make_test($mk_string, + '', $answer); + +unlink('help.hlb'); +unlink('file1.hlp'); + +#Text library +$mk_string = "text : text.tlb(file1.txt)\n\n" . +"file1.txt :\n" . +"\t\@pipe open/write xxx file1.txt ; write xxx \"text file\" ; close xxx\n"; + +my $answer = "library /replace text.tlb file1.txt"; + +run_make_test($mk_string, + '', $answer); + +unlink('text.tlb'); +unlink('file1.txt'); + + +#Macro library +$mk_string = "macro : macro.mlb(file1.mar)\n\n" . +"file1.mar :\n" . +"\t\pipe open/write xxx file1.mar ; " . +"write xxx \".macro a b\" ; write xxx \".endm\" ; close xxx\n"; + +my $answer = "library /replace macro.mlb file1.mar"; + +run_make_test($mk_string, + '', $answer); + +unlink('macro.mlb'); +unlink('file1.mar'); + +$mk_string = +"all:imagelib.olb(file2.exe)\n" . +"file2.exe : file2.obj file2.opt\n" . +"\t\@link /share=\$\@ \$\*,\$\*/opt\n\n" . +"file2.opt :\n" . +"\t\@pipe open/write xxx file2.opt ; " . +"write xxx \"CASE_SENSITIVE=YES\" ; close xxx\n" . +"file2.c :\n" . +"\t\@pipe open/write xxx file2.c ; write xxx \"file2(){}\" ; close xxx\n"; + +my $answer = "library /replace imagelib.olb file2.exe"; + +run_make_test($mk_string, + '', $answer); + +unlink('imagelib.olb'); +unlink('file2.c'); +unlink('file2.obj'); +unlink('file2.exe'); +unlink('file2.opt'); + +# This tells the test driver that the perl test script executed properly. +1; |