aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-05-28 11:54:51 +0100
committerRon Yorston <rmy@pobox.com>2024-05-28 11:54:51 +0100
commit208d9858409f823d533d1e95396dde00be03d7d3 (patch)
tree34c0ea21c8d1b23c2bc72909843b12bd1c0cb9ca
parent0224cfd5e5c8157e5bc74a81027fa508687abfbf (diff)
downloadbusybox-w32-208d9858409f823d533d1e95396dde00be03d7d3.tar.gz
busybox-w32-208d9858409f823d533d1e95396dde00be03d7d3.tar.bz2
busybox-w32-208d9858409f823d533d1e95396dde00be03d7d3.zip
make: fixes to -t option
The -t option (in general) causes targets to be touched instead of having build commands run to create them. There were two problems. The flag variable 'ssilent' in docmds was too small (uint8_t) to contain the value of 'dotouch' (uint32_t). Truncation of the value resulted in build commands being echoed when they shouldn't have been. The POSIX specification is unclear as to how build commands with a '+' prefix interact with touch. The rationale indicates that this feature was imported from GNU make, so the behaviour has been made to match what it does: if a '+' build command is run the target is not touched. The code has been rearranged to move the call to touch() up into docmds(). Adds 48 bytes.
-rw-r--r--miscutils/make.c67
-rwxr-xr-xtestsuite/make.tests26
2 files changed, 60 insertions, 33 deletions
diff --git a/miscutils/make.c b/miscutils/make.c
index 056cb2909..70fd30440 100644
--- a/miscutils/make.c
+++ b/miscutils/make.c
@@ -2295,6 +2295,31 @@ remove_target(void)
2295} 2295}
2296 2296
2297/* 2297/*
2298 * Update the modification time of a file to now.
2299 */
2300static void
2301touch(struct name *np)
2302{
2303 if (dryrun || !silent)
2304 printf("touch %s\n", np->n_name);
2305
2306 if (!dryrun) {
2307 const struct timespec timebuf[2] = {{0, UTIME_NOW}, {0, UTIME_NOW}};
2308
2309 if (utimensat(AT_FDCWD, np->n_name, timebuf, 0) < 0) {
2310 if (errno == ENOENT) {
2311 int fd = open(np->n_name, O_RDWR | O_CREAT, 0666);
2312 if (fd >= 0) {
2313 close(fd);
2314 return;
2315 }
2316 }
2317 warning("touch %s failed", np->n_name);
2318 }
2319 }
2320}
2321
2322/*
2298 * Do commands to make a target 2323 * Do commands to make a target
2299 */ 2324 */
2300static int 2325static int
@@ -2304,7 +2329,7 @@ docmds(struct name *np, struct cmd *cp)
2304 char *q, *command; 2329 char *q, *command;
2305 2330
2306 for (; cp; cp = cp->c_next) { 2331 for (; cp; cp = cp->c_next) {
2307 uint8_t ssilent, signore, sdomake; 2332 uint32_t ssilent, signore, sdomake;
2308 2333
2309 // Location of command in makefile (for use in error messages) 2334 // Location of command in makefile (for use in error messages)
2310 makefile = cp->c_makefile; 2335 makefile = cp->c_makefile;
@@ -2380,44 +2405,24 @@ docmds(struct name *np, struct cmd *cp)
2380 } 2405 }
2381 } 2406 }
2382 } 2407 }
2383 if (sdomake || dryrun || dotouch) 2408 if (sdomake || dryrun)
2384 estat = MAKE_DIDSOMETHING; 2409 estat = MAKE_DIDSOMETHING;
2385 free(command); 2410 free(command);
2386 } 2411 }
2387 makefile = NULL;
2388 return estat;
2389}
2390
2391/*
2392 * Update the modification time of a file to now.
2393 */
2394static void
2395touch(struct name *np)
2396{
2397 if (dryrun || !silent)
2398 printf("touch %s\n", np->n_name);
2399 2412
2400 if (!dryrun) { 2413 if (dotouch && !(np->n_flag & N_PHONY) && !(estat & MAKE_DIDSOMETHING)) {
2401 const struct timespec timebuf[2] = {{0, UTIME_NOW}, {0, UTIME_NOW}}; 2414 touch(np);
2402 2415 estat = MAKE_DIDSOMETHING;
2403 if (utimensat(AT_FDCWD, np->n_name, timebuf, 0) < 0) {
2404 if (errno == ENOENT) {
2405 int fd = open(np->n_name, O_RDWR | O_CREAT, 0666);
2406 if (fd >= 0) {
2407 close(fd);
2408 return;
2409 }
2410 }
2411 warning("touch %s failed", np->n_name);
2412 }
2413 } 2416 }
2417
2418 makefile = NULL;
2419 return estat;
2414} 2420}
2415 2421
2416static int 2422static int
2417make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, 2423make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc,
2418 char *dedup, struct name *implicit) 2424 char *dedup, struct name *implicit)
2419{ 2425{
2420 int estat;
2421 char *name, *member = NULL, *base = NULL, *prereq = NULL; 2426 char *name, *member = NULL, *base = NULL, *prereq = NULL;
2422 2427
2423 name = splitlib(np->n_name, &member); 2428 name = splitlib(np->n_name, &member);
@@ -2457,11 +2462,7 @@ make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc,
2457 setmacro("*", base, 0 | M_VALID); 2462 setmacro("*", base, 0 | M_VALID);
2458 free(name); 2463 free(name);
2459 2464
2460 estat = docmds(np, cp); 2465 return docmds(np, cp);
2461 if (dotouch && !(np->n_flag & N_PHONY))
2462 touch(np);
2463
2464 return estat;
2465} 2466}
2466 2467
2467/* 2468/*
diff --git a/testsuite/make.tests b/testsuite/make.tests
index 33e730602..c2b62532a 100755
--- a/testsuite/make.tests
+++ b/testsuite/make.tests
@@ -2,6 +2,7 @@
2 2
3. ./testing.sh 3. ./testing.sh
4unset MAKEFLAGS 4unset MAKEFLAGS
5rm -rf make.tempdir
5 6
6# testing "test name" "command" "expected result" "file input" "stdin" 7# testing "test name" "command" "expected result" "file input" "stdin"
7 8
@@ -116,6 +117,31 @@ baz:
116 @: 117 @:
117' 118'
118 119
120# The -t option touches files that are out-of-date unless the target
121# has no commands or they're already up-to-date.
122mkdir make.tempdir && cd make.tempdir || exit 1
123touch baz
124testing "make check -t option" \
125 "make -t -f - 2>/dev/null" "touch bar\n" "" '
126all: foo bar baz
127foo:
128bar:
129 @echo bar
130baz:
131 @echo baz
132'
133cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
134
135# Build commands with a '+' prefix are executed even with the -t option.
136mkdir make.tempdir && cd make.tempdir || exit 1
137testing "make execute build command with + prefix and -t" \
138 "make -t -f - 2>/dev/null" "OK\n" "" '
139all: bar
140bar:
141 @+echo OK
142'
143cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
144
119# A macro created using ::= remembers it's of type immediate-expansion. 145# A macro created using ::= remembers it's of type immediate-expansion.
120# Immediate expansion also occurs when += is used to append to such a macro. 146# Immediate expansion also occurs when += is used to append to such a macro.
121testing "make appending to immediate-expansion macro" \ 147testing "make appending to immediate-expansion macro" \