aboutsummaryrefslogtreecommitdiff
path: root/miscutils/make.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2025-09-03 11:17:48 +0100
committerRon Yorston <rmy@pobox.com>2025-09-03 11:17:48 +0100
commitd8086da8bfbf76b9910d04e3e7f646ebc7f4b593 (patch)
treeeb75998187c8326e6a36b9b029b3624392dc6bea /miscutils/make.c
parent2c94f4417538b1b2bbe499b7681d389ea72a08ce (diff)
downloadbusybox-w32-d8086da8bfbf76b9910d04e3e7f646ebc7f4b593.tar.gz
busybox-w32-d8086da8bfbf76b9910d04e3e7f646ebc7f4b593.tar.bz2
busybox-w32-d8086da8bfbf76b9910d04e3e7f646ebc7f4b593.zip
make: override commands for single-colon target rule
If more than one single-colon target rule has commands only the last set of commands should be used. Previously the presence of more than one single-colon target rule with commands was treated as an error. Adds 88-112 bytes.
Diffstat (limited to '')
-rw-r--r--miscutils/make.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/miscutils/make.c b/miscutils/make.c
index a165274aa..8026917b3 100644
--- a/miscutils/make.c
+++ b/miscutils/make.c
@@ -276,6 +276,7 @@ struct globals {
276 time_t ar_mtime; 276 time_t ar_mtime;
277 int lineno; // Physical line number in file 277 int lineno; // Physical line number in file
278 int dispno; // Line number for display purposes 278 int dispno; // Line number for display purposes
279 struct cmd *curr_cmd;
279 const char *rulepos; 280 const char *rulepos;
280 int rule_idx; 281 int rule_idx;
281#define IF_MAX 10 282#define IF_MAX 10
@@ -307,6 +308,7 @@ struct globals {
307#define ar_mtime (G.ar_mtime) 308#define ar_mtime (G.ar_mtime)
308#define lineno (G.lineno) 309#define lineno (G.lineno)
309#define dispno (G.dispno) 310#define dispno (G.dispno)
311#define curr_cmd (G.curr_cmd)
310#define rulepos (G.rulepos) 312#define rulepos (G.rulepos)
311#define rule_idx (G.rule_idx) 313#define rule_idx (G.rule_idx)
312#define clevel (G.clevel) 314#define clevel (G.clevel)
@@ -338,9 +340,20 @@ static struct name *dyndep(struct name *np, struct rule *infrule,
338static void 340static void
339vwarning(FILE *stream, const char *msg, va_list list) 341vwarning(FILE *stream, const char *msg, va_list list)
340{ 342{
343 const char *m = NULL;
344 int d = 0;
345
346 if (curr_cmd) {
347 m = curr_cmd->c_makefile;
348 d = curr_cmd->c_dispno;
349 } else if (makefile) {
350 m = makefile;
351 d = dispno;
352 }
353
341 fprintf(stream, "%s: ", applet_name); 354 fprintf(stream, "%s: ", applet_name);
342 if (makefile) 355 if (m)
343 fprintf(stream, "(%s:%d): ", makefile, dispno); 356 fprintf(stream, "(%s:%d): ", m, d);
344 vfprintf(stream, msg, list); 357 vfprintf(stream, msg, list);
345 fputc('\n', stream); 358 fputc('\n', stream);
346} 359}
@@ -726,6 +739,7 @@ addrule(struct name *np, struct depend *dp, struct cmd *cp, int flag)
726{ 739{
727 struct rule *rp; 740 struct rule *rp;
728 struct rule **rpp; 741 struct rule **rpp;
742 struct cmd *old_cp;
729 743
730 // Can't mix single-colon and double-colon rules 744 // Can't mix single-colon and double-colon rules
731 if (!posix && (np->n_flag & N_TARGET)) { 745 if (!posix && (np->n_flag & N_TARGET)) {
@@ -742,7 +756,7 @@ addrule(struct name *np, struct depend *dp, struct cmd *cp, int flag)
742 return; 756 return;
743 } 757 }
744 758
745 if (cp && !(np->n_flag & N_DOUBLE) && getcmd(np)) { 759 if (cp && !(np->n_flag & N_DOUBLE) && (old_cp = getcmd(np))) {
746 // Handle the inference rule redefinition case 760 // Handle the inference rule redefinition case
747 // .DEFAULT rule can also be redefined (as an extension). 761 // .DEFAULT rule can also be redefined (as an extension).
748 if ((np->n_flag & N_INFERENCE) 762 if ((np->n_flag & N_INFERENCE)
@@ -751,7 +765,17 @@ addrule(struct name *np, struct depend *dp, struct cmd *cp, int flag)
751 freerules(np->n_rule); 765 freerules(np->n_rule);
752 np->n_rule = NULL; 766 np->n_rule = NULL;
753 } else { 767 } else {
754 error("commands defined twice for target %s", np->n_name); 768 // We're adding commands to a single colon rule which
769 // already has some. Clear the old ones first.
770 warning("overriding rule for target %s", np->n_name);
771 curr_cmd = old_cp;
772 warning("previous rule for target %s", np->n_name);
773 curr_cmd = NULL;
774
775 for (rp = np->n_rule; rp; rp = rp->r_next) {
776 freecmds(rp->r_cmd);
777 rp->r_cmd = NULL;
778 }
755 } 779 }
756 } 780 }
757 781
@@ -2602,8 +2626,7 @@ docmds(struct name *np, struct cmd *cp)
2602 uint32_t ssilent, signore, sdomake; 2626 uint32_t ssilent, signore, sdomake;
2603 2627
2604 // Location of command in makefile (for use in error messages) 2628 // Location of command in makefile (for use in error messages)
2605 makefile = cp->c_makefile; 2629 curr_cmd = cp;
2606 dispno = cp->c_dispno;
2607 opts &= ~OPT_make; // We want to know if $(MAKE) is expanded 2630 opts &= ~OPT_make; // We want to know if $(MAKE) is expanded
2608 q = command = expand_macros(cp->c_cmd, FALSE); 2631 q = command = expand_macros(cp->c_cmd, FALSE);
2609 ssilent = silent || (np->n_flag & N_SILENT) || dotouch; 2632 ssilent = silent || (np->n_flag & N_SILENT) || dotouch;
@@ -2697,7 +2720,7 @@ docmds(struct name *np, struct cmd *cp)
2697 estat = MAKE_DIDSOMETHING; 2720 estat = MAKE_DIDSOMETHING;
2698 } 2721 }
2699 2722
2700 makefile = NULL; 2723 curr_cmd = NULL;
2701 return estat; 2724 return estat;
2702} 2725}
2703 2726