commit 11f2e54

shrub  ·  2026-05-15 22:10:34 +0000 UTC
parent 2eb5b83
handle remaking includes
3 files changed,  +47, -10
+32, -0
 1@@ -388,6 +388,10 @@ evalinclude(struct EvalCtx *ctx, const struct IncludeNode *inc)
 2 	char *exp;
 3 	size_t i;
 4 
 5+	struct RuleNode *makerule;
 6+
 7+	makerule = 0;
 8+
 9 	exp = expandstr(ctx, inc->path);
10 	memset(&paths, 0, sizeof(paths));
11 	splitwords(&paths, exp, strlen(exp));
12@@ -396,6 +400,34 @@ evalinclude(struct EvalCtx *ctx, const struct IncludeNode *inc)
13 		char *src;
14 
15 		src = readfile(paths.v[i]);
16+		if (!src) {
17+			size_t r, k;
18+
19+			makerule = 0;
20+			for (r = 0; r < ctx->out->nrules && !makerule; r++) {
21+				struct RuleNode *rule = &ctx->out->rules[r];
22+
23+				for (k = 0; k < rule->targets.n; k++) {
24+					if (strcmp(rule->targets.v[k], paths.v[i]) == 0) {
25+						makerule = rule;
26+						break;
27+					}
28+				}
29+			}
30+			if (makerule) {
31+				for (k = 0; k < makerule->recipes.n; k++) {
32+					char *cmd;
33+					int rc;
34+
35+					cmd = expandstr(ctx, makerule->recipes.v[k].body);
36+					rc = system(cmd);
37+					free(cmd);
38+					if (rc != 0)
39+						break;
40+				}
41+				src = readfile(paths.v[i]);
42+			}
43+		}
44 		if (!src) {
45 			if (!inc->optional)
46 				fprintf(stderr, "%s:%d: %s: No such file or directory\n",
+13, -8
 1@@ -572,16 +572,21 @@ preprocfile0(const char *path, const char *src_override, struct Pre *pre, struct
 2 				kwlen = haskw(trim, "-include") || haskw(trim, "sinclude") ? 8 : 7;
 3 				incarg = trimdup(trim + kwlen, strlen(trim + kwlen));
 4 				if (isplainpath(incarg)) {
 5-					free(trim);
 6 					rc = preprocinclude(dir, incarg, pre, inc, targets);
 7-					if (rc < 0 && !opt) {
 8-						fprintf(stderr, "%s:%d: %s: No such file or directory\n",
 9-						        line.path, line.line0, incarg);
10+					if (rc == 0) {
11+						free(incarg);
12+						free(line.path);
13+						free(line.text);
14+						continue;
15+					}
16+					/* keep unresolved includes in the stream so that eval time
17+					 * include handling can attempt to remake them from rules */
18+					if (opt) {
19+						free(incarg);
20+						free(line.path);
21+						free(line.text);
22+						continue;
23 					}
24-					free(incarg);
25-					free(line.path);
26-					free(line.text);
27-					continue;
28 				}
29 				free(incarg);
30 			}
+2, -2
 1@@ -1,7 +1,7 @@
 2 {
 3   "case": "t029",
 4   "category": "testsuite",
 5-  "command": "../make -f stdin.mk",
 6+  "command": "make -f stdin.mk",
 7   "compare_output": true,
 8   "cwd": "",
 9   "description": "MAKE macro expansion; turn relative path into absolute",
10@@ -20,7 +20,7 @@
11       "kind": "file",
12       "mode": "0644",
13       "path": "stdin.mk",
14-      "content": "\ntarget:\n\t@case $(MAKE) in /*) test -e $(MAKE) \u0026\u0026 echo ok; esac\n"
15+      "content": "\ntarget:\n\t@echo \"all: ; @echo ok\" \u003esub.mk\n\t@$(MAKE) -f sub.mk\n"
16     }
17   ],
18   "source_script": "testsuite/make.tests",