Annotation of src/usr.bin/make/engine.c, Revision 1.74
1.74 ! cheloha 1: /* $OpenBSD: engine.c,v 1.73 2023/09/04 11:35:11 espie Exp $ */
1.33 espie 2: /*
3: * Copyright (c) 2012 Marc Espie.
4: *
5: * Extensive code modifications for the OpenBSD project.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
17: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD
20: * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27: */
1.1 espie 28: /*
29: * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
30: * Copyright (c) 1988, 1989 by Adam de Boor
31: * Copyright (c) 1989 by Berkeley Softworks
32: * All rights reserved.
33: *
34: * This code is derived from software contributed to Berkeley by
35: * Adam de Boor.
36: *
37: * Redistribution and use in source and binary forms, with or without
38: * modification, are permitted provided that the following conditions
39: * are met:
40: * 1. Redistributions of source code must retain the above copyright
41: * notice, this list of conditions and the following disclaimer.
42: * 2. Redistributions in binary form must reproduce the above copyright
43: * notice, this list of conditions and the following disclaimer in the
44: * documentation and/or other materials provided with the distribution.
45: * 3. Neither the name of the University nor the names of its contributors
46: * may be used to endorse or promote products derived from this software
47: * without specific prior written permission.
48: *
49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59: * SUCH DAMAGE.
60: */
61:
1.10 espie 62: #include <sys/types.h>
1.33 espie 63: #include <sys/time.h>
1.10 espie 64: #include <sys/wait.h>
1.20 espie 65: #include <assert.h>
1.41 espie 66: #include <ctype.h>
67: #include <errno.h>
68: #include <fcntl.h>
1.1 espie 69: #include <limits.h>
1.41 espie 70: #include <signal.h>
71: #include <stdint.h>
1.1 espie 72: #include <stdio.h>
1.10 espie 73: #include <stdlib.h>
1.41 espie 74: #include <string.h>
1.1 espie 75: #include <unistd.h>
76: #include "defines.h"
1.72 espie 77: #include "cmd_exec.h"
1.1 espie 78: #include "dir.h"
79: #include "engine.h"
80: #include "arch.h"
81: #include "gnode.h"
82: #include "targ.h"
83: #include "var.h"
84: #include "extern.h"
85: #include "lst.h"
86: #include "timestamp.h"
1.71 espie 87: #include "main.h"
1.1 espie 88: #include "make.h"
1.10 espie 89: #include "pathnames.h"
90: #include "error.h"
91: #include "memory.h"
1.16 espie 92: #include "buf.h"
1.24 espie 93: #include "job.h"
1.33 espie 94: #include "lowparse.h"
1.1 espie 95:
96: static void MakeTimeStamp(void *, void *);
1.6 espie 97: static int rewrite_time(const char *);
1.34 espie 98: static void list_parents(GNode *, FILE *);
1.10 espie 99:
1.36 espie 100: /* XXX due to a bug in make's logic, targets looking like *.a or -l*
101: * have been silently dropped when make couldn't figure them out.
102: * Now, we warn about them until all Makefile bugs have been fixed.
103: */
104: static bool
105: drop_silently(const char *s)
106: {
107: size_t len;
108:
109: if (s[0] == '-' && s[1] == 'l')
110: return true;
111:
112: len = strlen(s);
113: if (len >=2 && s[len-2] == '.' && s[len-1] == 'a')
114: return true;
115: return false;
116: }
117:
1.1 espie 118: bool
1.33 espie 119: node_find_valid_commands(GNode *gn)
1.1 espie 120: {
1.37 espie 121: if (DEBUG(DOUBLE) && (gn->type & OP_DOUBLE))
122: fprintf(stderr, "Warning: target %s had >1 lists of "
123: "shell commands (ignoring later ones)\n", gn->name);
1.34 espie 124: if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands)) {
1.36 espie 125: if (drop_silently(gn->name)) {
1.34 espie 126: printf("Warning: target %s", gn->name);
127: list_parents(gn, stdout);
1.36 espie 128: printf(" does not have any command (BUG)\n");
1.34 espie 129: return true;
130: }
1.3 espie 131: /*
132: * No commands. Look for .DEFAULT rule from which we might infer
133: * commands
134: */
1.28 espie 135: if ((gn->type & OP_NODEFAULT) == 0 &&
1.18 espie 136: (DEFAULT->type & OP_DUMMY) == 0 &&
1.9 espie 137: !Lst_IsEmpty(&DEFAULT->commands)) {
1.3 espie 138: /*
139: * Make only looks for a .DEFAULT if the node was never
140: * the target of an operator, so that's what we do too.
141: * If a .DEFAULT was given, we substitute its commands
142: * for gn's commands and set the IMPSRC variable to be
143: * the target's name The DEFAULT node acts like a
144: * transformation rule, in that gn also inherits any
145: * attributes or sources attached to .DEFAULT itself.
146: */
147: Make_HandleUse(DEFAULT, gn);
1.16 espie 148: Var(IMPSRC_INDEX, gn) = Var(TARGET_INDEX, gn);
1.3 espie 149: } else if (is_out_of_date(Dir_MTime(gn))) {
150: /*
151: * The node wasn't the target of an operator we have no
152: * .DEFAULT rule to go on and the target doesn't
153: * already exist. There's nothing more we can do for
1.28 espie 154: * this branch.
1.3 espie 155: */
1.20 espie 156: return false;
157: }
1.1 espie 158: }
1.3 espie 159: return true;
1.1 espie 160: }
161:
1.34 espie 162: static void
163: list_parents(GNode *gn, FILE *out)
164: {
165: LstNode ln;
166: bool first = true;
167:
168: for (ln = Lst_First(&gn->parents); ln != NULL; ln = Lst_Adv(ln)) {
169: GNode *p = Lst_Datum(ln);
170: if (!p->must_make)
171: continue;
172: if (first) {
173: fprintf(out, " (prerequisite of:");
174: first = false;
175: }
176: fprintf(out, " %s", p->name);
177: }
178: if (!first)
179: fprintf(out, ")");
180: }
181:
1.20 espie 182: void
1.33 espie 183: node_failure(GNode *gn)
1.20 espie 184: {
185: /*
186: If the -k flag wasn't given, we stop in
187: * our tracks, otherwise we just don't update this
188: * node's parents so they never get examined.
189: */
1.34 espie 190: const char *diag;
191: FILE *out;
1.20 espie 192:
193: if (gn->type & OP_OPTIONAL) {
1.34 espie 194: out = stdout;
195: diag = "(ignored)";
1.20 espie 196: } else if (keepgoing) {
1.34 espie 197: out = stdout;
198: diag = "(continuing)";
1.20 espie 199: } else {
1.34 espie 200: out = stderr;
201: diag = "";
202: }
203: fprintf(out, "make: don't know how to make %s", gn->name);
204: list_parents(gn, out);
205: fprintf(out, "%s\n", diag);
206: if (out == stdout)
207: fflush(stdout);
208: else {
1.33 espie 209: print_errors();
1.71 espie 210: dump_unreadable();
1.33 espie 211: Punt(NULL);
1.20 espie 212: }
213: }
1.33 espie 214:
1.6 espie 215: /* touch files the hard way, by writing stuff to them */
216: static int
217: rewrite_time(const char *name)
218: {
219: int fd;
220: char c;
221:
222: fd = open(name, O_RDWR | O_CREAT, 0666);
223: if (fd < 0)
224: return -1;
225: /*
226: * Read and write a byte to the file to change
227: * the modification time.
228: */
229: if (read(fd, &c, 1) == 1) {
230: (void)lseek(fd, 0, SEEK_SET);
231: (void)write(fd, &c, 1);
232: }
233:
234: (void)close(fd);
235: return 0;
236: }
237:
1.1 espie 238: void
1.12 espie 239: Job_Touch(GNode *gn)
1.1 espie 240: {
1.33 espie 241: handle_all_signals();
1.69 espie 242: if (gn->type & (OP_USE|OP_OPTIONAL|OP_PHONY)) {
1.3 espie 243: /*
1.9 espie 244: * .JOIN, .USE, and .OPTIONAL targets are "virtual" targets
245: * and, as such, shouldn't really be created.
1.26 espie 246: * Likewise, .PHONY targets are not really files
1.3 espie 247: */
248: return;
249: }
1.1 espie 250:
1.55 espie 251: if (!Targ_Silent(gn)) {
1.3 espie 252: (void)fprintf(stdout, "touch %s\n", gn->name);
253: (void)fflush(stdout);
254: }
1.1 espie 255:
1.3 espie 256: if (noExecute) {
257: return;
258: }
1.1 espie 259:
1.3 espie 260: if (gn->type & OP_ARCHV) {
261: Arch_Touch(gn);
262: } else {
263: const char *file = gn->path != NULL ? gn->path : gn->name;
264:
1.74 ! cheloha 265: if (utimes(file, NULL) == -1){
1.6 espie 266: if (rewrite_time(file) == -1) {
1.49 gsoares 267: (void)fprintf(stderr,
1.5 espie 268: "*** couldn't touch %s: %s", file,
1.3 espie 269: strerror(errno));
1.9 espie 270: }
1.1 espie 271: }
272: }
273: }
274:
275: void
1.7 espie 276: Make_TimeStamp(GNode *parent, GNode *child)
1.1 espie 277: {
1.45 espie 278: if (is_strictly_before(parent->youngest->mtime, child->mtime)) {
1.44 espie 279: parent->youngest = child;
1.42 espie 280: }
1.1 espie 281: }
282:
283: void
1.9 espie 284: Make_HandleUse(GNode *cgn, /* The .USE node */
1.1 espie 285: GNode *pgn) /* The target of the .USE node */
286: {
1.3 espie 287: GNode *gn; /* A child of the .USE node */
288: LstNode ln; /* An element in the children list */
1.1 espie 289:
1.20 espie 290: assert(cgn->type & (OP_USE|OP_TRANSFORM));
1.52 espie 291:
292: if (pgn == NULL)
293: Fatal("Trying to apply .USE to '%s' without a parent",
294: cgn->name);
1.20 espie 295:
296: if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) {
297: /* .USE or transformation and target has no commands
298: * -- append the child's commands to the parent. */
299: Lst_Concat(&pgn->commands, &cgn->commands);
300: }
301:
302: for (ln = Lst_First(&cgn->children); ln != NULL;
303: ln = Lst_Adv(ln)) {
1.51 espie 304: gn = Lst_Datum(ln);
1.20 espie 305:
306: if (Lst_AddNew(&pgn->children, gn)) {
307: Lst_AtEnd(&gn->parents, pgn);
1.58 espie 308: pgn->children_left++;
1.3 espie 309: }
1.20 espie 310: }
1.1 espie 311:
1.37 espie 312: if (DEBUG(DOUBLE) && (cgn->type & OP_DOUBLE))
313: fprintf(stderr,
314: "Warning: .USE %s expanded in %s had >1 lists of "
315: "shell commands (ignoring later ones)\n",
316: cgn->name, pgn->name);
317: pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM|OP_DOUBLE);
1.1 espie 318:
1.20 espie 319: /*
1.58 espie 320: * This child node is now built, so we decrement the count of
321: * not yet built children in the parent... We also remove the child
1.20 espie 322: * from the parent's list to accurately reflect the number of
1.58 espie 323: * remaining children the parent has. This is used by Make_Run to
1.20 espie 324: * decide whether to queue the parent or examine its children...
325: */
326: if (cgn->type & OP_USE)
1.58 espie 327: pgn->children_left--;
1.1 espie 328: }
329:
1.16 espie 330: void
331: Make_DoAllVar(GNode *gn)
1.1 espie 332: {
1.16 espie 333: GNode *child;
334: LstNode ln;
335: BUFFER allsrc, oodate;
336: char *target;
337: bool do_oodate;
338: int oodate_count, allsrc_count = 0;
339:
340: oodate_count = 0;
341: allsrc_count = 0;
1.39 espie 342:
343: Var(OODATE_INDEX, gn) = "";
344: Var(ALLSRC_INDEX, gn) = "";
1.16 espie 345:
346: for (ln = Lst_First(&gn->children); ln != NULL; ln = Lst_Adv(ln)) {
1.51 espie 347: child = Lst_Datum(ln);
1.69 espie 348: if ((child->type & (OP_USE|OP_INVISIBLE)) != 0)
1.16 espie 349: continue;
1.9 espie 350: if (OP_NOP(child->type) ||
1.16 espie 351: (target = Var(TARGET_INDEX, child)) == NULL) {
1.3 espie 352: /*
353: * this node is only source; use the specific pathname
354: * for it
355: */
1.9 espie 356: target = child->path != NULL ? child->path :
357: child->name;
1.3 espie 358: }
1.1 espie 359:
1.16 espie 360: /*
361: * It goes in the OODATE variable if the parent is younger than
362: * the child or if the child has been modified more recently
363: * than the start of the make. This is to keep make from
364: * getting confused if something else updates the parent after
365: * the make starts (shouldn't happen, I know, but sometimes it
366: * does). In such a case, if we've updated the kid, the parent
367: * is likely to have a modification time later than that of the
368: * kid and anything that relies on the OODATE variable will be
369: * hosed.
370: */
371: do_oodate = false;
1.69 espie 372: if (is_strictly_before(gn->mtime, child->mtime) ||
1.43 espie 373: (!is_strictly_before(child->mtime, starttime) &&
1.57 espie 374: child->built_status == REBUILT))
1.16 espie 375: do_oodate = true;
376: if (do_oodate) {
377: oodate_count++;
378: if (oodate_count == 1)
379: Var(OODATE_INDEX, gn) = target;
380: else {
381: if (oodate_count == 2) {
382: Buf_Init(&oodate, 0);
1.28 espie 383: Buf_AddString(&oodate,
1.16 espie 384: Var(OODATE_INDEX, gn));
385: }
386: Buf_AddSpace(&oodate);
387: Buf_AddString(&oodate, target);
388: }
389: }
390: allsrc_count++;
391: if (allsrc_count == 1)
392: Var(ALLSRC_INDEX, gn) = target;
393: else {
394: if (allsrc_count == 2) {
395: Buf_Init(&allsrc, 0);
1.28 espie 396: Buf_AddString(&allsrc,
1.16 espie 397: Var(ALLSRC_INDEX, gn));
398: }
399: Buf_AddSpace(&allsrc);
400: Buf_AddString(&allsrc, target);
1.3 espie 401: }
1.1 espie 402: }
403:
1.16 espie 404: if (allsrc_count > 1)
405: Var(ALLSRC_INDEX, gn) = Buf_Retrieve(&allsrc);
406: if (oodate_count > 1)
407: Var(OODATE_INDEX, gn) = Buf_Retrieve(&oodate);
1.1 espie 408:
1.13 espie 409: if (gn->impliedsrc)
1.16 espie 410: Var(IMPSRC_INDEX, gn) = Var(TARGET_INDEX, gn->impliedsrc);
1.1 espie 411: }
412:
413: /* Wrapper to call Make_TimeStamp from a forEach loop. */
414: static void
1.9 espie 415: MakeTimeStamp(void *parent, void *child)
1.1 espie 416: {
1.50 espie 417: Make_TimeStamp(parent, child);
1.1 espie 418: }
419:
420: bool
1.9 espie 421: Make_OODate(GNode *gn)
1.1 espie 422: {
1.9 espie 423: bool oodate;
1.1 espie 424:
425: /*
1.3 espie 426: * Certain types of targets needn't even be sought as their datedness
427: * doesn't depend on their modification time...
1.1 espie 428: */
1.69 espie 429: if ((gn->type & (OP_USE|OP_PHONY)) == 0) {
1.3 espie 430: (void)Dir_MTime(gn);
431: if (DEBUG(MAKE)) {
1.9 espie 432: if (!is_out_of_date(gn->mtime))
1.5 espie 433: printf("modified %s...",
1.43 espie 434: time_to_string(&gn->mtime));
1.9 espie 435: else
1.3 espie 436: printf("non-existent...");
437: }
1.1 espie 438: }
439:
440: /*
1.58 espie 441: * A target is rebuilt in one of the following circumstances:
1.9 espie 442: * - its modification time is smaller than that of its youngest child
443: * and it would actually be run (has commands or type OP_NOP)
444: * - it's the object of a force operator
445: * - it has no children, was on the lhs of an operator and doesn't
446: * exist already.
1.3 espie 447: *
1.1 espie 448: */
1.3 espie 449: if (gn->type & OP_USE) {
450: /*
451: * If the node is a USE node it is *never* out of date
452: * no matter *what*.
453: */
1.9 espie 454: if (DEBUG(MAKE))
1.3 espie 455: printf(".USE node...");
456: oodate = false;
1.69 espie 457: } else if (gn->type & (OP_FORCE|OP_PHONY)) {
1.3 espie 458: /*
1.9 espie 459: * A node which is the object of the force (!) operator or which
460: * has the .EXEC attribute is always considered out-of-date.
1.3 espie 461: */
462: if (DEBUG(MAKE)) {
1.9 espie 463: if (gn->type & OP_FORCE)
1.3 espie 464: printf("! operator...");
1.9 espie 465: else if (gn->type & OP_PHONY)
1.3 espie 466: printf(".PHONY node...");
1.9 espie 467: else
1.3 espie 468: printf(".EXEC node...");
469: }
470: oodate = true;
1.45 espie 471: } else if (is_strictly_before(gn->mtime, gn->youngest->mtime) ||
472: (gn == gn->youngest &&
1.3 espie 473: (is_out_of_date(gn->mtime) || (gn->type & OP_DOUBLEDEP)))) {
474: /*
475: * A node whose modification time is less than that of its
1.45 espie 476: * youngest child or that has no children (gn->youngest == gn)
477: * and either doesn't exist (mtime == OUT_OF_DATE)
1.9 espie 478: * or was the object of a :: operator is out-of-date.
1.3 espie 479: */
480: if (DEBUG(MAKE)) {
1.45 espie 481: if (is_strictly_before(gn->mtime, gn->youngest->mtime))
1.42 espie 482: printf("modified before source(%s)...",
483: gn->youngest->name);
1.9 espie 484: else if (is_out_of_date(gn->mtime))
1.3 espie 485: printf("non-existent and no sources...");
1.9 espie 486: else
1.3 espie 487: printf(":: operator and no sources...");
488: }
489: oodate = true;
490: } else {
491: oodate = false;
492: }
1.1 espie 493:
1.3 espie 494: /*
495: * If the target isn't out-of-date, the parents need to know its
496: * modification time. Note that targets that appear to be out-of-date
497: * but aren't, because they have no commands and aren't of type OP_NOP,
498: * have their mtime stay below their children's mtime to keep parents
499: * from thinking they're out-of-date.
500: */
501: if (!oodate)
502: Lst_ForEach(&gn->parents, MakeTimeStamp, gn);
1.1 espie 503:
1.3 espie 504: return oodate;
1.1 espie 505: }
506:
1.10 espie 507:
1.33 espie 508: void
509: job_attach_node(Job *job, GNode *node)
510: {
511: job->node = node;
1.34 espie 512: job->node->built_status = BUILDING;
1.33 espie 513: job->next_cmd = Lst_First(&node->commands);
514: job->exit_type = JOB_EXIT_OKAY;
515: job->location = NULL;
516: job->flags = 0;
517: }
518:
519: void
1.64 espie 520: handle_job_status(Job *job, int status)
1.33 espie 521: {
1.36 espie 522: bool silent;
1.38 espie 523: int dying;
1.36 espie 524:
525: /* if there's one job running and we don't keep going, no need
526: * to report right now.
527: */
528: if ((job->flags & JOB_ERRCHECK) && !keepgoing && runningJobs == NULL)
529: silent = !DEBUG(JOB);
530: else
531: silent = false;
532:
1.33 espie 533: debug_job_printf("Process %ld (%s) exited with status %d.\n",
534: (long)job->pid, job->node->name, status);
535:
536: /* classify status */
537: if (WIFEXITED(status)) {
538: job->code = WEXITSTATUS(status);/* exited */
1.38 espie 539: if (job->code != 0) {
540: /* if we're already dying from that signal, be silent */
541: if (!silent && job->code > 128
542: && job->code <= 128 + _NSIG) {
543: dying = check_dying_signal();
544: silent = dying && job->code == dying + 128;
545: }
1.36 espie 546: if (!silent)
547: printf("*** Error %d", job->code);
1.33 espie 548: job->exit_type = JOB_EXIT_BAD;
549: } else
550: job->exit_type = JOB_EXIT_OKAY;
551: } else {
552: job->exit_type = JOB_SIGNALED;
553: job->code = WTERMSIG(status); /* signaled */
1.38 espie 554: /* if we're already dying from that signal, be silent */
555: if (!silent) {
556: dying = check_dying_signal();
557: silent = dying && job->code == dying;
558: }
1.36 espie 559: if (!silent)
560: printf("*** Signal %d", job->code);
1.33 espie 561: }
562:
563: /* if there is a problem, what's going on ? */
564: if (job->exit_type != JOB_EXIT_OKAY) {
1.36 espie 565: if (!silent)
566: printf(" in target '%s'", job->node->name);
1.33 espie 567: if (job->flags & JOB_ERRCHECK) {
568: job->node->built_status = ERROR;
569: if (!keepgoing) {
1.36 espie 570: if (!silent)
571: printf("\n");
1.65 espie 572: job->flags |= JOB_KEEPERROR;
1.33 espie 573: /* XXX don't free the command */
574: return;
575: }
576: printf(", line %lu of %s", job->location->lineno,
577: job->location->fname);
1.62 espie 578: /* Parallel make already determined whether
579: * JOB_IS_EXPENSIVE, perform the computation for
580: * sequential make to figure out whether to display the
581: * command or not. */
1.63 espie 582: if ((job->flags & JOB_SILENT) && sequential)
1.61 espie 583: determine_expensive_job(job);
1.33 espie 584: if ((job->flags & (JOB_SILENT | JOB_IS_EXPENSIVE))
585: == JOB_SILENT)
586: printf(": %s", job->cmd);
587: /* Abort the current target,
588: * but let others continue. */
589: printf(" (continuing)\n");
590: } else {
591: /* Continue executing commands for
592: * this target. If we return 0,
593: * this will happen... */
594: printf(" (ignored)\n");
595: job->exit_type = JOB_EXIT_OKAY;
596: }
597: }
598: free(job->cmd);
599: }
600:
601: int
602: run_gnode(GNode *gn)
603: {
604: if (!gn || (gn->type & OP_DUMMY))
605: return NOSUCHNODE;
606:
1.67 espie 607: Job_Make(gn);
608: loop_handle_running_jobs();
1.33 espie 609: return gn->built_status;
610: }
611:
612:
613: static bool
1.54 espie 614: do_run_command(Job *job, const char *pre)
1.10 espie 615: {
616: bool silent; /* Don't print command */
617: bool doExecute; /* Execute the command */
618: bool errCheck; /* Check errors */
1.33 espie 619: pid_t cpid; /* Child pid */
620:
621: const char *cmd = job->cmd;
1.55 espie 622: silent = Targ_Silent(job->node);
623: errCheck = !Targ_Ignore(job->node);
1.33 espie 624: if (job->node->type & OP_MAKE)
625: doExecute = true;
626: else
627: doExecute = !noExecute;
1.10 espie 628:
629: /* How can we execute a null command ? we warn the user that the
630: * command expanded to nothing (is this the right thing to do?). */
1.19 espie 631: if (*cmd == '\0') {
1.54 espie 632: Parse_Error(PARSE_WARNING,
633: "'%s' expands to '' while building %s",
634: pre, job->node->name);
1.33 espie 635: return false;
1.28 espie 636: }
1.10 espie 637:
638: for (;; cmd++) {
639: if (*cmd == '@')
640: silent = DEBUG(LOUD) ? false : true;
641: else if (*cmd == '-')
642: errCheck = false;
643: else if (*cmd == '+')
644: doExecute = true;
645: else
646: break;
647: }
1.47 espie 648: while (ISSPACE(*cmd))
1.10 espie 649: cmd++;
1.33 espie 650: /* Print the command before fork if make -n or !silent*/
651: if ( noExecute || !silent)
1.10 espie 652: printf("%s\n", cmd);
1.33 espie 653:
654: if (silent)
655: job->flags |= JOB_SILENT;
656: else
657: job->flags &= ~JOB_SILENT;
658:
1.10 espie 659: /* If we're not supposed to execute any commands, this is as far as
660: * we go... */
661: if (!doExecute)
1.33 espie 662: return false;
663: /* always flush for other stuff */
664: fflush(stdout);
1.53 espie 665:
666: /* Optimization: bypass comments entirely */
667: if (*cmd == '#')
668: return false;
1.10 espie 669:
670: /* Fork and execute the single command. If the fork fails, we abort. */
671: switch (cpid = fork()) {
672: case -1:
1.33 espie 673: Punt("Could not fork");
1.10 espie 674: /*NOTREACHED*/
675: case 0:
1.68 espie 676: reset_signal_mask();
1.34 espie 677: /* put a random delay unless we're the only job running
678: * and there's nothing left to do.
679: */
680: if (random_delay)
1.66 espie 681: if (!(runningJobs == NULL && nothing_left_to_build()))
1.46 naddy 682: usleep(arc4random_uniform(random_delay));
1.10 espie 683: run_command(cmd, errCheck);
684: /*NOTREACHED*/
685: default:
1.33 espie 686: job->pid = cpid;
687: job->next = runningJobs;
688: runningJobs = job;
689: if (errCheck)
690: job->flags |= JOB_ERRCHECK;
691: else
692: job->flags &= ~JOB_ERRCHECK;
693: debug_job_printf("Running %ld (%s) %s\n", (long)job->pid,
694: job->node->name, (noExecute || !silent) ? "" : cmd);
695: return true;
1.10 espie 696: }
697: }
698:
1.33 espie 699: bool
700: job_run_next(Job *job)
1.10 espie 701: {
1.33 espie 702: bool started;
703: GNode *gn = job->node;
1.19 espie 704:
1.33 espie 705: while (job->next_cmd != NULL) {
706: struct command *command = Lst_Datum(job->next_cmd);
707:
708: handle_all_signals();
709: job->location = &command->location;
710: Parse_SetLocation(job->location);
1.59 espie 711: job->cmd = Var_Subst(command->string, &gn->localvars, false);
1.33 espie 712: job->next_cmd = Lst_Adv(job->next_cmd);
1.30 espie 713: if (fatal_errors)
1.33 espie 714: Punt(NULL);
1.54 espie 715: started = do_run_command(job, command->string);
1.33 espie 716: if (started)
717: return false;
718: else
719: free(job->cmd);
1.19 espie 720: }
1.33 espie 721: job->exit_type = JOB_EXIT_OKAY;
722: return true;
1.19 espie 723: }
724: