commit 5519266

shrub  ·  2026-05-05 18:37:04 +0000 UTC
parent fd3a8d1
handle .PHONY
6 files changed,  +30, -0
+5, -0
 1@@ -278,6 +278,7 @@ genninjafile(const struct Graph *graph, const char *path, const char *prefix, in
 2 	if (!fp)
 3 		return -1;
 4 	fprintf(fp, "# this file was generated from a makefile by shinobi\n");
 5+	fprintf(fp, "build __shin_always_build__: phony\n\n");
 6 	ruleid = 0;
 7 	rules = 0;
 8 	nrules = 0;
 9@@ -305,6 +306,8 @@ genninjafile(const struct Graph *graph, const char *path, const char *prefix, in
10 				free(cmd);
11 			}
12 			fprintf(fp, "build %s: r%d", graph->v[i].name, id);
13+			if (graph->v[i].phony)
14+				fprintf(fp, " __shin_always_build__");
15 			for (j = 0; j < graph->v[i].prereqs.n; j++)
16 				fprintf(fp, " %s", graph->v[i].prereqs.v[j]);
17 			if (graph->v[i].order_only.n) {
18@@ -315,6 +318,8 @@ genninjafile(const struct Graph *graph, const char *path, const char *prefix, in
19 			fprintf(fp, "\n\n");
20 		} else if (graph->v[i].defined || graph->v[i].prereqs.n > 0 || graph->v[i].order_only.n > 0) {
21 			fprintf(fp, "build %s: phony", graph->v[i].name);
22+			if (graph->v[i].phony)
23+				fprintf(fp, " __shin_always_build__");
24 			for (j = 0; j < graph->v[i].prereqs.n; j++)
25 				fprintf(fp, " %s", graph->v[i].prereqs.v[j]);
26 			if (graph->v[i].order_only.n) {
+4, -0
 1@@ -315,8 +315,11 @@ evalnodes(const struct NodeList *in, struct RuleSet *out, struct EvalCtx *ctx)
 2 			break;
 3 		}
 4 	}
 5+	if (out)
 6+		addwords(&out->phony, &targets.phony);
 7 	if (out)
 8 		out->posix = targets.posix;
 9+	freestrs(&targets.phony);
10 	return 0;
11 }
12 
13@@ -396,6 +399,7 @@ freeruleset(struct RuleSet *ruleset)
14 	freeassigns(ruleset->vars, ruleset->nvars);
15 	freeassigns(ruleset->tvars, ruleset->ntvars);
16 	freerules(ruleset->rules, ruleset->nrules);
17+	freestrs(&ruleset->phony);
18 	memset(ruleset, 0, sizeof(*ruleset));
19 }
20 
+8, -0
 1@@ -21,6 +21,7 @@ struct TAssign {
 2 struct GraphState {
 3 	struct Graph *graph;
 4 	struct Env env;
 5+	const struct StrList *phony;
 6 	const struct RuleNode *rules;
 7 	size_t nrules;
 8 	struct PatRules patterns;
 9@@ -178,6 +179,8 @@ addrule(struct GraphState *gs, const char *name, const struct RuleNode *rule)
10 	}
11 	t->defined = 1;
12 	t->dcolon = rule->dcolon;
13+	if (hasword(gs->phony, name))
14+		t->phony = 1;
15 	for (i = 0; i < rule->prereqs.n; i++)
16 		addglobword(&prereqs, rule->prereqs.v[i]);
17 	for (i = 0; i < rule->order_only.n; i++)
18@@ -202,6 +205,8 @@ addrule(struct GraphState *gs, const char *name, const struct RuleNode *rule)
19 			memset(t, 0, sizeof(*t));
20 			t->name = intern(prereqs.v[i]);
21 		}
22+		if (hasword(gs->phony, t->name))
23+			t->phony = 1;
24 		memset(&penv, 0, sizeof(penv));
25 		memset(&pctx, 0, sizeof(pctx));
26 		pctx.env = &penv;
27@@ -244,6 +249,7 @@ buildgraph(const struct RuleSet *ruleset, struct Graph *graph)
28 	memset(&gs, 0, sizeof(gs));
29 	memset(&ctx, 0, sizeof(ctx));
30 	gs.graph = graph;
31+	gs.phony = &ruleset->phony;
32 	seedenv(&gs.env, ruleset->posix, ruleset->envoverride);
33 	gs.rules = ruleset->rules;
34 	gs.nrules = ruleset->nrules;
35@@ -320,6 +326,8 @@ buildgraph(const struct RuleSet *ruleset, struct Graph *graph)
36 					nt = &graph->v[graph->n++];
37 					memset(nt, 0, sizeof(*nt));
38 					nt->name = intern(prereq);
39+					if (hasword(gs.phony, nt->name))
40+						nt->phony = 1;
41 					t = &graph->v[i];
42 				}
43 			}
+1, -0
1@@ -23,6 +23,7 @@ struct EvalCtx {
2 
3 struct SpecialTargets {
4 	int posix;
5+	struct StrList phony;
6 	char recipeprefix;
7 };
8 
+2, -0
 1@@ -173,6 +173,7 @@ struct RuleSet {
 2 	size_t ntvars;
 3 	struct RuleNode *rules;
 4 	size_t nrules;
 5+	struct StrList phony;
 6 	int posix;
 7 	int envoverride;
 8 };
 9@@ -200,6 +201,7 @@ struct Target {
10 	struct Env env;
11 	int dcolon;
12 	int defined;
13+	int phony;
14 };
15 
16 struct SubGraph;
+10, -0
 1@@ -7,6 +7,7 @@ void
 2 initspecialtargets(struct SpecialTargets *targets)
 3 {
 4 	targets->posix = 0;
 5+	memset(&targets->phony, 0, sizeof(targets->phony));
 6 	targets->recipeprefix = '\t';
 7 }
 8 
 9@@ -26,9 +27,18 @@ updatespecialassign(struct SpecialTargets *targets, const char *lhs, const char
10 int
11 handlespecialrule(struct SpecialTargets *targets, const struct RuleNode *rule)
12 {
13+	size_t i;
14+
15 	if (rule->targets.n == 1 && strcmp(rule->targets.v[0], ".POSIX") == 0) {
16 		targets->posix = 1;
17 		return 1;
18 	}
19+	if (rule->targets.n == 1 && strcmp(rule->targets.v[0], ".PHONY") == 0) {
20+		for (i = 0; i < rule->prereqs.n; i++) {
21+			if (!hasword(&targets->phony, rule->prereqs.v[i]))
22+				addstr(&targets->phony, rule->prereqs.v[i]);
23+		}
24+		return 1;
25+	}
26 	return 0;
27 }