diff options
-rw-r--r-- | miscutils/make.c | 25 | ||||
-rwxr-xr-x | testsuite/make.tests | 32 |
2 files changed, 38 insertions, 19 deletions
diff --git a/miscutils/make.c b/miscutils/make.c index cc5e7ca92..df810677f 100644 --- a/miscutils/make.c +++ b/miscutils/make.c | |||
@@ -188,6 +188,7 @@ struct name { | |||
188 | #define N_SPECIAL 0x80 // Special target | 188 | #define N_SPECIAL 0x80 // Special target |
189 | #define N_MARK 0x100 // Mark for deduplication | 189 | #define N_MARK 0x100 // Mark for deduplication |
190 | #define N_PHONY 0x200 // Name is a phony target | 190 | #define N_PHONY 0x200 // Name is a phony target |
191 | #define N_INFERENCE 0x400 // Inference rule | ||
191 | 192 | ||
192 | // List of rules to build a target | 193 | // List of rules to build a target |
193 | struct rule { | 194 | struct rule { |
@@ -736,7 +737,10 @@ addrule(struct name *np, struct depend *dp, struct cmd *cp, int flag) | |||
736 | 737 | ||
737 | if (cp && !(np->n_flag & N_DOUBLE) && getcmd(np)) { | 738 | if (cp && !(np->n_flag & N_DOUBLE) && getcmd(np)) { |
738 | // Handle the inference rule redefinition case | 739 | // Handle the inference rule redefinition case |
739 | if ((np->n_flag & N_SPECIAL) && !dp) { | 740 | // .DEFAULT rule can also be redefined (as an extension). |
741 | if ((np->n_flag & N_INFERENCE) | ||
742 | && !(posix && (np->n_flag & N_SPECIAL)) | ||
743 | ) { | ||
740 | freerules(np->n_rule); | 744 | freerules(np->n_rule); |
741 | np->n_rule = NULL; | 745 | np->n_rule = NULL; |
742 | } else { | 746 | } else { |
@@ -2343,12 +2347,19 @@ input(FILE *fd, int ilevel) | |||
2343 | 2347 | ||
2344 | np = newname(files[i]); | 2348 | np = newname(files[i]); |
2345 | if (ttype != T_NORMAL) { | 2349 | if (ttype != T_NORMAL) { |
2346 | if (ttype == T_INFERENCE && posix) { | 2350 | if (ttype == T_INFERENCE) { |
2347 | if (semicolon_cmd) | 2351 | if (posix) { |
2348 | error_in_inference_rule("'; command'"); | 2352 | if (semicolon_cmd) |
2349 | seen_inference = TRUE; | 2353 | error_in_inference_rule("'; command'"); |
2354 | seen_inference = TRUE; | ||
2355 | } | ||
2356 | np->n_flag |= N_INFERENCE; | ||
2357 | } else if (strcmp(p, ".DEFAULT") == 0) { | ||
2358 | // .DEFAULT rule is a special case | ||
2359 | np->n_flag |= N_SPECIAL | N_INFERENCE; | ||
2360 | } else { | ||
2361 | np->n_flag |= N_SPECIAL; | ||
2350 | } | 2362 | } |
2351 | np->n_flag |= N_SPECIAL; | ||
2352 | } else if (!firstname) { | 2363 | } else if (!firstname) { |
2353 | firstname = np; | 2364 | firstname = np; |
2354 | } | 2365 | } |
@@ -2358,7 +2369,7 @@ input(FILE *fd, int ilevel) | |||
2358 | if (files != &p) | 2369 | if (files != &p) |
2359 | globfree(&gd); | 2370 | globfree(&gd); |
2360 | } | 2371 | } |
2361 | if (seen_inference && count != 1) | 2372 | if (posix && seen_inference && count != 1) |
2362 | error_in_inference_rule("multiple targets"); | 2373 | error_in_inference_rule("multiple targets"); |
2363 | 2374 | ||
2364 | // Prerequisites and commands will be unused if there were | 2375 | // Prerequisites and commands will be unused if there were |
diff --git a/testsuite/make.tests b/testsuite/make.tests index a12e50b8b..376bdcc15 100755 --- a/testsuite/make.tests +++ b/testsuite/make.tests | |||
@@ -12,18 +12,6 @@ target: | |||
12 | @echo target | 12 | @echo target |
13 | ' | 13 | ' |
14 | 14 | ||
15 | # .DEFAULT rules with no commands or some prerequisites are ignored. | ||
16 | # .DEFAULT rules with commands can be redefined. | ||
17 | testing "make .DEFAULT rule" \ | ||
18 | "make -f - default" "default2\n" "" ' | ||
19 | .DEFAULT: ignored | ||
20 | .DEFAULT: | ||
21 | @echo default1 | ||
22 | .DEFAULT: | ||
23 | @echo default2 | ||
24 | target: | ||
25 | ' | ||
26 | |||
27 | testing "make .DEFAULT rule for prerequisite" \ | 15 | testing "make .DEFAULT rule for prerequisite" \ |
28 | "make -f - 2>/dev/null" "source\n" "" ' | 16 | "make -f - 2>/dev/null" "source\n" "" ' |
29 | .DEFAULT: | 17 | .DEFAULT: |
@@ -721,6 +709,26 @@ target:: file2 file3 file3 | |||
721 | ' | 709 | ' |
722 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | 710 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null |
723 | 711 | ||
712 | # .DEFAULT rules with no commands or some prerequisites are ignored. | ||
713 | # .DEFAULT rules with commands can be redefined. | ||
714 | testing "make: .DEFAULT rule" \ | ||
715 | "make -f - default" "default2\n" "" ' | ||
716 | .DEFAULT: ignored | ||
717 | .DEFAULT: | ||
718 | @echo default1 | ||
719 | .DEFAULT: | ||
720 | @echo default2 | ||
721 | target: | ||
722 | ' | ||
723 | |||
724 | testing "make: double-colon rule" \ | ||
725 | "make -f -" "target1\ntarget2\n" "" ' | ||
726 | target:: | ||
727 | @echo target1 | ||
728 | target:: | ||
729 | @echo target2 | ||
730 | ' | ||
731 | |||
724 | # Double-colon rules didn't work properly if their target was phony: | 732 | # Double-colon rules didn't work properly if their target was phony: |
725 | # - they didn't ignore the presence of a file matching the target name; | 733 | # - they didn't ignore the presence of a file matching the target name; |
726 | # - they were also invoked as if they were a single-colon rule. | 734 | # - they were also invoked as if they were a single-colon rule. |