Skip to content

Commit 49b434d

Browse files
committed
mamake: fix %{?} for resume after interrupt (re: 0353bf2, f5d5318)
If the user interrupts the build while a target with multiple prerequisites is being generated, such as libast.a, the contents of %{?} is incorrect when restarting and resuming the build, because it only tracks targets updated during the current mamake run. If an interrupt occurs while building a static library (*.a) and the build is then resumed, this currently leads to the *.o targets made before the interrupt not being updated in a pre-existing *.a library (see use of %{?} in src/cmd/INIT/include/link_ar.mam). The fix: compare the timestamps of already-built prerequisites to the timestamp of the parent rule, and add each such prerequisite to %{?} if it is newer than the parent target. (This changes the behaviour of %{?} for rules with the 'virtual' attribute, because those are not bound to files and always start out with a timestamp of zero. But that's okay because %{?} has never been used within them.)
1 parent bf24651 commit 49b434d

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

src/cmd/INIT/README-mamake.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,11 @@ or referenced (`prev`) within the current rule.
167167
`%{^}` is a space-separated list of names of all the current rule's
168168
previously processed or referenced prerequisites.
169169

170-
`%{?}` is a space-separate list of the current rule's previously processed
171-
prerequisites that have been updated by a shell action (see `exec` below)
172-
during the current `mamake` run. Prerequisites that were already up to date,
173-
or prerequisites that do not contain a shell action, are not included.
170+
`%{?}` is a space-separated list of the current rule's previously processed
171+
prerequisites that were generated by a shell action (see `exec` below)
172+
more recently than the current rule's target.
173+
For rules with the `virtual` attribute, which have no target, `%{?}` will
174+
list all previously processed prerequisites that contain a shell action.
174175

175176
## Commands ##
176177

src/cmd/INIT/mamake.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* coded for portability
2929
*/
3030

31-
#define RELEASE_DATE "2025-01-05"
31+
#define RELEASE_DATE "2025-04-02"
3232
static char id[] = "\n@(#)$Id: mamake (ksh 93u+m) " RELEASE_DATE " $\0\n";
3333

3434
#if _PACKAGE_ast
@@ -238,6 +238,7 @@ typedef struct Rule_s /* rule item */
238238
int flags; /* RULE_* flags */
239239
int making; /* currently make()ing */
240240
time_t time; /* modification time */
241+
time_t parenttime; /* parent's modification time */
241242
unsigned int line; /* starting line in Mamfile */
242243
unsigned int endline; /* ending line in Mamfile */
243244
pid_t pid; /* PID of parallel bg job */
@@ -2280,6 +2281,13 @@ static void make(Rule_t *r, Makestate_t *parentstate)
22802281
propagate(r, NULL, &st.modtime);
22812282
r->flags |= RULE_updated;
22822283
}
2284+
else if (st.modtime > r->parenttime && r->flags & RULE_generated)
2285+
{
2286+
/* if we didn't generate the target in this run, but it's newer than the parent
2287+
* target, then the generation of the parent target was probably interrupted
2288+
* and then resumed in this run, so include this target in %{?} for consistency */
2289+
r->flags |= RULE_updated;
2290+
}
22832291
r->flags |= RULE_made;
22842292
if (!(r->flags & (RULE_dontcare|RULE_error|RULE_exists|RULE_generated|RULE_virtual)))
22852293
error_making(r, 0);
@@ -2390,6 +2398,7 @@ static void make(Rule_t *r, Makestate_t *parentstate)
23902398
{
23912399
/* make the target */
23922400
attributes(q, v);
2401+
q->parenttime = r->time;
23932402
make(q, NULL);
23942403
if (q->pid)
23952404
{

0 commit comments

Comments
 (0)