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 }