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