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