aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-05-22 12:44:01 +0100
committerRon Yorston <rmy@pobox.com>2024-05-22 12:44:01 +0100
commitc6b525f2afde0833d21b3f0132961a3b0178bbbb (patch)
tree34826922d0d52a0420f29059a4a9f014e6b48f79
parenteaa8695b76849d8156826a8919a591555c81a3dd (diff)
downloadbusybox-w32-c6b525f2afde0833d21b3f0132961a3b0178bbbb.tar.gz
busybox-w32-c6b525f2afde0833d21b3f0132961a3b0178bbbb.tar.bz2
busybox-w32-c6b525f2afde0833d21b3f0132961a3b0178bbbb.zip
make: set $< and $* for target rules
POSIX only requires $< and $* to be set for inference rules, not target rules. As an extension allow them to be set for target rules, as in GNU make. This may or may not be useful. In POSIX mode, when $< and $* are only set for inference rules, they're set to an empty string for target rules. This avoids the possibility of stale values being used. Adds 64-80 bytes. (GitHub issue #407)
-rw-r--r--miscutils/make.c33
-rwxr-xr-xtestsuite/make.tests13
2 files changed, 40 insertions, 6 deletions
diff --git a/miscutils/make.c b/miscutils/make.c
index f594e196b..c69dcec8a 100644
--- a/miscutils/make.c
+++ b/miscutils/make.c
@@ -2298,7 +2298,7 @@ make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc,
2298 char *dedup, struct name *implicit) 2298 char *dedup, struct name *implicit)
2299{ 2299{
2300 int estat; 2300 int estat;
2301 char *name, *member = NULL, *base; 2301 char *name, *member = NULL, *base = NULL, *prereq = NULL;
2302 2302
2303 name = splitlib(np->n_name, &member); 2303 name = splitlib(np->n_name, &member);
2304 setmacro("?", oodate, 0 | M_VALID); 2304 setmacro("?", oodate, 0 | M_VALID);
@@ -2308,12 +2308,33 @@ make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc,
2308 } 2308 }
2309 setmacro("%", member, 0 | M_VALID); 2309 setmacro("%", member, 0 | M_VALID);
2310 setmacro("@", name, 0 | M_VALID); 2310 setmacro("@", name, 0 | M_VALID);
2311 if (implicit) { 2311 if (implicit || !posix) {
2312 setmacro("<", implicit->n_name, 0 | M_VALID); 2312 char *s;
2313
2314 // As an extension, if we're not dealing with an implicit
2315 // rule set $< to the first out-of-date prerequisite.
2316 if (implicit == NULL) {
2317 if (oodate) {
2318 s = strchr(oodate, ' ');
2319 if (s)
2320 *s = '\0';
2321 prereq = oodate;
2322 }
2323 } else
2324 prereq = implicit->n_name;
2325
2313 base = member ? member : name; 2326 base = member ? member : name;
2314 *suffix(base) = '\0'; 2327 s = suffix(base);
2315 setmacro("*", base, 0 | M_VALID); 2328 // As an extension, if we're not dealing with an implicit
2316 } 2329 // rule and the target ends with a known suffix, remove it
2330 // and set $* to the stem, else to an empty string.
2331 if (implicit == NULL && !is_suffix(s))
2332 base = NULL;
2333 else
2334 *s = '\0';
2335 }
2336 setmacro("<", prereq, 0 | M_VALID);
2337 setmacro("*", base, 0 | M_VALID);
2317 free(name); 2338 free(name);
2318 2339
2319 estat = docmds(np, cp); 2340 estat = docmds(np, cp);
diff --git a/testsuite/make.tests b/testsuite/make.tests
index fdbb4ccfc..5119a77d3 100755
--- a/testsuite/make.tests
+++ b/testsuite/make.tests
@@ -540,6 +540,19 @@ bar:
540 @echo $(BAR) 540 @echo $(BAR)
541' 541'
542 542
543# $* and $< are supported for target rules
544mkdir make.tempdir && cd make.tempdir || exit 1
545touch src.c src.h
546testing 'make support $* and $< for target rules' \
547 "make -f -" "src.c src.h\nsrc.o\nsrc\nsrc.c\n" "" '
548src.o: src.c src.h
549 @echo "$?"
550 @echo "$@"
551 @echo "$*"
552 @echo "$<"
553'
554cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
555
543# An empty original suffix indicates that every word should have 556# An empty original suffix indicates that every word should have
544# the new suffix added. If neither suffix is provided the words 557# the new suffix added. If neither suffix is provided the words
545# remain unchanged. 558# remain unchanged.