build.c (12761B)
1 /* 2 * The build engine: bring a target up to date by running its recipe through 3 * the injected shell. Ported from pdpmake make.c. Recipe execution goes through 4 * host->exec (pdpmake used system()), touch through host->touch, and 5 * failed-target removal through host->remove_file. Part of the src/api/make.c 6 * amalgamation. 7 * 8 * host->exec reports the child result in *exit_status: >= 0 is the exit code, 9 * < 0 is the negated terminating signal number; the call itself returns 0 when 10 * the child ran and was reaped, non-zero when the shell could not be spawned. 11 */ 12 #include "make.h" 13 14 static void mk_remove_target(MakeCtx* mc) { 15 if (!dryrun && !print && !precious && mc->target && 16 !(mc->target->n_flag & (N_PRECIOUS | N_PHONY)) && 17 mc->host->remove_file(mc->host->user, mk_path(mc, mc->target->n_name)) == 18 0) { 19 mk_diagnostic(mc, "'%s' removed", mc->target->n_name); 20 } 21 } 22 23 /* 24 * Update the modification time of a file to now (create it if absent). 25 */ 26 static void mk_do_touch(MakeCtx* mc, struct name* np) { 27 if (dryrun || !silent) mk_outf(mc, "touch %s\n", np->n_name); 28 29 if (!dryrun) { 30 if (mc->host->touch(mc->host->user, mk_path(mc, np->n_name)) != 0) 31 mk_warning(mc, "touch %s failed", np->n_name); 32 } 33 } 34 35 /* 36 * Do commands to make a target. 37 */ 38 static int mk_docmds(MakeCtx* mc, struct name* np, struct cmd* cp) { 39 int estat = 0; 40 char* q; 41 char* command; 42 43 for (; cp; cp = cp->c_next) { 44 uint32_t ssilent, signore, sdomake; 45 46 /* Location of command in makefile (for error messages). */ 47 mc->curr_cmd = cp; 48 mc->opts &= ~OPT_make; /* We want to know if $(MAKE) is expanded. */ 49 q = command = mk_expand_macros(mc, cp->c_cmd, FALSE); 50 ssilent = silent || (np->n_flag & N_SILENT) || dotouch; 51 signore = ignore || (np->n_flag & N_IGNORE); 52 sdomake = (!dryrun || doinclude || domake) && !dotouch; 53 for (;;) { 54 if (*q == '@') /* specific silent */ 55 ssilent = TRUE + 1; 56 else if (*q == '-') /* specific ignore */ 57 signore = TRUE; 58 else if (*q == '+') /* specific domake */ 59 sdomake = TRUE + 1; 60 else 61 break; 62 do { 63 q++; 64 } while (isblank((unsigned char)*q)); 65 } 66 67 if (sdomake > TRUE) { 68 /* '+' must not override '@' or .SILENT */ 69 if (ssilent != TRUE + 1 && !(np->n_flag & N_SILENT)) ssilent = FALSE; 70 } else if (!sdomake) 71 ssilent = dotouch; 72 73 if (!ssilent && *q != '\0') { /* Ignore empty commands. */ 74 mk_out(mc, q); 75 mk_outc(mc, '\n'); 76 } 77 78 if (quest && sdomake != TRUE + 1) { 79 /* MAKE_FAILURE means rebuild is needed. */ 80 estat |= MAKE_FAILURE | MAKE_DIDSOMETHING; 81 continue; 82 } 83 84 if (sdomake && *q != '\0') { /* Ignore empty commands. */ 85 int status = 0; 86 int spawned; 87 char* cmd = (!signore && mc->posix) ? mk_concat3(mc, "set -e;", q, "") : q; 88 const KitExec* ex = mc->host->exec; 89 KitExecProc* proc = NULL; 90 KitSlice av[3]; 91 KitExecOpts eo; 92 93 av[0] = kit_slice_cstr(mc->shell); 94 av[1] = KIT_SLICE_LIT("-c"); 95 av[2] = kit_slice_cstr(cmd); 96 memset(&eo, 0, sizeof eo); 97 eo.argv = av; 98 eo.argc = 3; 99 eo.env = mc->env; 100 eo.nenv = mc->nenv; 101 eo.cwd = mc->root ? kit_slice_cstr(mc->root) : KIT_SLICE_NULL; 102 eo.search_path = 1; 103 mc->target = np; 104 spawned = ex->spawn(ex->user, &eo, &proc); 105 if (spawned == 0) spawned = ex->wait(ex->user, proc, &status, NULL, NULL); 106 /* If this command was being run to create/refresh an include file, 107 * errors are ignored and a failure status returned. */ 108 if (spawned != 0) { 109 if (!doinclude) 110 mk_error(mc, "couldn't execute '%s'", q); 111 else 112 mk_warning(mc, "failed to build '%s'", np->n_name); 113 } else if (status != 0 && !signore) { 114 int signaled = status < 0; 115 int err_value = signaled ? -status : status; 116 const char* err_type = signaled ? "signal" : "exit"; 117 118 if (!mc->posix && signaled) mk_remove_target(mc); 119 if (doinclude) { 120 mk_warning(mc, "failed to build '%s'", np->n_name); 121 } else { 122 if (!quest || err_value == 127) 123 mk_diagnostic(mc, "failed to build '%s' %s %d", np->n_name, err_type, 124 err_value); 125 if (errcont) { 126 estat |= MAKE_FAILURE; 127 mc->target = NULL; 128 break; 129 } 130 mk_exit(mc, 2); 131 } 132 } 133 mc->target = NULL; 134 } 135 if (sdomake || dryrun) estat = MAKE_DIDSOMETHING; 136 } 137 138 if (dotouch && !(np->n_flag & N_PHONY) && !(estat & MAKE_DIDSOMETHING)) { 139 mk_do_touch(mc, np); 140 estat = MAKE_DIDSOMETHING; 141 } 142 143 mc->curr_cmd = NULL; 144 return estat; 145 } 146 147 /* 148 * Remove the suffix from a name, either the one in 'tsuff' or, if NULL, one of 149 * the known suffixes. 150 */ 151 static char* mk_remove_suffix(MakeCtx* mc, const char* name, const char* tsuff) { 152 char* base = NULL; 153 154 if (tsuff != NULL) { 155 base = mk_has_suffix(mc, name, tsuff); 156 } else { 157 struct name* xp = mk_newname(mc, ".SUFFIXES"); 158 for (struct rule* rp = xp->n_rule; rp; rp = rp->r_next) { 159 for (struct depend* dp = rp->r_dep; dp; dp = dp->d_next) { 160 base = mk_has_suffix(mc, name, dp->d_name->n_name); 161 if (base) return base; 162 } 163 } 164 } 165 return base; 166 } 167 168 static int mk_make1(MakeCtx* mc, struct name* np, struct cmd* cp, char* oodate, 169 char* allsrc, char* dedup, struct name* implicit, 170 const char* tsuff) { 171 char* name; 172 char* member = NULL; 173 char* base = NULL; 174 char* prereq = NULL; 175 176 name = mk_splitlib(mc, np->n_name, &member); 177 mk_setmacro(mc, "?", oodate, 0 | M_VALID); 178 if (!POSIX_2017) { 179 mk_setmacro(mc, "+", allsrc, 0 | M_VALID); 180 mk_setmacro(mc, "^", dedup, 0 | M_VALID); 181 } 182 mk_setmacro(mc, "%", member, 0 | M_VALID); 183 mk_setmacro(mc, "@", name, 0 | M_VALID); 184 if (implicit || !mc->posix) { 185 char* s; 186 187 /* As an extension, if we're not dealing with an implicit prerequisite set 188 * $< to the first out-of-date prerequisite. */ 189 if (implicit == NULL) { 190 if (oodate) { 191 s = strchr(oodate, ' '); 192 if (s) *s = '\0'; 193 prereq = oodate; 194 } 195 } else 196 prereq = implicit->n_name; 197 198 if (!mc->posix && member == NULL) { 199 /* Remove a suffix (not necessarily period-led) from a target, but not for 200 * lib.a(member.o) targets. */ 201 base = mk_remove_suffix(mc, name, tsuff); 202 if (base) { 203 name = base; 204 } 205 } else { 206 base = member ? member : name; 207 s = mk_suffix(base); 208 /* If not implicit and the target ends with a known suffix, set $* to the 209 * stem, else to an empty string. */ 210 if (implicit == NULL && !mk_is_suffix(mc, s)) 211 base = NULL; 212 else 213 *s = '\0'; 214 } 215 } 216 mk_setmacro(mc, "<", prereq, 0 | M_VALID); 217 mk_setmacro(mc, "*", base, 0 | M_VALID); 218 219 return mk_docmds(mc, np, cp); 220 } 221 222 /* 223 * Determine if the mtime of target t is <= that of prerequisite p. If tv_nsec 224 * of either is 0 assume 1-second resolution and compare only tv_sec. 225 */ 226 static int mk_timespec_le(const struct mk_timespec* t, 227 const struct mk_timespec* p) { 228 if (t->tv_nsec == 0 || p->tv_nsec == 0) 229 return t->tv_sec <= p->tv_sec; 230 else if (t->tv_sec < p->tv_sec) 231 return TRUE; 232 else if (t->tv_sec == p->tv_sec) 233 return t->tv_nsec <= p->tv_nsec; 234 return FALSE; 235 } 236 237 static const struct mk_timespec* mk_timespec_max(const struct mk_timespec* t, 238 const struct mk_timespec* p) { 239 return mk_timespec_le(t, p) ? p : t; 240 } 241 242 /* 243 * Recursive routine to make a target. 244 */ 245 static int mk_make(MakeCtx* mc, struct name* np, int level) { 246 struct depend* dp; 247 struct rule* rp; 248 struct name* impdep = NULL; /* implicit prerequisite */ 249 struct rule infrule; 250 struct cmd* sc_cmd = NULL; /* commands for single-colon rule */ 251 char* oodate = NULL; 252 char* allsrc = NULL; 253 char* dedup = NULL; 254 const char* tsuff = NULL; 255 struct mk_timespec dtim = {1, 0}; 256 int estat = 0; 257 258 if (np->n_flag & N_DONE) return 0; 259 if (np->n_flag & N_DOING) mk_error(mc, "circular dependency for %s", 260 np->n_name); 261 np->n_flag |= N_DOING; 262 263 if (!np->n_tim.tv_sec) mk_modtime(mc, np); /* Get modtime of this file. */ 264 265 if (!(np->n_flag & N_DOUBLE)) { 266 /* Find the commands for a single-colon rule, using an inference or .DEFAULT 267 * rule if needed (but, as an extension, not for phony targets). */ 268 sc_cmd = mk_getcmd(np); 269 if (!sc_cmd && (mc->posix || !(np->n_flag & N_PHONY))) { 270 impdep = mk_dyndep(mc, np, &infrule, &tsuff); 271 if (impdep) { 272 sc_cmd = infrule.r_cmd; 273 mk_addrule(mc, np, infrule.r_dep, NULL, FALSE); 274 } 275 } 276 277 /* As a last resort check for a default rule. */ 278 if (!(np->n_flag & N_TARGET) && np->n_tim.tv_sec == 0) { 279 if (mc->posix || !(np->n_flag & N_PHONY)) 280 sc_cmd = mk_getcmd(mk_findname(mc, ".DEFAULT")); 281 if (!sc_cmd) { 282 if (doinclude) return 1; 283 mk_error(mc, "don't know how to make %s", np->n_name); 284 } 285 impdep = np; 286 } 287 } else { 288 /* If any double-colon rule has no commands we need an inference rule. */ 289 for (rp = np->n_rule; rp; rp = rp->r_next) { 290 if (!rp->r_cmd) { 291 /* Phony targets don't need an inference rule. */ 292 if (!mc->posix && (np->n_flag & N_PHONY)) continue; 293 impdep = mk_dyndep(mc, np, &infrule, &tsuff); 294 if (!impdep) { 295 if (doinclude) return 1; 296 mk_error(mc, "don't know how to make %s", np->n_name); 297 } 298 break; 299 } 300 } 301 } 302 303 /* Reset flag to detect duplicate prerequisites. */ 304 if (!(np->n_flag & N_DOUBLE)) { 305 for (rp = np->n_rule; rp; rp = rp->r_next) 306 for (dp = rp->r_dep; dp; dp = dp->d_next) dp->d_name->n_flag &= ~N_MARK; 307 } 308 309 for (rp = np->n_rule; rp; rp = rp->r_next) { 310 struct name* locdep = NULL; 311 312 /* Each double-colon rule is handled separately. */ 313 if ((np->n_flag & N_DOUBLE)) { 314 /* If the rule has no commands use the inference rule (unless there isn't 315 * one, as allowed for phony targets). */ 316 if (!rp->r_cmd) { 317 if (impdep) { 318 locdep = impdep; 319 infrule.r_dep->d_next = rp->r_dep; 320 rp->r_dep = infrule.r_dep; 321 rp->r_cmd = infrule.r_cmd; 322 } 323 } 324 /* A rule with no prerequisites is executed unconditionally. */ 325 if (!rp->r_dep) dtim = np->n_tim; 326 /* Reset flag to detect duplicate prerequisites. */ 327 for (dp = rp->r_dep; dp; dp = dp->d_next) dp->d_name->n_flag &= ~N_MARK; 328 } 329 for (dp = rp->r_dep; dp; dp = dp->d_next) { 330 /* Make prerequisite. */ 331 estat |= mk_make(mc, dp->d_name, level + 1); 332 333 /* Make strings of out-of-date prerequisites ($?), all prerequisites ($+) 334 * and deduplicated prerequisites ($^). */ 335 if (mk_timespec_le(&np->n_tim, &dp->d_name->n_tim)) { 336 if (mc->posix || !(dp->d_name->n_flag & N_MARK)) 337 oodate = mk_appendword(mc, oodate, dp->d_name->n_name); 338 } 339 allsrc = mk_appendword(mc, allsrc, dp->d_name->n_name); 340 if (!(dp->d_name->n_flag & N_MARK)) 341 dedup = mk_appendword(mc, dedup, dp->d_name->n_name); 342 dp->d_name->n_flag |= N_MARK; 343 dtim = *mk_timespec_max(&dtim, &dp->d_name->n_tim); 344 } 345 if ((np->n_flag & N_DOUBLE)) { 346 if (((np->n_flag & N_PHONY) || mk_timespec_le(&np->n_tim, &dtim))) { 347 if (!(estat & MAKE_FAILURE)) { 348 estat |= mk_make1(mc, np, rp->r_cmd, oodate, allsrc, dedup, locdep, 349 tsuff); 350 dtim = (struct mk_timespec){1, 0}; 351 } 352 oodate = NULL; 353 } 354 allsrc = dedup = NULL; 355 if (locdep) { 356 rp->r_dep = rp->r_dep->d_next; 357 rp->r_cmd = NULL; 358 } 359 } 360 } 361 362 np->n_flag |= N_DONE; 363 np->n_flag &= ~N_DOING; 364 365 if (!(np->n_flag & N_DOUBLE) && 366 ((np->n_flag & N_PHONY) || (mk_timespec_le(&np->n_tim, &dtim)))) { 367 if (!(estat & MAKE_FAILURE)) { 368 if (sc_cmd) 369 estat |= mk_make1(mc, np, sc_cmd, oodate, allsrc, dedup, impdep, tsuff); 370 else if (!doinclude && level == 0 && !(estat & MAKE_DIDSOMETHING)) 371 mk_warning(mc, "nothing to be done for %s", np->n_name); 372 } else if (!doinclude && !quest) { 373 mk_diagnostic(mc, "'%s' not built due to errors", np->n_name); 374 } 375 } 376 377 if (estat & MAKE_DIDSOMETHING) { 378 mk_modtime(mc, np); 379 if (!np->n_tim.tv_sec) { 380 np->n_tim.tv_sec = mc->ctx->now > 0 ? mc->ctx->now : ((int64_t)1 << 40); 381 np->n_tim.tv_nsec = 0; 382 } 383 } else if (!quest && level == 0 && !mk_timespec_le(&np->n_tim, &dtim)) 384 mk_outf(mc, "%s: '%s' is up to date\n", mc->myname, np->n_name); 385 386 return estat; 387 }