| # -*-perl-*- |
| $description = "Test handling of static pattern rules."; |
| |
| $details = "\ |
| The makefile created in this test has three targets. The |
| filter command is used to get those target names ending in |
| .o and statically creates a compile command with the target |
| name and the target name with .c. It also does the same thing |
| for another target filtered with .elc and creates a command |
| to emacs a .el file"; |
| |
| &touch('bar.c', 'lose.c'); |
| |
| # TEST #0 |
| # ------- |
| |
| run_make_test(' |
| files = foo.elc bar.o lose.o |
| |
| $(filter %.o,$(files)): %.o: %.c ; @echo CC -c $(CFLAGS) $< -o $@ |
| |
| $(filter %.elc,$(files)): %.elc: %.el ; @echo emacs $< |
| ', |
| '', |
| 'CC -c bar.c -o bar.o'); |
| |
| # TEST #1 |
| # ------- |
| |
| run_make_test(undef, 'lose.o', 'CC -c lose.c -o lose.o'); |
| |
| |
| # TEST #2 |
| # ------- |
| &touch("foo.el"); |
| |
| run_make_test(undef, 'foo.elc', 'emacs foo.el'); |
| |
| # Clean up after the first tests. |
| unlink('foo.el', 'bar.c', 'lose.c'); |
| |
| |
| # TEST #3 -- PR/1670: don't core dump on invalid static pattern rules |
| # ------- |
| |
| run_make_test(' |
| .DEFAULT: ; @echo $@ |
| foo: foo%: % %.x % % % y.% % ; @echo $@ |
| ', |
| '', ".x\ny.\nfoo"); |
| |
| |
| # TEST #4 -- bug #12180: core dump on a stat pattern rule with an empty |
| # prerequisite list. |
| run_make_test(' |
| foo.x bar.x: %.x : ; @echo $@ |
| |
| ', |
| '', 'foo.x'); |
| |
| |
| # TEST #5 -- bug #13881: double colon static pattern rule does not |
| # substitute %. |
| run_make_test(' |
| foo.bar:: %.bar: %.baz |
| foo.baz: ;@: |
| ', |
| '', ''); |
| |
| |
| # TEST #6: make sure the second stem does not overwrite the first |
| # perprerequisite's stem (Savannah bug #16053). |
| # |
| run_make_test(' |
| .RECIPEPREFIX := > |
| |
| all.foo.bar: %.foo.bar: %.one |
| |
| all.foo.bar: %.bar: %.two |
| |
| all.foo.bar: |
| >#TAB#@echo $* |
| >#TAB#@echo $^ |
| |
| .DEFAULT:;@: |
| ', |
| '', |
| 'all.foo |
| all.one all.foo.two'); |
| |
| |
| # TEST #7: make sure the second stem does not overwrite the first |
| # perprerequisite's stem when second expansion is enabled |
| # (Savannah bug #16053). |
| # |
| run_make_test(' |
| .RECIPEPREFIX := > |
| .SECONDEXPANSION: |
| |
| all.foo.bar: %.foo.bar: %.one $$*-one |
| |
| all.foo.bar: %.bar: %.two $$*-two |
| |
| all.foo.bar: |
| >#TAB#@echo $* |
| >#TAB#@echo $^ |
| |
| .DEFAULT:;@: |
| ', |
| '', |
| 'all.foo |
| all.one all-one all.foo.two all.foo-two'); |
| |
| # Test #8: |
| # sv 60188. |
| # Static pattern rules are considered explicit rules: no prerequisite of |
| # a static pattern rule can ever be considered intermediate. |
| |
| touch('hello.z'); |
| |
| # subtest 1 |
| run_make_test(q! |
| hello.z: %.z: %.x ; @echo $@ |
| %.x: ; |
| !, '', "hello.z\n"); |
| |
| # subtest 2 |
| run_make_test(q! |
| hello.z: %.z: %.x test.x ; @echo $@ |
| %.x: ; |
| !, '', "hello.z\n"); |
| |
| # subtest 3 |
| # 'hello.x' is mentioned explicitly on an unrelated rule. |
| run_make_test(q! |
| hello.z: %.z: %.x ; @echo $@ |
| %.x: ; |
| unrelated: hello.x |
| !, '', "hello.z\n"); |
| |
| unlink('hello.z'); |
| |
| # sv 17374 Ensure double-colon static pattern rules work |
| |
| touch(qw(a.src b.src)); |
| |
| run_make_test(q! |
| all: a.tgt b.tgt |
| a.tgt b.tgt:: %.tgt : %.src ; cp $< $@ |
| !, |
| '', "cp a.src a.tgt\ncp b.src b.tgt\n"); |
| |
| unlink(qw(a.src b.src a.tgt b.tgt)); |
| |
| my @dir = ('', 'lib/'); # With and without last slash. |
| my @secondexpansion = ('', '.SECONDEXPANSION:'); |
| |
| # The following combinations are generated with and without second expansion. |
| # 1. |
| # all: bye.x |
| # bye.x: %.x: ... |
| # |
| # 2. |
| # all: lib/bye.x |
| # lib/bye.x: %.x: ... |
| # |
| # 3. |
| # all: lib/bye.x |
| # lib/bye.x: lib/%.x: ... |
| # |
| # The following combination is not generated, because there is no rule to |
| # build bye.x, no stem substitution takes place, not of interest of this test. |
| # 4. |
| # all: bye.x |
| # bye.x: lib/%.x: ... |
| # |
| |
| for my $se (@secondexpansion) { |
| for my $d (@dir) { # The directory of the prerequisite of 'all'. |
| for my $r (@dir) { # The directory of the prerequisite in the rule definition. |
| (!$d && $r) && next; # Combination 4. |
| my $dollar = $se ? '$' : ''; |
| |
| # The prerequisite should only have directory if the prerequisite of 'all' has |
| # it and if the prerequisite pattern in the rule definition does not have it. |
| # That is combination 2. |
| my $pdir = $d && !$r ? $d : ''; |
| |
| |
| # One func, one %. |
| my $prereqs = "${pdir}bye.1"; |
| run_make_test(" |
| $se |
| .PHONY: $prereqs |
| all: ${d}bye.x |
| ${d}bye.x: $r%.x: $dollar\$(firstword %.1); \$(info \$@ from \$^) |
| ", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| |
| |
| # Multiple funcs, each has one %. |
| $prereqs = "${pdir}bye.1 ${pdir}bye.2"; |
| run_make_test(" |
| $se |
| .PHONY: $prereqs |
| all: ${d}bye.x |
| ${d}bye.x: $r%.x: $dollar\$(firstword %.1) $dollar\$(firstword %.2); \$(info \$@ from \$^) |
| ", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| |
| |
| # Multiple funcs, each has multiple %. |
| $prereqs = "${pdir}bye.1 ${pdir}bye.2 ${pdir}bye.3 ${pdir}bye.4"; |
| run_make_test(" |
| $se |
| .PHONY: $prereqs |
| all: ${d}bye.x |
| ${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, %.1 %.2) $dollar\$(wordlist 1, 99, %.3 %.4); \$(info \$@ from \$^) |
| ", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| |
| |
| # Multiple funcs, each has multiple %, each prerequisite has multiple %. |
| $prereqs = "${pdir}bye_%_%.1 ${pdir}bye_%_%.2 ${pdir}bye_%_%.3 ${pdir}bye_%_%.4"; |
| run_make_test(" |
| $se |
| .PHONY: $prereqs |
| all: ${d}bye.x |
| ${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, %_%_%.1 %_%_%.2) $dollar\$(wordlist 1, 99, %_%_%.3 %_%_%.4); \$(info \$@ from \$^) |
| ", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| |
| |
| # Nested functions. |
| $prereqs = "${pdir}bye.1 ${pdir}bye.2 ${pdir}bye.3 ${pdir}bye.4"; |
| run_make_test(" |
| $se |
| .PHONY: $prereqs |
| all: ${d}bye.x |
| ${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, $dollar\$(wordlist 1, 99, %.1 %.2)) $dollar\$(wordlist 1, 99, $dollar\$(wordlist 1,99, %.3 %.4)); \$(info \$@ from \$^) |
| ", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| |
| |
| # Multiple funcs, each has multiple words, each word has multiple %, sole %, |
| # various corner cases. |
| # Make should substitute the first % and only the first % in each word with the |
| # stem. |
| $prereqs = "${pdir}bye1%2% ${pdir}bye 3${pdir}bye4%5 6${pdir}bye ${pdir}bye7%8 ${pdir}bye9 ${pdir}bye10% 11${pdir}bye12 13"; |
| run_make_test(" |
| $se |
| .PHONY: $prereqs |
| all: ${d}bye.x |
| ${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, %1%2% % 3%4%5 6%) %7%8 %9 $dollar\$(wordlist 1, 99, %10% 11%12) 13; \$(info \$@ from \$^) |
| ", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| |
| |
| if ($port_type eq 'UNIX') { |
| # Test that make does not use some hardcoded array of a finite size on stack. |
| # Long prerequisite name. This prerequisite name is over 66K long. |
| my $prefix = 'abcdefgh' x 128 x 33; # 33K long. |
| my $suffix = 'stuvwxyz' x 128 x 33; # 33K long. |
| $prereqs = "${prefix}${pdir}bye${suffix}.1 ${prefix}${pdir}bye${suffix}.2"; |
| run_make_test(" |
| $se |
| .PHONY: $prereqs |
| all: ${d}bye.x |
| ${d}bye.x: $r%.x: $dollar\$(wordlist 1, 99, ${prefix}%${suffix}.1 ${prefix}%${suffix}.2); \$(info \$@ from \$^) |
| ", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| } |
| |
| |
| # Empty stem. |
| $prereqs = "${pdir}.1"; |
| run_make_test(" |
| $se |
| .PHONY: $prereqs |
| all: ${d}bye.x |
| ${d}bye.x: $r%bye.x: $dollar\$(firstword %.1); \$(info \$@ from \$^) |
| ", '', "${d}bye.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| |
| |
| # A word expands to an empty prerequisite. |
| run_make_test(" |
| $se |
| all: ${d}bye.x |
| ${d}bye.x: $r%.x: $dollar\$(%); \$(info \$@ from \$^) |
| ", '', "${d}bye.x from \n#MAKE#: Nothing to be done for 'all'.\n"); |
| |
| } |
| } |
| } |
| |
| # Escaped %. |
| # The following combinations are generated without second expansion. |
| # 1. |
| # all: the%weird\\_hello_pattern\\.x |
| # the\\%weird\\_hello_pattern\\.x: the\\%weird\\_%_pattern\\.x: ... |
| # |
| # 2. |
| # all: lib/the%weird\\_hello_pattern\\.x |
| # lib/the\\%weird\\_hello_pattern\\.x: lib/the\\%weird\\_%_pattern\\.x: ... |
| # |
| # Other combinations or second expansion are not tested, because escaped % is |
| # not implemented for those. |
| |
| for my $d (@dir) { |
| my $prereqs = "${d}the%weird\\\\_hello_pattern%\\\\.1 ${d}the%weird\\\\_hello_pattern%\\\\.2"; |
| run_make_test(" |
| .PHONY: $prereqs |
| all: ${d}the%weird\\\\_hello_pattern\\\\.x |
| ${d}the\\%weird\\\\_hello_pattern\\\\.x: ${d}the\\%weird\\\\_%_pattern\\\\.x: \$(wordlist 1, 99, ${d}the\\%weird\\\\_%_pattern%\\\\.1 ${d}the\\%weird\\\\_%_pattern%\\\\.2); \$(info \$@ from \$^) |
| ", '', "${d}the%weird\\\\_hello_pattern\\\\.x from $prereqs\n#MAKE#: Nothing to be done for 'all'.\n"); |
| } |
| |
| 1; |