aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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" \