aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/make.c142
1 files changed, 92 insertions, 50 deletions
diff --git a/miscutils/make.c b/miscutils/make.c
index 856ecbff0..bc84e8242 100644
--- a/miscutils/make.c
+++ b/miscutils/make.c
@@ -28,7 +28,7 @@
28//config: - '--posix' command line option 28//config: - '--posix' command line option
29//config: - PDPMAKE_POSIXLY_CORRECT environment variable 29//config: - PDPMAKE_POSIXLY_CORRECT environment variable
30//config: Enable this if you want to check whether your makefiles are 30//config: Enable this if you want to check whether your makefiles are
31//config: POSIX compliant. This adds about 1.6 kb. 31//config: POSIX compliant. This adds about 1.7 kb.
32 32
33//applet:IF_MAKE(APPLET(make, BB_DIR_USR_BIN, BB_SUID_DROP)) 33//applet:IF_MAKE(APPLET(make, BB_DIR_USR_BIN, BB_SUID_DROP))
34//applet:IF_PDPMAKE(APPLET_ODDNAME(pdpmake, make, BB_DIR_USR_BIN, BB_SUID_DROP, make)) 34//applet:IF_PDPMAKE(APPLET_ODDNAME(pdpmake, make, BB_DIR_USR_BIN, BB_SUID_DROP, make))
@@ -37,7 +37,7 @@
37 37
38//usage:#define make_trivial_usage 38//usage:#define make_trivial_usage
39//usage: IF_FEATURE_MAKE_POSIX( 39//usage: IF_FEATURE_MAKE_POSIX(
40//usage: "[--posix] [-C DIR] [-f FILE] [-j NUM] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..." 40//usage: "[--posix] [-C DIR] [-f FILE] [-j NUM] [-x PRAG] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..."
41//usage: ) 41//usage: )
42//usage: IF_NOT_FEATURE_MAKE_POSIX( 42//usage: IF_NOT_FEATURE_MAKE_POSIX(
43//usage: "[-C DIR] [-f FILE] [-j NUM] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..." 43//usage: "[-C DIR] [-f FILE] [-j NUM] [-eiknpqrsSt] [MACRO[::]=VAL]... [TARGET]..."
@@ -50,6 +50,9 @@
50//usage: "\n -C DIR Change to DIR" 50//usage: "\n -C DIR Change to DIR"
51//usage: "\n -f FILE Makefile" 51//usage: "\n -f FILE Makefile"
52//usage: "\n -j NUM Jobs to run in parallel (not implemented)" 52//usage: "\n -j NUM Jobs to run in parallel (not implemented)"
53//usage: IF_FEATURE_MAKE_POSIX(
54//usage: "\n -x PRAG Make POSIX mode less strict"
55//usage: )
53//usage: "\n -e Environment variables override macros in makefiles" 56//usage: "\n -e Environment variables override macros in makefiles"
54//usage: "\n -i Ignore exit status" 57//usage: "\n -i Ignore exit status"
55//usage: "\n -k Continue on error" 58//usage: "\n -k Continue on error"
@@ -69,28 +72,52 @@
69#define POSIX_2017 (posix && !(pragma & P_POSIX_202X)) 72#define POSIX_2017 (posix && !(pragma & P_POSIX_202X))
70 73
71#define OPTSTR1 "eij:+knqrsSt" 74#define OPTSTR1 "eij:+knqrsSt"
75#if ENABLE_FEATURE_MAKE_POSIX
76#define OPTSTR2 "pf:*C:*x:*"
77#else
72#define OPTSTR2 "pf:*C:*" 78#define OPTSTR2 "pf:*C:*"
79#endif
73 80
74enum { 81enum {
75 OPT_e = (1 << 0), 82 OPTBIT_e = 0,
76 OPT_i = (1 << 1), 83 OPTBIT_i,
77 OPT_j = (1 << 2), 84 OPTBIT_j,
78 OPT_k = (1 << 3), 85 OPTBIT_k,
79 OPT_n = (1 << 4), 86 OPTBIT_n,
80 OPT_q = (1 << 5), 87 OPTBIT_q,
81 OPT_r = (1 << 6), 88 OPTBIT_r,
82 OPT_s = (1 << 7), 89 OPTBIT_s,
83 OPT_S = (1 << 8), 90 OPTBIT_S,
84 OPT_t = (1 << 9), 91 OPTBIT_t,
92 OPTBIT_p,
93 OPTBIT_f,
94 OPTBIT_C,
95 IF_FEATURE_MAKE_POSIX(OPTBIT_x,)
96 OPTBIT_precious,
97 OPTBIT_phony,
98 OPTBIT_include,
99 OPTBIT_make,
100
101 OPT_e = (1 << OPTBIT_e),
102 OPT_i = (1 << OPTBIT_i),
103 OPT_j = (1 << OPTBIT_j),
104 OPT_k = (1 << OPTBIT_k),
105 OPT_n = (1 << OPTBIT_n),
106 OPT_q = (1 << OPTBIT_q),
107 OPT_r = (1 << OPTBIT_r),
108 OPT_s = (1 << OPTBIT_s),
109 OPT_S = (1 << OPTBIT_S),
110 OPT_t = (1 << OPTBIT_t),
85 // These options aren't allowed in MAKEFLAGS 111 // These options aren't allowed in MAKEFLAGS
86 OPT_p = (1 << 10), 112 OPT_p = (1 << OPTBIT_p),
87 OPT_f = (1 << 11), 113 OPT_f = (1 << OPTBIT_f),
88 OPT_C = (1 << 12), 114 OPT_C = (1 << OPTBIT_C),
115 OPT_x = IF_FEATURE_MAKE_POSIX((1 << OPTBIT_x)) + 0,
89 // The following aren't command line options and must be last 116 // The following aren't command line options and must be last
90 OPT_precious = (1 << 13), 117 OPT_precious = (1 << OPTBIT_precious),
91 OPT_phony = (1 << 14), 118 OPT_phony = (1 << OPTBIT_phony),
92 OPT_include = (1 << 15), 119 OPT_include = (1 << OPTBIT_include),
93 OPT_make = (1 << 16), 120 OPT_make = (1 << OPTBIT_make),
94}; 121};
95 122
96// Options in OPTSTR1 that aren't included in MAKEFLAGS 123// Options in OPTSTR1 that aren't included in MAKEFLAGS
@@ -169,7 +196,7 @@ struct macro {
169#define M_IMMEDIATE 8 // immediate-expansion macro is being defined 196#define M_IMMEDIATE 8 // immediate-expansion macro is being defined
170#define M_VALID 16 // assert macro name is valid 197#define M_VALID 16 // assert macro name is valid
171 198
172// Constants for PRAGMA. Order must match strings in addrule(). 199// Constants for PRAGMA. Order must match strings in set_pragma().
173#define P_MACRO_NAME 0x01 200#define P_MACRO_NAME 0x01
174#define P_TARGET_NAME 0x02 201#define P_TARGET_NAME 0x02
175#define P_COMMAND_COMMENT 0x04 202#define P_COMMAND_COMMENT 0x04
@@ -194,12 +221,11 @@ struct globals {
194#define IF_MAX 10 221#define IF_MAX 10
195 uint8_t clevel; 222 uint8_t clevel;
196 uint8_t cstate[IF_MAX + 1]; 223 uint8_t cstate[IF_MAX + 1];
224 int numjobs;
197#if ENABLE_FEATURE_MAKE_POSIX 225#if ENABLE_FEATURE_MAKE_POSIX
198 bool posix; 226 bool posix;
199 bool seen_first; 227 bool seen_first;
200#endif 228 llist_t *pragmas;
201 int numjobs;
202#if ENABLE_FEATURE_MAKE_POSIX
203 unsigned char pragma; 229 unsigned char pragma;
204#endif 230#endif
205} FIX_ALIASING; 231} FIX_ALIASING;
@@ -223,16 +249,14 @@ struct globals {
223#define rulepos (G.rulepos) 249#define rulepos (G.rulepos)
224#define clevel (G.clevel) 250#define clevel (G.clevel)
225#define cstate (G.cstate) 251#define cstate (G.cstate)
252#define numjobs (G.numjobs)
226#if ENABLE_FEATURE_MAKE_POSIX 253#if ENABLE_FEATURE_MAKE_POSIX
227#define posix (G.posix) 254#define posix (G.posix)
228#define seen_first (G.seen_first) 255#define seen_first (G.seen_first)
229#else 256#define pragmas (G.pragmas)
230#define posix 0
231#endif
232#define numjobs (G.numjobs)
233#if ENABLE_FEATURE_MAKE_POSIX
234#define pragma (G.pragma) 257#define pragma (G.pragma)
235#else 258#else
259#define posix 0
236#define pragma 0 260#define pragma 0
237#endif 261#endif
238 262
@@ -432,9 +456,9 @@ newname(const char *name)
432#if ENABLE_FEATURE_MAKE_POSIX 456#if ENABLE_FEATURE_MAKE_POSIX
433 error("invalid target name '%s'%s", name, 457 error("invalid target name '%s'%s", name,
434 potentially_valid_target(name) ? 458 potentially_valid_target(name) ?
435 ". Allow with .PRAGMA: target_name" : ""); 459 ": allow with pragma target_name" : "");
436#else 460#else
437 error("invalid target name '%s'"); 461 error("invalid target name '%s'", name);
438#endif 462#endif
439 463
440 bucket = getbucket(name); 464 bucket = getbucket(name);
@@ -509,6 +533,28 @@ inc_ref(void *vp)
509 return vp; 533 return vp;
510} 534}
511 535
536#if ENABLE_FEATURE_MAKE_POSIX
537static void
538set_pragma(const char *name)
539{
540 // Order must match constants above.
541 static const char *p_name =
542 "macro_name\0"
543 "target_name\0"
544 "command_comment\0"
545 "empty_suffix\0"
546 "posix_202x\0"
547 ;
548 int idx = index_in_strings(p_name, name);
549
550 if (idx != -1) {
551 pragma |= 1 << idx;
552 return;
553 }
554 warning("invalid pragma '%s'", name);
555}
556#endif
557
512/* 558/*
513 * Add a new rule to a target. This checks to see if commands already 559 * Add a new rule to a target. This checks to see if commands already
514 * exist for the target. If flag is TRUE the target can have multiple 560 * exist for the target. If flag is TRUE the target can have multiple
@@ -569,21 +615,8 @@ addrule(struct name *np, struct depend *dp, struct cmd *cp, int flag)
569 np->n_flag |= N_DOUBLE; 615 np->n_flag |= N_DOUBLE;
570#if ENABLE_FEATURE_MAKE_POSIX 616#if ENABLE_FEATURE_MAKE_POSIX
571 if (strcmp(np->n_name, ".PRAGMA") == 0) { 617 if (strcmp(np->n_name, ".PRAGMA") == 0) {
572 // Order must match constants above
573 static const char *p_name =
574 "macro_name\0"
575 "target_name\0"
576 "command_comment\0"
577 "empty_suffix\0"
578 "posix_202x\0"
579 ;
580
581 for (; dp; dp = dp->d_next) { 618 for (; dp; dp = dp->d_next) {
582 int idx = index_in_strings(p_name, dp->d_name->n_name); 619 set_pragma(dp->d_name->n_name);
583 if (idx != -1)
584 pragma |= 1 << idx;
585 else
586 warning("invalid .PRAGMA %s", dp->d_name->n_name);
587 } 620 }
588 } 621 }
589#endif 622#endif
@@ -657,7 +690,7 @@ setmacro(const char *name, const char *val, int level)
657#if ENABLE_FEATURE_MAKE_POSIX 690#if ENABLE_FEATURE_MAKE_POSIX
658 error("invalid macro name '%s'%s", name, 691 error("invalid macro name '%s'%s", name,
659 potentially_valid_macro(name) ? 692 potentially_valid_macro(name) ?
660 ". Allow with .PRAGMA: macro_name" : ""); 693 ": allow with pragma macro_name" : "");
661#else 694#else
662 error("invalid macro name '%s'", name); 695 error("invalid macro name '%s'", name);
663#endif 696#endif
@@ -1155,7 +1188,7 @@ expand_macros(const char *str, int except_dollar)
1155 if (posix && !(pragma & P_EMPTY_SUFFIX) && lenf == 0) 1188 if (posix && !(pragma & P_EMPTY_SUFFIX) && lenf == 0)
1156 error("empty suffix%s", 1189 error("empty suffix%s",
1157 !ENABLE_FEATURE_MAKE_POSIX ? "" : 1190 !ENABLE_FEATURE_MAKE_POSIX ? "" :
1158 ". Allow with .PRAGMA: empty_suffix"); 1191 ": allow with pragma empty_suffix");
1159 find_suff = expfind; 1192 find_suff = expfind;
1160 repl_suff = replace; 1193 repl_suff = replace;
1161 lenr = strlen(repl_suff); 1194 lenr = strlen(repl_suff);
@@ -1544,7 +1577,7 @@ process_command(char *s)
1544 t = strchr(s, '#'); 1577 t = strchr(s, '#');
1545 if (t) { 1578 if (t) {
1546 *t = '\0'; 1579 *t = '\0';
1547 warning("comment in command. Allow with .PRAGMA: command_comment"); 1580 warning("comment in command removed: keep with pragma command_comment");
1548 } 1581 }
1549 } 1582 }
1550 1583
@@ -2409,7 +2442,7 @@ print_details(void)
2409 2442
2410/* 2443/*
2411 * Process options from an argv array. If from_env is non-zero we're 2444 * Process options from an argv array. If from_env is non-zero we're
2412 * handling options from MAKEFLAGS so skip '-C', '-f' and '-p'. 2445 * handling options from MAKEFLAGS so skip '-C', '-f', '-p' and '-x'.
2413 */ 2446 */
2414static uint32_t 2447static uint32_t
2415process_options(char **argv, int from_env) 2448process_options(char **argv, int from_env)
@@ -2417,8 +2450,9 @@ process_options(char **argv, int from_env)
2417 uint32_t flags; 2450 uint32_t flags;
2418 2451
2419 flags = getopt32(argv, "^" OPTSTR1 OPTSTR2 "\0k-S:S-k", 2452 flags = getopt32(argv, "^" OPTSTR1 OPTSTR2 "\0k-S:S-k",
2420 &numjobs, &makefiles, &dirs); 2453 &numjobs, &makefiles, &dirs
2421 if (from_env && (flags & (OPT_C | OPT_f | OPT_p))) 2454 IF_FEATURE_MAKE_POSIX(, &pragmas));
2455 if (from_env && (flags & (OPT_C | OPT_f | OPT_p | OPT_x)))
2422 error("invalid MAKEFLAGS"); 2456 error("invalid MAKEFLAGS");
2423 if (posix && (flags & OPT_C)) 2457 if (posix && (flags & OPT_C))
2424 error("-C not allowed"); 2458 error("-C not allowed");
@@ -2656,6 +2690,9 @@ int make_main(int argc UNUSED_PARAM, char **argv)
2656 const char *path, *newpath = NULL; 2690 const char *path, *newpath = NULL;
2657 char **fargv, **fargv0; 2691 char **fargv, **fargv0;
2658 const char *dir, *file; 2692 const char *dir, *file;
2693#if ENABLE_FEATURE_MAKE_POSIX
2694 const char *prag;
2695#endif
2659 char def_make[] = "makefile"; 2696 char def_make[] = "makefile";
2660 int estat; 2697 int estat;
2661 FILE *ifd; 2698 FILE *ifd;
@@ -2719,6 +2756,11 @@ int make_main(int argc UNUSED_PARAM, char **argv)
2719 } 2756 }
2720 } 2757 }
2721 2758
2759#if ENABLE_FEATURE_MAKE_POSIX
2760 while ((prag = llist_pop(&pragmas)))
2761 set_pragma(prag);
2762#endif
2763
2722#if !ENABLE_PLATFORM_MINGW32 2764#if !ENABLE_PLATFORM_MINGW32
2723 init_signal(SIGHUP); 2765 init_signal(SIGHUP);
2724 init_signal(SIGTERM); 2766 init_signal(SIGTERM);