Annotation of src/usr.bin/make/main.c, Revision 1.1.1.1
1.1 deraadt 1: /* $NetBSD: main.c,v 1.20 1995/09/27 18:42:21 jtc Exp $ */
2:
3: /*
4: * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5: * Copyright (c) 1988, 1989 by Adam de Boor
6: * Copyright (c) 1989 by Berkeley Softworks
7: * All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * Adam de Boor.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. All advertising materials mentioning features or use of this software
21: * must display the following acknowledgement:
22: * This product includes software developed by the University of
23: * California, Berkeley and its contributors.
24: * 4. Neither the name of the University nor the names of its contributors
25: * may be used to endorse or promote products derived from this software
26: * without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38: * SUCH DAMAGE.
39: */
40:
41: #ifndef lint
42: char copyright[] =
43: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
44: All rights reserved.\n";
45: #endif /* not lint */
46:
47: #ifndef lint
48: #if 0
49: static char sccsid[] = "@(#)main.c 5.25 (Berkeley) 4/1/91";
50: #else
51: static char rcsid[] = "$NetBSD: main.c,v 1.20 1995/09/27 18:42:21 jtc Exp $";
52: #endif
53: #endif /* not lint */
54:
55: /*-
56: * main.c --
57: * The main file for this entire program. Exit routines etc
58: * reside here.
59: *
60: * Utility functions defined in this file:
61: * Main_ParseArgLine Takes a line of arguments, breaks them and
62: * treats them as if they were given when first
63: * invoked. Used by the parse module to implement
64: * the .MFLAGS target.
65: *
66: * Error Print a tagged error message. The global
67: * MAKE variable must have been defined. This
68: * takes a format string and two optional
69: * arguments for it.
70: *
71: * Fatal Print an error message and exit. Also takes
72: * a format string and two arguments.
73: *
74: * Punt Aborts all jobs and exits with a message. Also
75: * takes a format string and two arguments.
76: *
77: * Finish Finish things up by printing the number of
78: * errors which occured, as passed to it, and
79: * exiting.
80: */
81:
82: #include <sys/types.h>
83: #include <sys/time.h>
84: #include <sys/param.h>
85: #include <sys/resource.h>
86: #include <sys/stat.h>
87: #include <sys/utsname.h>
88: #include <errno.h>
89: #include <fcntl.h>
90: #include <signal.h>
91: #include <stdio.h>
92: #if __STDC__
93: #include <stdarg.h>
94: #else
95: #include <varargs.h>
96: #endif
97: #include "make.h"
98: #include "hash.h"
99: #include "dir.h"
100: #include "job.h"
101: #include "pathnames.h"
102:
103: #ifndef DEFMAXLOCAL
104: #define DEFMAXLOCAL DEFMAXJOBS
105: #endif DEFMAXLOCAL
106:
107: #define MAKEFLAGS ".MAKEFLAGS"
108:
109: Lst create; /* Targets to be made */
110: time_t now; /* Time at start of make */
111: GNode *DEFAULT; /* .DEFAULT node */
112: Boolean allPrecious; /* .PRECIOUS given on line by itself */
113:
114: static Boolean noBuiltins; /* -r flag */
115: static Lst makefiles; /* ordered list of makefiles to read */
116: int maxJobs; /* -J argument */
117: static int maxLocal; /* -L argument */
118: Boolean compatMake; /* -B argument */
119: Boolean debug; /* -d flag */
120: Boolean noExecute; /* -n flag */
121: Boolean keepgoing; /* -k flag */
122: Boolean queryFlag; /* -q flag */
123: Boolean touchFlag; /* -t flag */
124: Boolean usePipes; /* !-P flag */
125: Boolean ignoreErrors; /* -i flag */
126: Boolean beSilent; /* -s flag */
127: Boolean oldVars; /* variable substitution style */
128: Boolean checkEnvFirst; /* -e flag */
129: static Boolean jobsRunning; /* TRUE if the jobs might be running */
130:
131: static Boolean ReadMakefile();
132: static void usage();
133:
134: static char *curdir; /* startup directory */
135: static char *objdir; /* where we chdir'ed to */
136:
137: /*-
138: * MainParseArgs --
139: * Parse a given argument vector. Called from main() and from
140: * Main_ParseArgLine() when the .MAKEFLAGS target is used.
141: *
142: * XXX: Deal with command line overriding .MAKEFLAGS in makefile
143: *
144: * Results:
145: * None
146: *
147: * Side Effects:
148: * Various global and local flags will be set depending on the flags
149: * given
150: */
151: static void
152: MainParseArgs(argc, argv)
153: int argc;
154: char **argv;
155: {
156: extern int optind;
157: extern char *optarg;
158: int c;
159:
160: optind = 1; /* since we're called more than once */
161: #ifdef notyet
162: # define OPTFLAGS "BD:I:L:PSd:ef:ij:knqrst"
163: #else
164: # define OPTFLAGS "D:I:d:ef:ij:knqrst"
165: #endif
166: rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
167: switch(c) {
168: case 'D':
169: Var_Set(optarg, "1", VAR_GLOBAL);
170: Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
171: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
172: break;
173: case 'I':
174: Parse_AddIncludeDir(optarg);
175: Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
176: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
177: break;
178: #ifdef notyet
179: case 'B':
180: compatMake = TRUE;
181: break;
182: case 'L':
183: maxLocal = atoi(optarg);
184: Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
185: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
186: break;
187: case 'P':
188: usePipes = FALSE;
189: Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
190: break;
191: case 'S':
192: keepgoing = FALSE;
193: Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
194: break;
195: #endif
196: case 'd': {
197: char *modules = optarg;
198:
199: for (; *modules; ++modules)
200: switch (*modules) {
201: case 'A':
202: debug = ~0;
203: break;
204: case 'a':
205: debug |= DEBUG_ARCH;
206: break;
207: case 'c':
208: debug |= DEBUG_COND;
209: break;
210: case 'd':
211: debug |= DEBUG_DIR;
212: break;
213: case 'f':
214: debug |= DEBUG_FOR;
215: break;
216: case 'g':
217: if (modules[1] == '1') {
218: debug |= DEBUG_GRAPH1;
219: ++modules;
220: }
221: else if (modules[1] == '2') {
222: debug |= DEBUG_GRAPH2;
223: ++modules;
224: }
225: break;
226: case 'j':
227: debug |= DEBUG_JOB;
228: break;
229: case 'm':
230: debug |= DEBUG_MAKE;
231: break;
232: case 's':
233: debug |= DEBUG_SUFF;
234: break;
235: case 't':
236: debug |= DEBUG_TARG;
237: break;
238: case 'v':
239: debug |= DEBUG_VAR;
240: break;
241: default:
242: (void)fprintf(stderr,
243: "make: illegal argument to d option -- %c\n",
244: *modules);
245: usage();
246: }
247: Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
248: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
249: break;
250: }
251: case 'e':
252: checkEnvFirst = TRUE;
253: Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
254: break;
255: case 'f':
256: (void)Lst_AtEnd(makefiles, (ClientData)optarg);
257: break;
258: case 'i':
259: ignoreErrors = TRUE;
260: Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
261: break;
262: case 'j':
263: maxJobs = atoi(optarg);
264: Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
265: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
266: break;
267: case 'k':
268: keepgoing = TRUE;
269: Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
270: break;
271: case 'n':
272: noExecute = TRUE;
273: Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
274: break;
275: case 'q':
276: queryFlag = TRUE;
277: /* Kind of nonsensical, wot? */
278: Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
279: break;
280: case 'r':
281: noBuiltins = TRUE;
282: Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
283: break;
284: case 's':
285: beSilent = TRUE;
286: Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
287: break;
288: case 't':
289: touchFlag = TRUE;
290: Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
291: break;
292: default:
293: case '?':
294: usage();
295: }
296: }
297:
298: oldVars = TRUE;
299:
300: /*
301: * See if the rest of the arguments are variable assignments and
302: * perform them if so. Else take them to be targets and stuff them
303: * on the end of the "create" list.
304: */
305: for (argv += optind, argc -= optind; *argv; ++argv, --argc)
306: if (Parse_IsVar(*argv))
307: Parse_DoVar(*argv, VAR_CMD);
308: else {
309: if (!**argv)
310: Punt("illegal (null) argument.");
311: if (**argv == '-') {
312: if ((*argv)[1])
313: optind = 0; /* -flag... */
314: else
315: optind = 1; /* - */
316: goto rearg;
317: }
318: (void)Lst_AtEnd(create, (ClientData)strdup(*argv));
319: }
320: }
321:
322: /*-
323: * Main_ParseArgLine --
324: * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
325: * is encountered and by main() when reading the .MAKEFLAGS envariable.
326: * Takes a line of arguments and breaks it into its
327: * component words and passes those words and the number of them to the
328: * MainParseArgs function.
329: * The line should have all its leading whitespace removed.
330: *
331: * Results:
332: * None
333: *
334: * Side Effects:
335: * Only those that come from the various arguments.
336: */
337: void
338: Main_ParseArgLine(line)
339: char *line; /* Line to fracture */
340: {
341: char **argv; /* Manufactured argument vector */
342: int argc; /* Number of arguments in argv */
343:
344: if (line == NULL)
345: return;
346: for (; *line == ' '; ++line)
347: continue;
348: if (!*line)
349: return;
350:
351: argv = brk_string(line, &argc, TRUE);
352: MainParseArgs(argc, argv);
353: }
354:
355: /*-
356: * main --
357: * The main function, for obvious reasons. Initializes variables
358: * and a few modules, then parses the arguments give it in the
359: * environment and on the command line. Reads the system makefile
360: * followed by either Makefile, makefile or the file given by the
361: * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
362: * flags it has received by then uses either the Make or the Compat
363: * module to create the initial list of targets.
364: *
365: * Results:
366: * If -q was given, exits -1 if anything was out-of-date. Else it exits
367: * 0.
368: *
369: * Side Effects:
370: * The program exits when done. Targets are created. etc. etc. etc.
371: */
372: int
373: main(argc, argv)
374: int argc;
375: char **argv;
376: {
377: Lst targs; /* target nodes to create -- passed to Make_Init */
378: Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
379: struct stat sb, sa;
380: char *p, *p1, *path, *pwd, *getenv(), *getwd();
381: char mdpath[MAXPATHLEN + 1];
382: char obpath[MAXPATHLEN + 1];
383: char cdpath[MAXPATHLEN + 1];
384: struct utsname utsname;
385: char *machine = getenv("MACHINE");
386:
387: /*
388: * Find where we are and take care of PWD for the automounter...
389: * All this code is so that we know where we are when we start up
390: * on a different machine with pmake.
391: */
392: curdir = cdpath;
393: if (getcwd(curdir, MAXPATHLEN) == NULL) {
394: (void)fprintf(stderr, "make: %s.\n", strerror(errno));
395: exit(2);
396: }
397:
398: if (stat(curdir, &sa) == -1) {
399: (void)fprintf(stderr, "make: %s: %s.\n",
400: curdir, strerror(errno));
401: exit(2);
402: }
403:
404: if ((pwd = getenv("PWD")) != NULL) {
405: if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
406: sa.st_dev == sb.st_dev)
407: (void) strcpy(curdir, pwd);
408: }
409:
410: /*
411: * Get the name of this type of MACHINE from utsname
412: * so we can share an executable for similar machines.
413: * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
414: *
415: * Note that while MACHINE is decided at run-time,
416: * MACHINE_ARCH is always known at compile time.
417: */
418: if (!machine) {
419: if (uname(&utsname)) {
420: perror("make: uname");
421: exit(2);
422: }
423: machine = utsname.machine;
424: }
425:
426: /*
427: * if the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
428: * exists, change into it and build there. Once things are
429: * initted, have to add the original directory to the search path,
430: * and modify the paths for the Makefiles apropriately. The
431: * current directory is also placed as a variable for make scripts.
432: */
433: if (!(path = getenv("MAKEOBJDIR"))) {
434: path = _PATH_OBJDIR;
435: (void) sprintf(mdpath, "%s.%s", path, machine);
436: }
437: else
438: (void) strncpy(mdpath, path, MAXPATHLEN + 1);
439:
440: if (stat(mdpath, &sb) == 0 && S_ISDIR(sb.st_mode)) {
441:
442: if (chdir(mdpath)) {
443: (void)fprintf(stderr, "make warning: %s: %s.\n",
444: mdpath, strerror(errno));
445: objdir = curdir;
446: }
447: else {
448: if (mdpath[0] != '/') {
449: (void) sprintf(obpath, "%s/%s", curdir, mdpath);
450: objdir = obpath;
451: }
452: else
453: objdir = mdpath;
454: }
455: }
456: else {
457: if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
458:
459: if (chdir(path)) {
460: (void)fprintf(stderr, "make warning: %s: %s.\n",
461: path, strerror(errno));
462: objdir = curdir;
463: }
464: else {
465: if (path[0] != '/') {
466: (void) sprintf(obpath, "%s/%s", curdir,
467: path);
468: objdir = obpath;
469: }
470: else
471: objdir = obpath;
472: }
473: }
474: else
475: objdir = curdir;
476: }
477:
478: setenv("PWD", objdir, 1);
479:
480: create = Lst_Init(FALSE);
481: makefiles = Lst_Init(FALSE);
482: beSilent = FALSE; /* Print commands as executed */
483: ignoreErrors = FALSE; /* Pay attention to non-zero returns */
484: noExecute = FALSE; /* Execute all commands */
485: keepgoing = FALSE; /* Stop on error */
486: allPrecious = FALSE; /* Remove targets when interrupted */
487: queryFlag = FALSE; /* This is not just a check-run */
488: noBuiltins = FALSE; /* Read the built-in rules */
489: touchFlag = FALSE; /* Actually update targets */
490: usePipes = TRUE; /* Catch child output in pipes */
491: debug = 0; /* No debug verbosity, please. */
492: jobsRunning = FALSE;
493:
494: maxJobs = DEFMAXJOBS; /* Set default max concurrency */
495: maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
496: #ifdef notyet
497: compatMake = FALSE; /* No compat mode */
498: #else
499: compatMake = TRUE; /* No compat mode */
500: #endif
501:
502:
503: /*
504: * Initialize the parsing, directory and variable modules to prepare
505: * for the reading of inclusion paths and variable settings on the
506: * command line
507: */
508: Dir_Init(); /* Initialize directory structures so -I flags
509: * can be processed correctly */
510: Parse_Init(); /* Need to initialize the paths of #include
511: * directories */
512: Var_Init(); /* As well as the lists of variables for
513: * parsing arguments */
514: str_init();
515: if (objdir != curdir)
516: Dir_AddDir(dirSearchPath, curdir);
517: Var_Set(".CURDIR", curdir, VAR_GLOBAL);
518: Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
519:
520: /*
521: * Initialize various variables.
522: * MAKE also gets this name, for compatibility
523: * .MAKEFLAGS gets set to the empty string just in case.
524: * MFLAGS also gets initialized empty, for compatibility.
525: */
526: Var_Set("MAKE", argv[0], VAR_GLOBAL);
527: Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
528: Var_Set("MFLAGS", "", VAR_GLOBAL);
529: Var_Set("MACHINE", machine, VAR_GLOBAL);
530: #ifdef MACHINE_ARCH
531: Var_Set("MACHINE_ARCH", MACHINE_ARCH, VAR_GLOBAL);
532: #endif
533:
534: /*
535: * First snag any flags out of the MAKE environment variable.
536: * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
537: * in a different format).
538: */
539: #ifdef POSIX
540: Main_ParseArgLine(getenv("MAKEFLAGS"));
541: #else
542: Main_ParseArgLine(getenv("MAKE"));
543: #endif
544:
545: MainParseArgs(argc, argv);
546:
547: /*
548: * Initialize archive, target and suffix modules in preparation for
549: * parsing the makefile(s)
550: */
551: Arch_Init();
552: Targ_Init();
553: Suff_Init();
554:
555: DEFAULT = NILGNODE;
556: (void)time(&now);
557:
558: /*
559: * Set up the .TARGETS variable to contain the list of targets to be
560: * created. If none specified, make the variable empty -- the parser
561: * will fill the thing in with the default or .MAIN target.
562: */
563: if (!Lst_IsEmpty(create)) {
564: LstNode ln;
565:
566: for (ln = Lst_First(create); ln != NILLNODE;
567: ln = Lst_Succ(ln)) {
568: char *name = (char *)Lst_Datum(ln);
569:
570: Var_Append(".TARGETS", name, VAR_GLOBAL);
571: }
572: } else
573: Var_Set(".TARGETS", "", VAR_GLOBAL);
574:
575: /*
576: * Read in the built-in rules first, followed by the specified makefile,
577: * if it was (makefile != (char *) NULL), or the default Makefile and
578: * makefile, in that order, if it wasn't.
579: */
580: if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
581: Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
582:
583: if (!Lst_IsEmpty(makefiles)) {
584: LstNode ln;
585:
586: ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
587: if (ln != NILLNODE)
588: Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
589: } else if (!ReadMakefile("makefile"))
590: (void)ReadMakefile("Makefile");
591:
592: (void)ReadMakefile(".depend");
593:
594: Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
595: if (p1)
596: free(p1);
597:
598: /* Install all the flags into the MAKE envariable. */
599: if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
600: #ifdef POSIX
601: setenv("MAKEFLAGS", p, 1);
602: #else
603: setenv("MAKE", p, 1);
604: #endif
605: if (p1)
606: free(p1);
607:
608: /*
609: * For compatibility, look at the directories in the VPATH variable
610: * and add them to the search path, if the variable is defined. The
611: * variable's value is in the same format as the PATH envariable, i.e.
612: * <directory>:<directory>:<directory>...
613: */
614: if (Var_Exists("VPATH", VAR_CMD)) {
615: char *vpath, *path, *cp, savec;
616: /*
617: * GCC stores string constants in read-only memory, but
618: * Var_Subst will want to write this thing, so store it
619: * in an array
620: */
621: static char VPATH[] = "${VPATH}";
622:
623: vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
624: path = vpath;
625: do {
626: /* skip to end of directory */
627: for (cp = path; *cp != ':' && *cp != '\0'; cp++)
628: continue;
629: /* Save terminator character so know when to stop */
630: savec = *cp;
631: *cp = '\0';
632: /* Add directory to search path */
633: Dir_AddDir(dirSearchPath, path);
634: *cp = savec;
635: path = cp + 1;
636: } while (savec == ':');
637: (void)free((Address)vpath);
638: }
639:
640: /*
641: * Now that all search paths have been read for suffixes et al, it's
642: * time to add the default search path to their lists...
643: */
644: Suff_DoPaths();
645:
646: /* print the initial graph, if the user requested it */
647: if (DEBUG(GRAPH1))
648: Targ_PrintGraph(1);
649:
650: /*
651: * Have now read the entire graph and need to make a list of targets
652: * to create. If none was given on the command line, we consult the
653: * parsing module to find the main target(s) to create.
654: */
655: if (Lst_IsEmpty(create))
656: targs = Parse_MainName();
657: else
658: targs = Targ_FindList(create, TARG_CREATE);
659:
660: /*
661: * this was original amMake -- want to allow parallelism, so put this
662: * back in, eventually.
663: */
664: if (!compatMake) {
665: /*
666: * Initialize job module before traversing the graph, now that
667: * any .BEGIN and .END targets have been read. This is done
668: * only if the -q flag wasn't given (to prevent the .BEGIN from
669: * being executed should it exist).
670: */
671: if (!queryFlag) {
672: if (maxLocal == -1)
673: maxLocal = maxJobs;
674: Job_Init(maxJobs, maxLocal);
675: jobsRunning = TRUE;
676: }
677:
678: /* Traverse the graph, checking on all the targets */
679: outOfDate = Make_Run(targs);
680: } else
681: /*
682: * Compat_Init will take care of creating all the targets as
683: * well as initializing the module.
684: */
685: Compat_Run(targs);
686:
687: Lst_Destroy(targs, NOFREE);
688: Lst_Destroy(makefiles, NOFREE);
689: Lst_Destroy(create, (void (*) __P((ClientData))) free);
690:
691: /* print the graph now it's been processed if the user requested it */
692: if (DEBUG(GRAPH2))
693: Targ_PrintGraph(2);
694:
695: Suff_End();
696: Targ_End();
697: Arch_End();
698: str_end();
699: Var_End();
700: Parse_End();
701: Dir_End();
702:
703: if (queryFlag && outOfDate)
704: return(1);
705: else
706: return(0);
707: }
708:
709: /*-
710: * ReadMakefile --
711: * Open and parse the given makefile.
712: *
713: * Results:
714: * TRUE if ok. FALSE if couldn't open file.
715: *
716: * Side Effects:
717: * lots
718: */
719: static Boolean
720: ReadMakefile(fname)
721: char *fname; /* makefile to read */
722: {
723: extern Lst parseIncPath, sysIncPath;
724: FILE *stream;
725: char *name, path[MAXPATHLEN + 1];
726:
727: if (!strcmp(fname, "-")) {
728: Parse_File("(stdin)", stdin);
729: Var_Set("MAKEFILE", "", VAR_GLOBAL);
730: } else {
731: if ((stream = fopen(fname, "r")) != NULL)
732: goto found;
733: /* if we've chdir'd, rebuild the path name */
734: if (curdir != objdir && *fname != '/') {
735: (void)sprintf(path, "%s/%s", curdir, fname);
736: if ((stream = fopen(path, "r")) != NULL) {
737: fname = path;
738: goto found;
739: }
740: }
741: /* look in -I and system include directories. */
742: name = Dir_FindFile(fname, parseIncPath);
743: if (!name)
744: name = Dir_FindFile(fname, sysIncPath);
745: if (!name || !(stream = fopen(name, "r")))
746: return(FALSE);
747: fname = name;
748: /*
749: * set the MAKEFILE variable desired by System V fans -- the
750: * placement of the setting here means it gets set to the last
751: * makefile specified, as it is set by SysV make.
752: */
753: found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
754: Parse_File(fname, stream);
755: (void)fclose(stream);
756: }
757: return(TRUE);
758: }
759:
760: /*-
761: * Error --
762: * Print an error message given its format.
763: *
764: * Results:
765: * None.
766: *
767: * Side Effects:
768: * The message is printed.
769: */
770: /* VARARGS */
771: void
772: #if __STDC__
773: Error(char *fmt, ...)
774: #else
775: Error(va_alist)
776: va_dcl
777: #endif
778: {
779: va_list ap;
780: #if __STDC__
781: va_start(ap, fmt);
782: #else
783: char *fmt;
784:
785: va_start(ap);
786: fmt = va_arg(ap, char *);
787: #endif
788: (void)vfprintf(stderr, fmt, ap);
789: va_end(ap);
790: (void)fprintf(stderr, "\n");
791: (void)fflush(stderr);
792: }
793:
794: /*-
795: * Fatal --
796: * Produce a Fatal error message. If jobs are running, waits for them
797: * to finish.
798: *
799: * Results:
800: * None
801: *
802: * Side Effects:
803: * The program exits
804: */
805: /* VARARGS */
806: void
807: #if __STDC__
808: Fatal(char *fmt, ...)
809: #else
810: Fatal(va_alist)
811: va_dcl
812: #endif
813: {
814: va_list ap;
815: #if __STDC__
816: va_start(ap, fmt);
817: #else
818: char *fmt;
819:
820: va_start(ap);
821: fmt = va_arg(ap, char *);
822: #endif
823: if (jobsRunning)
824: Job_Wait();
825:
826: (void)vfprintf(stderr, fmt, ap);
827: va_end(ap);
828: (void)fprintf(stderr, "\n");
829: (void)fflush(stderr);
830:
831: if (DEBUG(GRAPH2))
832: Targ_PrintGraph(2);
833: exit(2); /* Not 1 so -q can distinguish error */
834: }
835:
836: /*
837: * Punt --
838: * Major exception once jobs are being created. Kills all jobs, prints
839: * a message and exits.
840: *
841: * Results:
842: * None
843: *
844: * Side Effects:
845: * All children are killed indiscriminately and the program Lib_Exits
846: */
847: /* VARARGS */
848: void
849: #if __STDC__
850: Punt(char *fmt, ...)
851: #else
852: Punt(va_alist)
853: va_dcl
854: #endif
855: {
856: va_list ap;
857: #if __STDC__
858: va_start(ap, fmt);
859: #else
860: char *fmt;
861:
862: va_start(ap);
863: fmt = va_arg(ap, char *);
864: #endif
865:
866: (void)fprintf(stderr, "make: ");
867: (void)vfprintf(stderr, fmt, ap);
868: va_end(ap);
869: (void)fprintf(stderr, "\n");
870: (void)fflush(stderr);
871:
872: DieHorribly();
873: }
874:
875: /*-
876: * DieHorribly --
877: * Exit without giving a message.
878: *
879: * Results:
880: * None
881: *
882: * Side Effects:
883: * A big one...
884: */
885: void
886: DieHorribly()
887: {
888: if (jobsRunning)
889: Job_AbortAll();
890: if (DEBUG(GRAPH2))
891: Targ_PrintGraph(2);
892: exit(2); /* Not 1, so -q can distinguish error */
893: }
894:
895: /*
896: * Finish --
897: * Called when aborting due to errors in child shell to signal
898: * abnormal exit.
899: *
900: * Results:
901: * None
902: *
903: * Side Effects:
904: * The program exits
905: */
906: void
907: Finish(errors)
908: int errors; /* number of errors encountered in Make_Make */
909: {
910: Fatal("%d error%s", errors, errors == 1 ? "" : "s");
911: }
912:
913: /*
914: * emalloc --
915: * malloc, but die on error.
916: */
917: char *
918: emalloc(len)
919: size_t len;
920: {
921: char *p;
922:
923: if ((p = (char *) malloc(len)) == NULL)
924: enomem();
925: return(p);
926: }
927:
928: /*
929: * enomem --
930: * die when out of memory.
931: */
932: void
933: enomem()
934: {
935: (void)fprintf(stderr, "make: %s.\n", strerror(errno));
936: exit(2);
937: }
938:
939: /*
940: * usage --
941: * exit with usage message
942: */
943: static void
944: usage()
945: {
946: (void)fprintf(stderr,
947: "usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
948: [-I directory] [-j max_jobs] [variable=value]\n");
949: exit(2);
950: }
951:
952:
953: int
954: PrintAddr(a, b)
955: ClientData a;
956: ClientData b;
957: {
958: printf("%lx ", (unsigned long) a);
959: return b ? 0 : 0;
960: }