From c7f1cfd9ed674936e21f99f8c18608b97685d5a7 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Fri, 17 Jan 2020 12:53:59 -0800 Subject: [PATCH 1/4] Fix manifest rebuild when it was pruned due to restat If build.ninja depends on an output with `restat = 1`, it may get pruned if the output did not change. In this case, we can continue with the build, since the previously loaded manifest is still correct. To make sure that we can add new build targets and start a new build after executing the build for another target, add a function to reset the build state. Fixes #31. --- build.c | 17 +++++++++++++++++ build.h | 2 ++ samu.c | 10 +++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/build.c b/build.c index 7d50d1e..71dda17 100644 --- a/build.c +++ b/build.c @@ -32,6 +32,23 @@ static struct edge *work; static size_t nstarted, ntotal; static bool consoleused; +void +buildreset(void) { + struct edge *e; + struct node *n; + size_t i; + + for (e = alledges; e; e = e->allnext) { + e->flags = 0; + for (i = 0; i < e->nout; ++i) { + n = e->out[i]; + free(n->use); + n->nuse = 0; + n->use = NULL; + } + } +} + /* returns whether n1 is newer than n2, or false if n1 is NULL */ static bool isnewer(struct node *n1, struct node *n2) diff --git a/build.h b/build.h index fa221bd..6eb1988 100644 --- a/build.h +++ b/build.h @@ -7,6 +7,8 @@ struct buildoptions { extern struct buildoptions buildopts; +/* reset state, so a new build can be executed */ +void buildreset(void); /* schedule a particular target to be built */ void buildadd(struct node *); /* execute rules to build the scheduled targets */ diff --git a/samu.c b/samu.c index a489b0f..f09c808 100644 --- a/samu.c +++ b/samu.c @@ -240,9 +240,13 @@ retry: buildadd(n); if (n->dirty) { build(); - if (++tries > 100) - fatal("manifest '%s' dirty after 100 tries", manifest); - goto retry; + if (n->gen->flags & FLAG_DIRTY_OUT || n->gen->nprune > 0) { + if (++tries > 100) + fatal("manifest '%s' dirty after 100 tries", manifest); + goto retry; + } + /* manifest was pruned; reset state, then continue with build */ + buildreset(); } } -- 2.24.0