diff options
Diffstat (limited to '')
-rwxr-xr-x | testsuite/make.tests | 805 |
1 files changed, 805 insertions, 0 deletions
diff --git a/testsuite/make.tests b/testsuite/make.tests new file mode 100755 index 000000000..fabdbe45c --- /dev/null +++ b/testsuite/make.tests | |||
@@ -0,0 +1,805 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | . ./testing.sh | ||
4 | unset MAKEFLAGS | ||
5 | rm -rf make.tempdir | ||
6 | |||
7 | # testing "test name" "command" "expected result" "file input" "stdin" | ||
8 | |||
9 | testing "make basic makefile" \ | ||
10 | "make -f -" "target\n" "" ' | ||
11 | target: | ||
12 | @echo target | ||
13 | ' | ||
14 | |||
15 | testing "make .DEFAULT rule for prerequisite" \ | ||
16 | "make -f - 2>/dev/null" "source\n" "" ' | ||
17 | .DEFAULT: | ||
18 | @echo $@ | ||
19 | target: source | ||
20 | ' | ||
21 | |||
22 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
23 | touch target.xyz | ||
24 | testing "make empty command overrides inference rule" \ | ||
25 | "make -f - target 2>/dev/null" "" "" ' | ||
26 | .SUFFIXES: .xyz | ||
27 | .xyz: | ||
28 | @echo xyz | ||
29 | target: ; | ||
30 | ' | ||
31 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
32 | |||
33 | # Macros should be expanded before suffix substitution. The suffixes | ||
34 | # can be obtained by macro expansion. | ||
35 | testing "make macro expansion and suffix substitution" \ | ||
36 | "make -f -" "src1.o src2.o\n" "" ' | ||
37 | DOTC = .c | ||
38 | DOTO = .o | ||
39 | SRC1 = src1.c | ||
40 | SRCS = $(SRC1) src2.c | ||
41 | target: | ||
42 | @echo $(SRCS:$(DOTC)=$(DOTO)) | ||
43 | ' | ||
44 | |||
45 | # Indeed, everything after the <colon> can be obtained by macro | ||
46 | # macro expansion. | ||
47 | testing "make macro expansion and suffix substitution 2" \ | ||
48 | "make -f -" "src1.o src2.o\n" "" ' | ||
49 | DOTS = .c=.o | ||
50 | SRC1 = src1.c | ||
51 | SRCS = $(SRC1) src2.c | ||
52 | target: | ||
53 | @echo $(SRCS:$(DOTS)) | ||
54 | ' | ||
55 | |||
56 | # It should be possible for an inference rule to determine that a | ||
57 | # prerequisite can be created using an explicit rule. | ||
58 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
59 | testing "make inference rule with explicit rule for prerequisite" \ | ||
60 | "make -f -" "touch x.p\ncat x.p >x.q\n" "" ' | ||
61 | .SUFFIXES: .p .q | ||
62 | x.q: | ||
63 | x.p: | ||
64 | touch $@ | ||
65 | .p.q: | ||
66 | cat $< >$@ | ||
67 | ' | ||
68 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
69 | |||
70 | # Austin Group defect report 875 clarifies certain aspects of the | ||
71 | # behaviour of inference rules. Study of this resulted in a number | ||
72 | # of changes to pdpmake, though this test passed anyway. | ||
73 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
74 | touch test.j test.k | ||
75 | testing "make proper handling of inference rules 1" \ | ||
76 | "make -f -" \ | ||
77 | ".j.l\n" "" ' | ||
78 | .SUFFIXES: .j .k .l | ||
79 | .j.l: | ||
80 | @echo .j.l | ||
81 | .k.l: | ||
82 | @echo .k.l | ||
83 | test.l: test.k | ||
84 | test.j: | ||
85 | test.k: | ||
86 | ' | ||
87 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
88 | |||
89 | # Check that single-suffix inference rules work. | ||
90 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
91 | touch test.sh | ||
92 | testing "make single-suffix inference rule works" \ | ||
93 | "make -f - -s; echo $?" \ | ||
94 | "0\n" "" ' | ||
95 | test: | ||
96 | ' | ||
97 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
98 | |||
99 | # There was a bug where the failure of a build command didn't result | ||
100 | # in make returning a non-zero exit status. | ||
101 | testing "make return error if command fails" \ | ||
102 | "make -f - >/dev/null 2>&1; test \$? -gt 0 && echo OK" "OK\n" "" ' | ||
103 | target: | ||
104 | @exit 42 | ||
105 | ' | ||
106 | |||
107 | # An equal sign in a command on a target rule was detected as a | ||
108 | # macro assignment. | ||
109 | testing "make equal sign in inline command" \ | ||
110 | "make -f -" "a = a\n" "" ' | ||
111 | a = a | ||
112 | target:;@echo a = $(a) | ||
113 | ' | ||
114 | |||
115 | # Ensure an inline command on a target rule can be detected even if | ||
116 | # the semicolon is obfuscated. | ||
117 | testing "make equal sign in obfuscated inline command" \ | ||
118 | "make -f -" "a = a\n" "" ' | ||
119 | a = a | ||
120 | semi = ; | ||
121 | target:$(semi)@echo a = $(a) | ||
122 | ' | ||
123 | |||
124 | # When a build command fails and the '-k' option has been provided | ||
125 | # (continue execution on error) no further commands should be executed | ||
126 | # for the current target. | ||
127 | testing "make failure of build command with -k" \ | ||
128 | "make -k -f - 2>/dev/null" "OK\n" "" ' | ||
129 | all: bar baz | ||
130 | bar: | ||
131 | @echo OK | ||
132 | @false | ||
133 | @echo Not reached | ||
134 | baz: | ||
135 | @: | ||
136 | ' | ||
137 | # Build commands with a '+' prefix are executed even with the -q option. | ||
138 | testing "make execute build command with + prefix and -q" \ | ||
139 | "make -q -f - 2>/dev/null" "OK\n" "" ' | ||
140 | all: bar | ||
141 | bar: | ||
142 | @+echo OK | ||
143 | ' | ||
144 | |||
145 | # The -t option touches files that are out-of-date unless the target | ||
146 | # has no commands or they're already up-to-date. | ||
147 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
148 | touch baz | ||
149 | testing "make check -t option" \ | ||
150 | "make -t -f - 2>/dev/null" "touch bar\n" "" ' | ||
151 | all: foo bar baz | ||
152 | foo: | ||
153 | bar: | ||
154 | @echo bar | ||
155 | baz: | ||
156 | @echo baz | ||
157 | ' | ||
158 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
159 | |||
160 | # Build commands with a '+' prefix are executed even with the -t option. | ||
161 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
162 | testing "make execute build command with + prefix and -t" \ | ||
163 | "make -t -f - 2>/dev/null" "OK\n" "" ' | ||
164 | all: bar | ||
165 | bar: | ||
166 | @+echo OK | ||
167 | ' | ||
168 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
169 | |||
170 | # A macro created using ::= remembers it's of type immediate-expansion. | ||
171 | # Immediate expansion also occurs when += is used to append to such a macro. | ||
172 | testing "make appending to immediate-expansion macro" \ | ||
173 | "make -f -" \ | ||
174 | "hello 1 2 3\nhello 4 4\n" "" ' | ||
175 | world = 1 | ||
176 | hello ::= hello $(world) | ||
177 | world = 2 | ||
178 | hello += $(world) | ||
179 | world = 3 | ||
180 | hello += $(world) | ||
181 | world = 4 | ||
182 | |||
183 | world = 1 | ||
184 | reset ::= hello $(world) | ||
185 | world = 2 | ||
186 | # No longer immediate-expansion | ||
187 | reset = hello $(world) | ||
188 | world = 3 | ||
189 | reset += $(world) | ||
190 | world = 4 | ||
191 | |||
192 | target: | ||
193 | @echo $(hello) | ||
194 | @echo $(reset) | ||
195 | ' | ||
196 | |||
197 | # Since GNU make and bmake interpret := macro assignments differently, | ||
198 | # POSIX has ::= for the GNU variant and :::= for BSD. | ||
199 | testing "make different styles of := macro assignment" \ | ||
200 | "make -f -" \ | ||
201 | '65 a a $A\n' "" ' | ||
202 | A = a | ||
203 | GNU ::= $A | ||
204 | BSD1 :::= $A | ||
205 | BSD2 :::= $$A | ||
206 | A = 65 | ||
207 | |||
208 | target: | ||
209 | @echo '\''$(A) $(GNU) $(BSD1) $(BSD2)'\'' | ||
210 | ' | ||
211 | |||
212 | # Similar to the above but for macro assignments on the command line. | ||
213 | # POSIX has ::= for the GNU variant and :::= for BSD. | ||
214 | testing "make := macro assignment on command line" \ | ||
215 | "make -f - A=a 'GNU::=\$A' 'BSD1:::=\$A' 'BSD2:::=\$\$A' A=65" \ | ||
216 | '65 a a $A\n' "" ' | ||
217 | target: | ||
218 | @echo '\''$(A) $(GNU) $(BSD1) $(BSD2)'\'' | ||
219 | ' | ||
220 | |||
221 | # basic pattern macro expansion | ||
222 | testing "make basic pattern macro expansion" \ | ||
223 | "make -f -" \ | ||
224 | "obj/util.o obj/main.o\n" "" ' | ||
225 | SRC = src/util.c src/main.c | ||
226 | OBJ = $(SRC:src/%.c=obj/%.o) | ||
227 | |||
228 | target: | ||
229 | @echo $(OBJ) | ||
230 | ' | ||
231 | |||
232 | # pattern macro expansion; match any value | ||
233 | testing "make pattern macro expansion; match any value" \ | ||
234 | "make -f -" \ | ||
235 | "any_value.o\n" "" ' | ||
236 | SRC = any_value | ||
237 | OBJ = $(SRC:%=%.o) | ||
238 | |||
239 | target: | ||
240 | @echo $(OBJ) | ||
241 | ' | ||
242 | |||
243 | # pattern macro expansion with empty rvalue | ||
244 | testing "make pattern macro expansion with empty rvalue" \ | ||
245 | "make -f -" \ | ||
246 | "\n" "" ' | ||
247 | SRC = util.c main.c | ||
248 | OBJ = $(SRC:%.c=) | ||
249 | |||
250 | target: | ||
251 | @echo $(OBJ) | ||
252 | ' | ||
253 | |||
254 | # pattern macro expansion with multiple <percent> in rvalue | ||
255 | # POSIX requires the first <percent> to be expanded, others | ||
256 | # may or may not be expanded. Permit either case. | ||
257 | testing "make pattern macro expansion with multiple <percent> in rvalue" \ | ||
258 | "make -f - | sed 's/mainmainmain/main%%/'" \ | ||
259 | "main%%\n" "" ' | ||
260 | SRC = main.c | ||
261 | OBJ = $(SRC:%.c=%%%) | ||
262 | |||
263 | target: | ||
264 | @echo $(OBJ) | ||
265 | ' | ||
266 | |||
267 | # pattern macro expansion; zero match | ||
268 | testing "make pattern macro expansion; zero match" \ | ||
269 | "make -f -" \ | ||
270 | "nsnp\n" "" ' | ||
271 | WORD = osop | ||
272 | REPL = $(WORD:os%op=ns%np) | ||
273 | |||
274 | target: | ||
275 | @echo $(REPL) | ||
276 | ' | ||
277 | |||
278 | # Check that MAKE will contain argv[0], e.g make in this case | ||
279 | testing "make basic MAKE macro expansion" \ | ||
280 | "make -f -" \ | ||
281 | "make\n" "" ' | ||
282 | target: | ||
283 | @echo $(MAKE) | ||
284 | ' | ||
285 | |||
286 | # Check that MAKE defined as environment variable will overwrite default MAKE | ||
287 | testing "make MAKE macro expansion; overwrite with env macro" \ | ||
288 | "MAKE=hello make -f -" \ | ||
289 | "hello\n" "" ' | ||
290 | target: | ||
291 | @echo $(MAKE) | ||
292 | ' | ||
293 | |||
294 | # Check that MAKE defined on the command-line will overwrite MAKE defined in | ||
295 | # Makefile | ||
296 | testing "make MAKE macro expansion; overwrite with command-line macro" \ | ||
297 | "make -f - MAKE=hello" \ | ||
298 | "hello\n" "" ' | ||
299 | MAKE = test | ||
300 | |||
301 | target: | ||
302 | @echo $(MAKE) | ||
303 | ' | ||
304 | |||
305 | # POSIX draft states that if make was invoked using relative path, MAKE must | ||
306 | # contain absolute path, not just argv[0] | ||
307 | testing "make MAKE macro expansion; turn relative path into absolute" \ | ||
308 | "../runtest-tempdir-links/make -f -" \ | ||
309 | "ok\n" "" ' | ||
310 | target: | ||
311 | @test -e "$(MAKE)" && test "$(MAKE)" = "$$(env which make)" && echo ok | ||
312 | ' | ||
313 | |||
314 | # $? contains prerequisites newer than target, file2 in this case | ||
315 | # $^ has all prerequisites, file1 and file2 | ||
316 | touch -t 202206171200 file1 | ||
317 | touch -t 202206171201 target | ||
318 | touch -t 202206171202 file2 | ||
319 | testing "make compare \$? and \$^ internal macros" \ | ||
320 | "make -f -" \ | ||
321 | "file2\nfile1 file2\n" "" ' | ||
322 | target: file1 file2 | ||
323 | @echo $? | ||
324 | @echo $^ | ||
325 | ' | ||
326 | rm -f target file1 file2 | ||
327 | |||
328 | # Phony targets are executed (once) even if a matching file exists. | ||
329 | # A .PHONY target with no prerequisites is ignored. | ||
330 | touch -t 202206171201 target | ||
331 | testing "make phony target" \ | ||
332 | "make -f -" \ | ||
333 | "phony\n" "" ' | ||
334 | .PHONY: target | ||
335 | .PHONY: | ||
336 | target: | ||
337 | @echo phony | ||
338 | ' | ||
339 | rm -f target | ||
340 | |||
341 | # Phony targets aren't touched with -t | ||
342 | testing "make phony target not touched" \ | ||
343 | "make -t -f - >/dev/null && test -f target && echo target" \ | ||
344 | "" "" ' | ||
345 | .PHONY: target | ||
346 | target: | ||
347 | @: | ||
348 | ' | ||
349 | rm -f target | ||
350 | |||
351 | # Include files are created or brought up-to-date | ||
352 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
353 | testing "make create include file" \ | ||
354 | "make -f -" \ | ||
355 | "made\n" "" ' | ||
356 | target: | ||
357 | @echo $(VAR) | ||
358 | mk: | ||
359 | @echo "VAR = made" >mk | ||
360 | include mk | ||
361 | ' | ||
362 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
363 | |||
364 | # Include files are created or brought up-to-date even when the -n | ||
365 | # option is given. | ||
366 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
367 | testing "make create include file even with -n" \ | ||
368 | "make -n -f -" \ | ||
369 | "echo made\n" "" ' | ||
370 | target: | ||
371 | @echo $(VAR) | ||
372 | mk: | ||
373 | @echo "VAR = made" >mk | ||
374 | include mk | ||
375 | ' | ||
376 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
377 | |||
378 | # Failure to create an include file isn't an error. (Provided the | ||
379 | # include line is ignoring non-existent files.) | ||
380 | testing "make failure to create include file is OK" \ | ||
381 | "make -f -" \ | ||
382 | "OK\n" "" ' | ||
383 | target: | ||
384 | @echo OK | ||
385 | mk: | ||
386 | @: | ||
387 | -include mk | ||
388 | ' | ||
389 | |||
390 | # $^ skips duplicate prerequisites, $+ doesn't | ||
391 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
392 | touch file1 file2 file3 | ||
393 | testing "make skip duplicate entries in \$^ but not \$+" \ | ||
394 | "make -f -" \ | ||
395 | "file1 file2 file3\nfile1 file2 file2 file3 file3\n" "" ' | ||
396 | target: file1 file2 file2 file3 file3 | ||
397 | @echo $^ | ||
398 | @echo $+ | ||
399 | ' | ||
400 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
401 | |||
402 | # Assign the output of a shell command to a macro. | ||
403 | testing "make shell assignment" \ | ||
404 | "make -f -" \ | ||
405 | "1 2 3 4\n" "" ' | ||
406 | hello != echo 1; echo 2; echo 3; echo; echo | ||
407 | |||
408 | target: | ||
409 | @echo "$(hello) 4" | ||
410 | ' | ||
411 | |||
412 | # Nested macro expansion is allowed. This should be compatible | ||
413 | # with other implementations. | ||
414 | testing "make nested macro expansion" \ | ||
415 | "make -f -" "0 bc\n1 d\n2\n3\n4 bcd\n5 bcd\n" "" ' | ||
416 | a = b | ||
417 | b = c | ||
418 | c = d | ||
419 | $(a:.q=.v)$(b:.z=.v) = bc | ||
420 | bcd = bcd | ||
421 | target: | ||
422 | @echo 0 $(bc) | ||
423 | @echo 1 $($($(a))) | ||
424 | @echo 2 $($(a) $(b) $(c)) | ||
425 | @echo 3 $($a $b $c) | ||
426 | @echo 4 $($(a)$(b)$(c)) | ||
427 | @echo 5 $($a$b$c) | ||
428 | ' | ||
429 | |||
430 | # .WAIT is allowed as a prerequisite. Since parallel builds aren't | ||
431 | # implemented it doesn't have any effect. | ||
432 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
433 | touch file1 file2 | ||
434 | testing "make .WAIT is allowed as a prerequisite" \ | ||
435 | "make -f -" \ | ||
436 | "file1 file2\n" "" ' | ||
437 | target: file1 .WAIT file2 | ||
438 | @echo $? | ||
439 | ' | ||
440 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
441 | |||
442 | # Escaped newlines inside macro expansions in commands get different | ||
443 | # treatment than those outside. In POSIX 2017 the output is 'a b ab'. | ||
444 | testing "make replace escaped NL in macro in command with space" \ | ||
445 | "make -f -" \ | ||
446 | "a b a b\n" "" ' | ||
447 | M=word | ||
448 | N=${M:word=a\\ | ||
449 | b} | ||
450 | target: | ||
451 | @echo ${N} ${M:word=a\\ | ||
452 | b} | ||
453 | ' | ||
454 | |||
455 | # The CURDIR macro is supported in POSIX 2024. | ||
456 | testing "make CURDIR macro" \ | ||
457 | "make -f -" \ | ||
458 | "OK\n" "" ' | ||
459 | target: | ||
460 | @test "$(CURDIR)" = "$$(pwd -P)" && echo OK | ||
461 | ' | ||
462 | # The CURDIR environment variable doesn't affect the macro | ||
463 | export CURDIR=/you/are/here | ||
464 | testing "make CURDIR macro not affected by environment" \ | ||
465 | "make -f -" \ | ||
466 | "OK\n" "" ' | ||
467 | target: | ||
468 | @test "$(CURDIR)" != "/you/are/here" && echo OK | ||
469 | ' | ||
470 | |||
471 | # The -e option makes the CURDIR macro match the environment | ||
472 | testing "make with -e CURDIR macro is affected by the environment" \ | ||
473 | "make -e -f -" \ | ||
474 | "/you/are/here\n" "" ' | ||
475 | target: | ||
476 | @echo $(CURDIR) | ||
477 | ' | ||
478 | unset CURDIR | ||
479 | |||
480 | # The fix for an equal sign in an inline command on a target rule broke | ||
481 | # a complex chain of macro assignments generated by autotools. | ||
482 | testing "make complex chain of macro assignments" \ | ||
483 | "make -f -" "flag 1\n" "" ' | ||
484 | FLAG_ = $(FLAG_$(VALUE)) | ||
485 | FLAG_0 = flag 0 | ||
486 | FLAG_1 = flag 1 | ||
487 | MYFLAG = $(FLAG_$(VALUE)) | ||
488 | VALUE = 1 | ||
489 | |||
490 | target: | ||
491 | @echo $(MYFLAG) | ||
492 | ' | ||
493 | |||
494 | # POSIX 2024 permits additional characters in macro and target names | ||
495 | testing "make allow - and / in target names, - in macro names" \ | ||
496 | "make -f -" \ | ||
497 | "/hello\nhel-lo\nmac-ro\n" "" ' | ||
498 | target: ./hello hel-lo | ||
499 | @echo $(mac-ro) | ||
500 | ./hello: | ||
501 | @echo /hello | ||
502 | hel-lo: | ||
503 | @echo hel-lo | ||
504 | mac-ro = mac-ro | ||
505 | ' | ||
506 | |||
507 | testing "make double-colon rule" \ | ||
508 | "make -f -" "target1\ntarget2\n" "" ' | ||
509 | target:: | ||
510 | @echo target1 | ||
511 | target:: | ||
512 | @echo target2 | ||
513 | ' | ||
514 | |||
515 | # There was a bug whereby the modification time of a file created by | ||
516 | # double-colon rules wasn't correctly updated. This test checks that | ||
517 | # the bug is now fixed. | ||
518 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
519 | touch -t 202206171200 file1 | ||
520 | touch -t 202206171201 intermediate | ||
521 | touch -t 202206171202 target | ||
522 | touch -t 202206171203 file2 | ||
523 | testing "make target depends on prerequisite updated by double-colon rule" \ | ||
524 | "make -f -" \ | ||
525 | "file2\n" "" ' | ||
526 | target: intermediate | ||
527 | @cat intermediate | ||
528 | intermediate:: file1 | ||
529 | @echo file1 >>intermediate | ||
530 | intermediate:: file2 | ||
531 | @echo file2 >>intermediate | ||
532 | ' | ||
533 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
534 | |||
535 | # Use chained inference rules to determine prerequisites. | ||
536 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
537 | touch target.p | ||
538 | testing "make chained inference rules" \ | ||
539 | "make -s -f - target.s" \ | ||
540 | "target.q\ntarget.r\ntarget.s\n" "" ' | ||
541 | .SUFFIXES: .p .q .r .s | ||
542 | .p.q: | ||
543 | @cp $< $*.q | ||
544 | @echo $*.q | ||
545 | .q.r: | ||
546 | @cp $< $*.r | ||
547 | @echo $*.r | ||
548 | .r.s: | ||
549 | @cp $< $*.s | ||
550 | @echo $*.s | ||
551 | ' | ||
552 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
553 | |||
554 | # Suffixes with multiple periods are supported | ||
555 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
556 | touch x.c.c | ||
557 | testing "make support multi-period suffixes" \ | ||
558 | "make -f -" "cat x.c.c >x.o.o\nx\n" "" ' | ||
559 | .SUFFIXES: .c.c .o.o | ||
560 | x.o.o: | ||
561 | .c.c.o.o: | ||
562 | cat $< >$@ | ||
563 | @echo $* | ||
564 | ' | ||
565 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
566 | |||
567 | # Suffixes with no periods are supported | ||
568 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
569 | touch filex | ||
570 | testing "make support suffixes without any periods" \ | ||
571 | "make -f -" "cp filex fileh\nfile\ncp filex filez\nfile\n" "" ' | ||
572 | .SUFFIXES: x h z | ||
573 | all: fileh filez | ||
574 | fileh: | ||
575 | filez: filex | ||
576 | cp filex filez | ||
577 | @echo $* | ||
578 | xh: | ||
579 | cp $< $@ | ||
580 | @echo $* | ||
581 | ' | ||
582 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
583 | |||
584 | # make supports *, ? and [] wildcards in targets and prerequisites | ||
585 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
586 | touch -t 202206171201 t1a t2aa t3b | ||
587 | touch s1a s2aa s3b | ||
588 | testing "make expand wildcards in filenames" \ | ||
589 | "make -f - t1a t2aa t3b" \ | ||
590 | "t1a s1a s2aa s3b\nt2aa s1a s2aa s3b\nt3b s1a s2aa s3b\n" "" ' | ||
591 | t1? t2* t3[abc]: s1? s2* s3[abc] | ||
592 | @echo $@ $? | ||
593 | ' | ||
594 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
595 | |||
596 | # A '#' character in a macro expansion doesn't start a comment | ||
597 | testing "make hash in macro expansion isn't a comment" \ | ||
598 | "make -f -" \ | ||
599 | ": hash # hash\n" "" ' | ||
600 | HASH = hash | ||
601 | hash = $(HASH:hash=#) | ||
602 | target: | ||
603 | : hash $(hash) hash | ||
604 | ' | ||
605 | |||
606 | # A '#' character can be escaped with a backslash | ||
607 | testing "make backslash-escaped hash isn't a comment" \ | ||
608 | "make -f -" \ | ||
609 | ": hash # hash\n" "" ' | ||
610 | hash = \\# | ||
611 | target: | ||
612 | : hash $(hash) hash | ||
613 | ' | ||
614 | |||
615 | # A '#' character in a command line doesn't start a comment | ||
616 | testing "make hash in command line isn't a comment" \ | ||
617 | "make -f -" \ | ||
618 | ": hash # hash\n" "" ' | ||
619 | target: | ||
620 | : hash # hash | ||
621 | ' | ||
622 | |||
623 | # Austin Group defect report 875 (mentioned above) actually used | ||
624 | # suffixes '.a .b .c'. This doesn't matter in POSIX mode but it | ||
625 | # caused a failure (now fixed) when chained inference rules were | ||
626 | # allowed. The '.a.c' and the built-in '.c.a' inference rules | ||
627 | # resulted in a loop. | ||
628 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
629 | touch test.a test.b | ||
630 | testing "make proper handling of inference rules 2" \ | ||
631 | "make -f -" \ | ||
632 | ".a.c\n" "" ' | ||
633 | .SUFFIXES: .a .b .c | ||
634 | .a.c: | ||
635 | @echo .a.c | ||
636 | .b.c: | ||
637 | @echo .b.c | ||
638 | test.c: test.b | ||
639 | test.a: | ||
640 | test.b: | ||
641 | ' | ||
642 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
643 | |||
644 | # Don't use the shell -e option when running commands. | ||
645 | testing "make no shell -e option when running commands" \ | ||
646 | "make -f -" "OK\n" "" ' | ||
647 | target: | ||
648 | @false; echo OK | ||
649 | ' | ||
650 | |||
651 | # Macros and targets may be mixed on the command line | ||
652 | testing "make allow mixed macros and targets" \ | ||
653 | "make -f - FOO=foo foo BAR=bar bar" "foo\nbar\nfoo\nbar\n" "" ' | ||
654 | foo: | ||
655 | @echo $(FOO) | ||
656 | @echo $(BAR) | ||
657 | bar: | ||
658 | @echo $(FOO) | ||
659 | @echo $(BAR) | ||
660 | ' | ||
661 | |||
662 | # $* and $< are supported for target rules | ||
663 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
664 | touch src.c src.h | ||
665 | testing 'make support $* and $< for target rules' \ | ||
666 | "make -f -" "src.c src.h\nsrc.o\nsrc\nsrc.c\n" "" ' | ||
667 | src.o: src.c src.h | ||
668 | @echo "$?" | ||
669 | @echo "$@" | ||
670 | @echo "$*" | ||
671 | @echo "$<" | ||
672 | ' | ||
673 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
674 | |||
675 | # ifeq/ifneq conditionals are supported | ||
676 | testing 'make support ifeq and ifneq conditionals' \ | ||
677 | "make -f -" "A OK\nB OK\n" "" ' | ||
678 | A = a | ||
679 | B = b | ||
680 | target: | ||
681 | ifeq ($(A),a) | ||
682 | @echo A OK | ||
683 | else | ||
684 | @echo A not OK | ||
685 | endif | ||
686 | ifneq "a" "$B" | ||
687 | @echo B OK | ||
688 | endif | ||
689 | ' | ||
690 | |||
691 | # An empty original suffix indicates that every word should have | ||
692 | # the new suffix added. If neither suffix is provided the words | ||
693 | # remain unchanged. | ||
694 | testing "make macro expansion and suffix substitution 3" \ | ||
695 | "make -f -" "src1.c src2.c\nsrc1 src2\n" "" ' | ||
696 | SRCS = src1 src2 | ||
697 | target: | ||
698 | @echo $(SRCS:=.c) | ||
699 | @echo $(SRCS:=) | ||
700 | ' | ||
701 | |||
702 | # Skip duplicate entries in $? and $^ | ||
703 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
704 | touch -t 202206171200 file1 file3 | ||
705 | touch -t 202206171201 target | ||
706 | touch -t 202206171202 file2 | ||
707 | testing "make skip duplicate entries in \$? and \$^" \ | ||
708 | "make -f -" \ | ||
709 | "file2\nfile1 file2 file3\n" "" ' | ||
710 | target: file1 file2 file2 file3 file3 | ||
711 | @echo $? | ||
712 | @echo $^ | ||
713 | ' | ||
714 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
715 | |||
716 | # Skip duplicate entries in $? and $^, with each double-colon rule | ||
717 | # handled separately | ||
718 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
719 | touch -t 202206171200 file1 file3 | ||
720 | touch -t 202206171201 target | ||
721 | touch -t 202206171202 file2 | ||
722 | testing "make skip duplicate entries: double-colon rules" \ | ||
723 | "make -f -" \ | ||
724 | "file2\nfile1 file3 file2\nfile2\nfile2 file3\n" "" ' | ||
725 | target:: file1 file3 file1 file2 file3 | ||
726 | @echo $? | ||
727 | @echo $^ | ||
728 | target:: file2 file3 file3 | ||
729 | @echo $? | ||
730 | @echo $^ | ||
731 | ' | ||
732 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
733 | |||
734 | # Skip duplicate entries in $? and $^, with each double-colon rule | ||
735 | # handled separately. No prerequisites out-of-date in the first. | ||
736 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
737 | touch -t 202206171200 file1 file3 | ||
738 | touch -t 202206171201 target | ||
739 | touch -t 202206171202 file2 | ||
740 | testing "make skip duplicate entries: double-colon rules, only second invoked" \ | ||
741 | "make -f -" \ | ||
742 | "file2\nfile2 file3\n" "" ' | ||
743 | target:: file1 file3 file1 file3 | ||
744 | @echo $? | ||
745 | @echo $^ | ||
746 | target:: file2 file3 file3 | ||
747 | @echo $? | ||
748 | @echo $^ | ||
749 | ' | ||
750 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
751 | |||
752 | # .DEFAULT rules with no commands or some prerequisites are ignored. | ||
753 | # .DEFAULT rules with commands can be redefined. | ||
754 | testing "make: .DEFAULT rule" \ | ||
755 | "make -f - default" "default2\n" "" ' | ||
756 | .DEFAULT: ignored | ||
757 | .DEFAULT: | ||
758 | @echo default1 | ||
759 | .DEFAULT: | ||
760 | @echo default2 | ||
761 | target: | ||
762 | ' | ||
763 | |||
764 | testing "make: double-colon rule" \ | ||
765 | "make -f -" "target1\ntarget2\n" "" ' | ||
766 | target:: | ||
767 | @echo target1 | ||
768 | target:: | ||
769 | @echo target2 | ||
770 | ' | ||
771 | |||
772 | # Double-colon rules didn't work properly if their target was phony: | ||
773 | # - they didn't ignore the presence of a file matching the target name; | ||
774 | # - they were also invoked as if they were a single-colon rule. | ||
775 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
776 | touch -t 202206171200 file1 | ||
777 | touch -t 202206171201 target | ||
778 | testing "make phony target of double-colon rule" \ | ||
779 | "make -f - 2>&1" \ | ||
780 | "unconditional\nconditional\n" "" ' | ||
781 | .PHONY: target | ||
782 | target:: | ||
783 | @echo unconditional | ||
784 | target:: file1 | ||
785 | @echo conditional | ||
786 | file1: | ||
787 | @touch file1 | ||
788 | ' | ||
789 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
790 | |||
791 | # GNU make and BSD make don't allow the use of inference rules | ||
792 | # for phony targets. In POSIX mode the output is "phony.xyz\n". | ||
793 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
794 | touch phony.xyz | ||
795 | testing "make don't use inference rule for phony target" \ | ||
796 | "make -f -" "make: nothing to be done for phony\n" "" ' | ||
797 | .PHONY: phony | ||
798 | .SUFFIXES: .xyz | ||
799 | .xyz: | ||
800 | @echo $< | ||
801 | phony: | ||
802 | ' | ||
803 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
804 | |||
805 | exit $FAILCOUNT | ||