aboutsummaryrefslogtreecommitdiffstats
path: root/main/samurai/0001-Fix-manifest-rebuild-when-it-was-pruned-due-to-resta.patch
blob: eaabb4019cebd8b725d98b7a917dbd9d76da99ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
From c7f1cfd9ed674936e21f99f8c18608b97685d5a7 Mon Sep 17 00:00:00 2001
From: Michael Forney <mforney@mforney.org>
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