Annotation of src/usr.bin/make/main.c, Revision 1.42
1.42 ! espie 1: /* $OpenBSD: main.c,v 1.41 2000/09/14 13:32:07 espie Exp $ */
1.12 millert 2: /* $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $ */
1.1 deraadt 3:
4: /*
1.9 millert 5: * Copyright (c) 1988, 1989, 1990, 1993
6: * The Regents of the University of California. All rights reserved.
1.1 deraadt 7: * Copyright (c) 1989 by Berkeley Softworks
8: * All rights reserved.
9: *
10: * This code is derived from software contributed to Berkeley by
11: * Adam de Boor.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. All advertising materials mentioning features or use of this software
22: * must display the following acknowledgement:
23: * This product includes software developed by the University of
24: * California, Berkeley and its contributors.
25: * 4. Neither the name of the University nor the names of its contributors
26: * may be used to endorse or promote products derived from this software
27: * without specific prior written permission.
28: *
29: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39: * SUCH DAMAGE.
40: */
41:
42: /*-
43: * main.c --
44: * The main file for this entire program. Exit routines etc
45: * reside here.
46: *
47: * Utility functions defined in this file:
48: * Main_ParseArgLine Takes a line of arguments, breaks them and
49: * treats them as if they were given when first
50: * invoked. Used by the parse module to implement
51: * the .MFLAGS target.
52: *
53: * Error Print a tagged error message. The global
54: * MAKE variable must have been defined. This
55: * takes a format string and two optional
56: * arguments for it.
57: *
58: * Fatal Print an error message and exit. Also takes
59: * a format string and two arguments.
60: *
61: * Punt Aborts all jobs and exits with a message. Also
62: * takes a format string and two arguments.
63: *
64: * Finish Finish things up by printing the number of
65: * errors which occured, as passed to it, and
66: * exiting.
67: */
68:
69: #include <sys/types.h>
70: #include <sys/time.h>
71: #include <sys/param.h>
72: #include <sys/resource.h>
1.2 deraadt 73: #include <sys/signal.h>
1.1 deraadt 74: #include <sys/stat.h>
1.12 millert 75: #ifndef MAKE_BOOTSTRAP
1.1 deraadt 76: #include <sys/utsname.h>
1.9 millert 77: #endif
1.8 briggs 78: #include <sys/wait.h>
1.1 deraadt 79: #include <errno.h>
80: #include <fcntl.h>
81: #include <stdio.h>
1.12 millert 82: #include <stdlib.h>
1.14 espie 83: #include <time.h>
1.12 millert 84: #ifdef __STDC__
1.1 deraadt 85: #include <stdarg.h>
86: #else
87: #include <varargs.h>
88: #endif
89: #include "make.h"
90: #include "hash.h"
91: #include "dir.h"
92: #include "job.h"
93: #include "pathnames.h"
1.41 espie 94:
95: #ifndef lint
96: UNUSED
97: static char copyright[] =
98: "@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
99: The Regents of the University of California. All rights reserved.\n";
100: #endif /* not lint */
101:
102: #ifndef lint
103: #if 0
104: static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
105: #else
106: UNUSED
1.42 ! espie 107: static char rcsid[] = "$OpenBSD: main.c,v 1.41 2000/09/14 13:32:07 espie Exp $";
1.41 espie 108: #endif
109: #endif /* not lint */
110:
1.1 deraadt 111:
112: #ifndef DEFMAXLOCAL
113: #define DEFMAXLOCAL DEFMAXJOBS
1.4 niklas 114: #endif /* DEFMAXLOCAL */
1.1 deraadt 115:
116: #define MAKEFLAGS ".MAKEFLAGS"
117:
1.33 espie 118: LIST create; /* Targets to be made */
1.28 espie 119: time_t now = OUT_OF_DATE;/* Time at start of make */
1.1 deraadt 120: GNode *DEFAULT; /* .DEFAULT node */
121: Boolean allPrecious; /* .PRECIOUS given on line by itself */
122:
123: static Boolean noBuiltins; /* -r flag */
1.33 espie 124: static LIST makefiles; /* ordered list of makefiles to read */
1.9 millert 125: static Boolean printVars; /* print value of one or more vars */
1.33 espie 126: static LIST variables; /* list of variables to print */
1.2 deraadt 127: int maxJobs; /* -j argument */
1.1 deraadt 128: static int maxLocal; /* -L argument */
129: Boolean compatMake; /* -B argument */
130: Boolean debug; /* -d flag */
131: Boolean noExecute; /* -n flag */
132: Boolean keepgoing; /* -k flag */
133: Boolean queryFlag; /* -q flag */
134: Boolean touchFlag; /* -t flag */
135: Boolean usePipes; /* !-P flag */
136: Boolean ignoreErrors; /* -i flag */
137: Boolean beSilent; /* -s flag */
138: Boolean oldVars; /* variable substitution style */
139: Boolean checkEnvFirst; /* -e flag */
140: static Boolean jobsRunning; /* TRUE if the jobs might be running */
141:
1.9 millert 142: static void MainParseArgs __P((int, char **));
143: char * chdir_verify_path __P((char *, char *));
1.32 espie 144: static int ReadMakefile __P((void *, void *));
1.42 ! espie 145: static void add_dirpath __P((Lst, const char *));
1.9 millert 146: static void usage __P((void));
1.39 espie 147: static void posixParseOptLetter __P((char));
1.16 espie 148: int main __P((int, char **));
1.1 deraadt 149:
150: static char *curdir; /* startup directory */
151: static char *objdir; /* where we chdir'ed to */
152:
1.39 espie 153: static void
154: posixParseOptLetter(c)
155: char c;
156: {
157: switch(c) {
158: case 'B':
159: compatMake = TRUE;
160: break;
161: case 'P':
162: usePipes = FALSE;
163: Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
164: break;
165: case 'S':
166: keepgoing = FALSE;
167: Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
168: break;
169: case 'e':
170: checkEnvFirst = TRUE;
171: Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
172: break;
173: case 'i':
174: ignoreErrors = TRUE;
175: Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
176: break;
177: case 'k':
178: keepgoing = TRUE;
179: Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
180: break;
181: case 'n':
182: noExecute = TRUE;
183: Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
184: break;
185: case 'q':
186: queryFlag = TRUE;
187: /* Kind of nonsensical, wot? */
188: Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
189: break;
190: case 'r':
191: noBuiltins = TRUE;
192: Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
193: break;
194: case 's':
195: beSilent = TRUE;
196: Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
197: break;
198: case 't':
199: touchFlag = TRUE;
200: Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
201: break;
202: default:
203: case '?':
204: usage();
205: }
206: }
207:
1.1 deraadt 208: /*-
209: * MainParseArgs --
210: * Parse a given argument vector. Called from main() and from
211: * Main_ParseArgLine() when the .MAKEFLAGS target is used.
212: *
213: * XXX: Deal with command line overriding .MAKEFLAGS in makefile
214: *
215: * Results:
216: * None
217: *
218: * Side Effects:
219: * Various global and local flags will be set depending on the flags
220: * given
221: */
222: static void
223: MainParseArgs(argc, argv)
224: int argc;
225: char **argv;
226: {
227: extern int optind;
228: extern char *optarg;
229: int c;
1.2 deraadt 230: int forceJobs = 0;
1.1 deraadt 231:
232: optind = 1; /* since we're called more than once */
1.2 deraadt 233: #ifdef REMOTE
1.9 millert 234: # define OPTFLAGS "BD:I:L:PSV:d:ef:ij:km:nqrst"
1.1 deraadt 235: #else
1.9 millert 236: # define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"
1.1 deraadt 237: #endif
1.39 espie 238: # define OPTLETTERS "BPSiknqrst"
1.10 millert 239: rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
1.1 deraadt 240: switch(c) {
241: case 'D':
242: Var_Set(optarg, "1", VAR_GLOBAL);
243: Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
244: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
245: break;
246: case 'I':
247: Parse_AddIncludeDir(optarg);
248: Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
249: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
250: break;
1.9 millert 251: case 'V':
252: printVars = TRUE;
1.33 espie 253: Lst_AtEnd(&variables, optarg);
1.9 millert 254: Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
255: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
256: break;
1.2 deraadt 257: #ifdef REMOTE
1.15 espie 258: case 'L': {
259: char *endptr;
260:
261: maxLocal = strtol(optarg, &endptr, 0);
262: if (endptr == optarg) {
263: fprintf(stderr,
264: "make: illegal argument to -L option -- %s -- not a number\n",
265: optarg);
266: usage();
267: }
1.1 deraadt 268: Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
269: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
270: break;
1.15 espie 271: }
1.2 deraadt 272: #endif
1.1 deraadt 273: case 'd': {
274: char *modules = optarg;
275:
276: for (; *modules; ++modules)
277: switch (*modules) {
278: case 'A':
279: debug = ~0;
280: break;
281: case 'a':
282: debug |= DEBUG_ARCH;
283: break;
284: case 'c':
285: debug |= DEBUG_COND;
286: break;
287: case 'd':
288: debug |= DEBUG_DIR;
289: break;
290: case 'f':
291: debug |= DEBUG_FOR;
292: break;
293: case 'g':
294: if (modules[1] == '1') {
295: debug |= DEBUG_GRAPH1;
296: ++modules;
297: }
298: else if (modules[1] == '2') {
299: debug |= DEBUG_GRAPH2;
300: ++modules;
301: }
302: break;
303: case 'j':
304: debug |= DEBUG_JOB;
305: break;
306: case 'm':
307: debug |= DEBUG_MAKE;
308: break;
309: case 's':
310: debug |= DEBUG_SUFF;
311: break;
312: case 't':
313: debug |= DEBUG_TARG;
314: break;
315: case 'v':
316: debug |= DEBUG_VAR;
317: break;
318: default:
319: (void)fprintf(stderr,
320: "make: illegal argument to d option -- %c\n",
321: *modules);
322: usage();
323: }
324: Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
325: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
326: break;
327: }
328: case 'f':
1.33 espie 329: Lst_AtEnd(&makefiles, optarg);
1.1 deraadt 330: break;
1.15 espie 331: case 'j': {
332: char *endptr;
333:
1.2 deraadt 334: forceJobs = TRUE;
1.15 espie 335: maxJobs = strtol(optarg, &endptr, 0);
336: if (endptr == optarg) {
337: fprintf(stderr,
338: "make: illegal argument to -j option -- %s -- not a number\n",
339: optarg);
340: usage();
341: }
1.1 deraadt 342: maxJobs = atoi(optarg);
1.2 deraadt 343: #ifndef REMOTE
344: maxLocal = maxJobs;
345: #endif
1.1 deraadt 346: Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
347: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
348: break;
1.15 espie 349: }
1.5 niklas 350: case 'm':
1.42 ! espie 351: Dir_AddDir(&sysIncPath, optarg, NULL);
1.5 niklas 352: Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
353: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
354: break;
1.1 deraadt 355: default:
1.39 espie 356: posixParseOptLetter(c);
1.1 deraadt 357: }
358: }
359:
1.2 deraadt 360: /*
361: * Be compatible if user did not specify -j and did not explicitly
362: * turned compatibility on
363: */
364: if (!compatMake && !forceJobs)
365: compatMake = TRUE;
366:
1.1 deraadt 367: oldVars = TRUE;
368:
369: /*
370: * See if the rest of the arguments are variable assignments and
371: * perform them if so. Else take them to be targets and stuff them
372: * on the end of the "create" list.
373: */
374: for (argv += optind, argc -= optind; *argv; ++argv, --argc)
1.3 deraadt 375: if (Parse_IsVar(*argv)) {
1.9 millert 376: char *var = estrdup(*argv);
1.3 deraadt 377:
378: Parse_DoVar(var, VAR_CMD);
379: free(var);
380: } else {
1.1 deraadt 381: if (!**argv)
382: Punt("illegal (null) argument.");
383: if (**argv == '-') {
384: if ((*argv)[1])
385: optind = 0; /* -flag... */
386: else
387: optind = 1; /* - */
388: goto rearg;
389: }
1.33 espie 390: Lst_AtEnd(&create, estrdup(*argv));
1.1 deraadt 391: }
392: }
393:
394: /*-
395: * Main_ParseArgLine --
396: * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
397: * is encountered and by main() when reading the .MAKEFLAGS envariable.
398: * Takes a line of arguments and breaks it into its
399: * component words and passes those words and the number of them to the
400: * MainParseArgs function.
401: * The line should have all its leading whitespace removed.
402: *
403: * Results:
404: * None
405: *
406: * Side Effects:
407: * Only those that come from the various arguments.
408: */
409: void
410: Main_ParseArgLine(line)
411: char *line; /* Line to fracture */
412: {
413: char **argv; /* Manufactured argument vector */
414: int argc; /* Number of arguments in argv */
1.14 espie 415: char *args; /* Space used by the args */
1.19 espie 416: char *buf;
1.39 espie 417: char *argv0;
418: char *s;
1.1 deraadt 419:
420: if (line == NULL)
421: return;
422: for (; *line == ' '; ++line)
423: continue;
424: if (!*line)
425: return;
426:
1.39 espie 427: /* POSIX rule: MAKEFLAGS can hold a set of option letters without
428: * any blanks or dashes. */
429: for (s = line;; s++) {
430: if (*s == '\0') {
431: while (line != s)
432: posixParseOptLetter(*line++);
433: return;
434: }
435: if (strchr(OPTLETTERS, *s) == NULL)
436: break;
437: }
438: argv0 = Var_Value(".MAKE", VAR_GLOBAL);
1.14 espie 439: buf = emalloc(strlen(line) + strlen(argv0) + 2);
440: (void)sprintf(buf, "%s %s", argv0, line);
441:
442: argv = brk_string(buf, &argc, TRUE, &args);
443: free(buf);
1.1 deraadt 444: MainParseArgs(argc, argv);
1.14 espie 445:
446: free(args);
447: free(argv);
1.1 deraadt 448: }
449:
1.9 millert 450: char *
451: chdir_verify_path(path, obpath)
452: char *path;
453: char *obpath;
454: {
455: struct stat sb;
456:
457: if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
458: if (chdir(path)) {
459: (void)fprintf(stderr, "make warning: %s: %s.\n",
460: path, strerror(errno));
461: return 0;
462: }
463: else {
464: if (path[0] != '/') {
465: (void) snprintf(obpath, MAXPATHLEN, "%s/%s",
466: curdir, path);
467: return obpath;
468: }
469: else
470: return path;
471: }
472: }
473:
474: return 0;
475: }
476:
1.42 ! espie 477: /* Add a :-separated path to a Lst of directories. */
! 478: static void
! 479: add_dirpath(l, n)
! 480: Lst l;
! 481: const char *n;
! 482: {
! 483: const char *start;
! 484: const char *cp;
! 485:
! 486: for (start = n;;) {
! 487: for (cp = start; *cp != '\0' && *cp != ':';)
! 488: cp++;
! 489: Dir_AddDir(l, start, cp);
! 490: if (*cp == '\0')
! 491: break;
! 492: else
! 493: start= cp+1;
! 494: }
! 495: }
! 496:
1.9 millert 497:
1.1 deraadt 498: /*-
499: * main --
500: * The main function, for obvious reasons. Initializes variables
501: * and a few modules, then parses the arguments give it in the
502: * environment and on the command line. Reads the system makefile
503: * followed by either Makefile, makefile or the file given by the
504: * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
505: * flags it has received by then uses either the Make or the Compat
506: * module to create the initial list of targets.
507: *
508: * Results:
509: * If -q was given, exits -1 if anything was out-of-date. Else it exits
510: * 0.
511: *
512: * Side Effects:
513: * The program exits when done. Targets are created. etc. etc. etc.
514: */
515: int
516: main(argc, argv)
517: int argc;
518: char **argv;
519: {
1.34 espie 520: LIST targs; /* target nodes to create -- passed to Make_Init */
1.1 deraadt 521: Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
522: struct stat sb, sa;
1.19 espie 523: char *p, *path, *pathp, *pwd;
1.1 deraadt 524: char mdpath[MAXPATHLEN + 1];
525: char obpath[MAXPATHLEN + 1];
526: char cdpath[MAXPATHLEN + 1];
527: char *machine = getenv("MACHINE");
1.12 millert 528: char *machine_arch = getenv("MACHINE_ARCH");
1.5 niklas 529: /* avoid faults on read-only strings */
530: static char syspath[] = _PATH_DEFSYSPATH;
1.1 deraadt 531:
1.2 deraadt 532: #ifdef RLIMIT_NOFILE
533: /*
534: * get rid of resource limit on file descriptors
535: */
536: {
537: struct rlimit rl;
538: if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
539: rl.rlim_cur != rl.rlim_max) {
540: rl.rlim_cur = rl.rlim_max;
541: (void) setrlimit(RLIMIT_NOFILE, &rl);
542: }
543: }
544: #endif
1.1 deraadt 545: /*
546: * Find where we are and take care of PWD for the automounter...
547: * All this code is so that we know where we are when we start up
548: * on a different machine with pmake.
549: */
550: curdir = cdpath;
551: if (getcwd(curdir, MAXPATHLEN) == NULL) {
552: (void)fprintf(stderr, "make: %s.\n", strerror(errno));
553: exit(2);
554: }
555:
556: if (stat(curdir, &sa) == -1) {
557: (void)fprintf(stderr, "make: %s: %s.\n",
558: curdir, strerror(errno));
559: exit(2);
560: }
561:
562: if ((pwd = getenv("PWD")) != NULL) {
563: if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
1.9 millert 564: sa.st_dev == sb.st_dev)
1.1 deraadt 565: (void) strcpy(curdir, pwd);
566: }
567:
568: /*
569: * Get the name of this type of MACHINE from utsname
570: * so we can share an executable for similar machines.
571: * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
572: *
1.12 millert 573: * Note that both MACHINE and MACHINE_ARCH are decided at
574: * run-time.
1.1 deraadt 575: */
1.12 millert 576: if (!machine) {
577: #ifndef MAKE_BOOTSTRAP
1.9 millert 578: struct utsname utsname;
579:
1.2 deraadt 580: if (uname(&utsname) == -1) {
1.1 deraadt 581: perror("make: uname");
582: exit(2);
583: }
584: machine = utsname.machine;
1.6 niklas 585: #else
586: machine = MACHINE;
587: #endif
1.1 deraadt 588: }
589:
1.12 millert 590: if (!machine_arch) {
591: #ifndef MACHINE_ARCH
592: machine_arch = "unknown"; /* XXX: no uname -p yet */
593: #else
594: machine_arch = MACHINE_ARCH;
595: #endif
596: }
597:
1.1 deraadt 598: /*
1.9 millert 599: * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
600: * exists, change into it and build there. (If a .${MACHINE} suffix
601: * exists, use that directory instead).
602: * Otherwise check MAKEOBJDIRPREFIX`cwd` (or by default,
603: * _PATH_OBJDIRPREFIX`cwd`) and build there if it exists.
604: * If all fails, use the current directory to build.
605: *
606: * Once things are initted,
607: * have to add the original directory to the search path,
1.1 deraadt 608: * and modify the paths for the Makefiles apropriately. The
609: * current directory is also placed as a variable for make scripts.
610: */
1.9 millert 611: if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
612: if (!(path = getenv("MAKEOBJDIR"))) {
613: path = _PATH_OBJDIR;
614: pathp = _PATH_OBJDIRPREFIX;
615: (void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
616: path, machine);
617: if (!(objdir = chdir_verify_path(mdpath, obpath)))
618: if (!(objdir=chdir_verify_path(path, obpath))) {
619: (void) snprintf(mdpath, MAXPATHLEN,
620: "%s%s", pathp, curdir);
621: if (!(objdir=chdir_verify_path(mdpath,
622: obpath)))
623: objdir = curdir;
624: }
625: }
626: else if (!(objdir = chdir_verify_path(path, obpath)))
1.1 deraadt 627: objdir = curdir;
628: }
629: else {
1.9 millert 630: (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
631: if (!(objdir = chdir_verify_path(mdpath, obpath)))
1.1 deraadt 632: objdir = curdir;
633: }
634:
635: setenv("PWD", objdir, 1);
1.30 espie 636: unsetenv("CDPATH");
1.1 deraadt 637:
1.33 espie 638: Lst_Init(&create);
639: Lst_Init(&makefiles);
1.9 millert 640: printVars = FALSE;
1.33 espie 641: Lst_Init(&variables);
1.1 deraadt 642: beSilent = FALSE; /* Print commands as executed */
643: ignoreErrors = FALSE; /* Pay attention to non-zero returns */
644: noExecute = FALSE; /* Execute all commands */
645: keepgoing = FALSE; /* Stop on error */
646: allPrecious = FALSE; /* Remove targets when interrupted */
647: queryFlag = FALSE; /* This is not just a check-run */
648: noBuiltins = FALSE; /* Read the built-in rules */
649: touchFlag = FALSE; /* Actually update targets */
650: usePipes = TRUE; /* Catch child output in pipes */
651: debug = 0; /* No debug verbosity, please. */
652: jobsRunning = FALSE;
653:
1.2 deraadt 654: maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
655: #ifdef REMOTE
1.1 deraadt 656: maxJobs = DEFMAXJOBS; /* Set default max concurrency */
657: #else
1.2 deraadt 658: maxJobs = maxLocal;
1.1 deraadt 659: #endif
1.2 deraadt 660: compatMake = FALSE; /* No compat mode */
1.9 millert 661:
1.1 deraadt 662:
663: /*
664: * Initialize the parsing, directory and variable modules to prepare
665: * for the reading of inclusion paths and variable settings on the
666: * command line
667: */
668: Dir_Init(); /* Initialize directory structures so -I flags
669: * can be processed correctly */
670: Parse_Init(); /* Need to initialize the paths of #include
671: * directories */
672: Var_Init(); /* As well as the lists of variables for
673: * parsing arguments */
674: if (objdir != curdir)
1.42 ! espie 675: Dir_AddDir(&dirSearchPath, curdir, NULL);
1.1 deraadt 676: Var_Set(".CURDIR", curdir, VAR_GLOBAL);
677: Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
678:
679: /*
680: * Initialize various variables.
681: * MAKE also gets this name, for compatibility
682: * .MAKEFLAGS gets set to the empty string just in case.
683: * MFLAGS also gets initialized empty, for compatibility.
684: */
685: Var_Set("MAKE", argv[0], VAR_GLOBAL);
1.14 espie 686: Var_Set(".MAKE", argv[0], VAR_GLOBAL);
1.1 deraadt 687: Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
688: Var_Set("MFLAGS", "", VAR_GLOBAL);
689: Var_Set("MACHINE", machine, VAR_GLOBAL);
1.12 millert 690: Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
1.1 deraadt 691:
692: /*
693: * First snag any flags out of the MAKE environment variable.
694: * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
695: * in a different format).
696: */
697: #ifdef POSIX
698: Main_ParseArgLine(getenv("MAKEFLAGS"));
699: #else
700: Main_ParseArgLine(getenv("MAKE"));
701: #endif
1.9 millert 702:
1.1 deraadt 703: MainParseArgs(argc, argv);
1.30 espie 704:
1.40 espie 705: #ifdef POSIX
1.39 espie 706: Var_AddCmdline(MAKEFLAGS);
707: #endif
1.1 deraadt 708:
709: /*
710: * Initialize archive, target and suffix modules in preparation for
711: * parsing the makefile(s)
712: */
713: Arch_Init();
714: Targ_Init();
715: Suff_Init();
716:
1.25 espie 717: DEFAULT = NULL;
1.1 deraadt 718: (void)time(&now);
719:
720: /*
721: * Set up the .TARGETS variable to contain the list of targets to be
722: * created. If none specified, make the variable empty -- the parser
723: * will fill the thing in with the default or .MAIN target.
724: */
1.33 espie 725: if (!Lst_IsEmpty(&create)) {
1.1 deraadt 726: LstNode ln;
727:
1.35 espie 728: for (ln = Lst_First(&create); ln != NULL; ln = Lst_Adv(ln)) {
1.1 deraadt 729: char *name = (char *)Lst_Datum(ln);
730:
731: Var_Append(".TARGETS", name, VAR_GLOBAL);
732: }
733: } else
734: Var_Set(".TARGETS", "", VAR_GLOBAL);
735:
1.5 niklas 736:
737: /*
738: * If no user-supplied system path was given (through the -m option)
739: * add the directories from the DEFSYSPATH (more than one may be given
740: * as dir1:...:dirn) to the system include path.
741: */
1.42 ! espie 742: if (Lst_IsEmpty(&sysIncPath))
! 743: add_dirpath(&sysIncPath, syspath);
1.5 niklas 744:
1.1 deraadt 745: /*
1.5 niklas 746: * Read in the built-in rules first, followed by the specified
747: * makefile, if it was (makefile != (char *) NULL), or the default
748: * Makefile and makefile, in that order, if it wasn't.
1.1 deraadt 749: */
1.5 niklas 750: if (!noBuiltins) {
751: LstNode ln;
1.33 espie 752: LIST sysMkPath; /* Path of sys.mk */
1.5 niklas 753:
1.33 espie 754: Lst_Init(&sysMkPath);
755: Dir_Expand(_PATH_DEFSYSMK, &sysIncPath, &sysMkPath);
756: if (Lst_IsEmpty(&sysMkPath))
1.5 niklas 757: Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
1.33 espie 758: ln = Lst_Find(&sysMkPath, ReadMakefile, NULL);
1.25 espie 759: if (ln != NULL)
1.5 niklas 760: Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1.34 espie 761: #ifdef CLEANUP
762: Lst_Destroy(&sysMkPath, (SimpleProc)free);
763: #endif
1.5 niklas 764: }
1.1 deraadt 765:
1.33 espie 766: if (!Lst_IsEmpty(&makefiles)) {
1.1 deraadt 767: LstNode ln;
768:
1.33 espie 769: ln = Lst_Find(&makefiles, ReadMakefile, NULL);
1.25 espie 770: if (ln != NULL)
1.1 deraadt 771: Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1.13 niklas 772: } else if (!ReadMakefile("BSDmakefile", NULL))
773: if (!ReadMakefile("makefile", NULL))
774: (void)ReadMakefile("Makefile", NULL);
1.1 deraadt 775:
1.9 millert 776: (void)ReadMakefile(".depend", NULL);
1.1 deraadt 777:
1.19 espie 778: Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
1.1 deraadt 779:
780: /* Install all the flags into the MAKE envariable. */
1.19 espie 781: if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) != NULL) && *p)
1.1 deraadt 782: #ifdef POSIX
783: setenv("MAKEFLAGS", p, 1);
784: #else
785: setenv("MAKE", p, 1);
786: #endif
787:
788: /*
789: * For compatibility, look at the directories in the VPATH variable
790: * and add them to the search path, if the variable is defined. The
791: * variable's value is in the same format as the PATH envariable, i.e.
792: * <directory>:<directory>:<directory>...
793: */
794: if (Var_Exists("VPATH", VAR_CMD)) {
1.42 ! espie 795: char *vpath;
1.1 deraadt 796: /*
797: * GCC stores string constants in read-only memory, but
798: * Var_Subst will want to write this thing, so store it
799: * in an array
800: */
801: static char VPATH[] = "${VPATH}";
802:
1.36 espie 803: vpath = Var_Subst(VPATH, (SymTable *)VAR_CMD, FALSE);
1.42 ! espie 804: add_dirpath(&dirSearchPath, vpath);
! 805: (void)free(vpath);
1.1 deraadt 806: }
807:
808: /*
809: * Now that all search paths have been read for suffixes et al, it's
810: * time to add the default search path to their lists...
811: */
812: Suff_DoPaths();
813:
814: /* print the initial graph, if the user requested it */
815: if (DEBUG(GRAPH1))
816: Targ_PrintGraph(1);
817:
1.9 millert 818: /* print the values of any variables requested by the user */
819: if (printVars) {
820: LstNode ln;
821:
1.35 espie 822: for (ln = Lst_First(&variables); ln != NULL; ln = Lst_Adv(ln)) {
1.9 millert 823: char *value = Var_Value((char *)Lst_Datum(ln),
1.19 espie 824: VAR_GLOBAL);
1.9 millert 825:
826: printf("%s\n", value ? value : "");
827: }
828: }
829:
1.1 deraadt 830: /*
831: * Have now read the entire graph and need to make a list of targets
832: * to create. If none was given on the command line, we consult the
833: * parsing module to find the main target(s) to create.
834: */
1.34 espie 835: Lst_Init(&targs);
836: if (!Lst_IsEmpty(&create))
837: Targ_FindList(&targs, &create);
1.1 deraadt 838: else
1.34 espie 839: Parse_MainName(&targs);
1.1 deraadt 840:
1.9 millert 841: if (!compatMake && !printVars) {
1.1 deraadt 842: /*
843: * Initialize job module before traversing the graph, now that
844: * any .BEGIN and .END targets have been read. This is done
845: * only if the -q flag wasn't given (to prevent the .BEGIN from
846: * being executed should it exist).
847: */
848: if (!queryFlag) {
849: if (maxLocal == -1)
850: maxLocal = maxJobs;
851: Job_Init(maxJobs, maxLocal);
852: jobsRunning = TRUE;
853: }
854:
855: /* Traverse the graph, checking on all the targets */
1.34 espie 856: outOfDate = Make_Run(&targs);
1.9 millert 857: } else if (!printVars) {
1.1 deraadt 858: /*
859: * Compat_Init will take care of creating all the targets as
860: * well as initializing the module.
861: */
1.34 espie 862: Compat_Run(&targs);
1.9 millert 863: }
864:
1.34 espie 865: Lst_Destroy(&targs, NOFREE);
1.33 espie 866: Lst_Destroy(&variables, NOFREE);
867: Lst_Destroy(&makefiles, NOFREE);
868: Lst_Destroy(&create, (SimpleProc)free);
1.1 deraadt 869:
870: /* print the graph now it's been processed if the user requested it */
871: if (DEBUG(GRAPH2))
872: Targ_PrintGraph(2);
873:
874: Suff_End();
875: Targ_End();
876: Arch_End();
877: Var_End();
878: Parse_End();
879: Dir_End();
1.14 espie 880: Job_End();
1.1 deraadt 881:
882: if (queryFlag && outOfDate)
883: return(1);
884: else
885: return(0);
886: }
887:
888: /*-
889: * ReadMakefile --
890: * Open and parse the given makefile.
891: *
892: * Results:
893: * TRUE if ok. FALSE if couldn't open file.
894: *
895: * Side Effects:
896: * lots
897: */
898: static Boolean
1.9 millert 899: ReadMakefile(p, q)
1.32 espie 900: void *p;
901: void *q;
1.1 deraadt 902: {
1.9 millert 903: char *fname = p; /* makefile to read */
1.33 espie 904: extern LIST parseIncPath;
1.1 deraadt 905: FILE *stream;
906: char *name, path[MAXPATHLEN + 1];
907:
908: if (!strcmp(fname, "-")) {
1.37 espie 909: Parse_File(estrdup("(stdin)"), stdin);
1.1 deraadt 910: Var_Set("MAKEFILE", "", VAR_GLOBAL);
911: } else {
912: if ((stream = fopen(fname, "r")) != NULL)
913: goto found;
914: /* if we've chdir'd, rebuild the path name */
915: if (curdir != objdir && *fname != '/') {
916: (void)sprintf(path, "%s/%s", curdir, fname);
917: if ((stream = fopen(path, "r")) != NULL) {
1.38 espie 918: fname = estrdup(path);
1.1 deraadt 919: goto found;
920: }
921: }
922: /* look in -I and system include directories. */
1.33 espie 923: name = Dir_FindFile(fname, &parseIncPath);
1.1 deraadt 924: if (!name)
1.33 espie 925: name = Dir_FindFile(fname, &sysIncPath);
1.1 deraadt 926: if (!name || !(stream = fopen(name, "r")))
927: return(FALSE);
928: fname = name;
929: /*
930: * set the MAKEFILE variable desired by System V fans -- the
931: * placement of the setting here means it gets set to the last
932: * makefile specified, as it is set by SysV make.
933: */
934: found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
935: Parse_File(fname, stream);
936: (void)fclose(stream);
937: }
938: return(TRUE);
939: }
940:
941: /*-
1.8 briggs 942: * Cmd_Exec --
943: * Execute the command in cmd, and return the output of that command
944: * in a string.
945: *
946: * Results:
947: * A string containing the output of the command, or the empty string
948: * If err is not NULL, it contains the reason for the command failure
949: *
950: * Side Effects:
951: * The string must be freed by the caller.
952: */
953: char *
954: Cmd_Exec(cmd, err)
955: char *cmd;
956: char **err;
957: {
958: char *args[4]; /* Args for invoking the shell */
959: int fds[2]; /* Pipe streams */
960: int cpid; /* Child PID */
961: int pid; /* PID from wait() */
962: char *res; /* result */
963: int status; /* command exit status */
1.22 espie 964: BUFFER buf; /* buffer to store the result */
1.8 briggs 965: char *cp;
1.17 espie 966: ssize_t cc;
1.18 espie 967: size_t length;
1.8 briggs 968:
969:
970: *err = NULL;
971:
972: /*
973: * Set up arguments for shell
974: */
975: args[0] = "sh";
976: args[1] = "-c";
977: args[2] = cmd;
978: args[3] = NULL;
979:
980: /*
981: * Open a pipe for fetching its output
982: */
983: if (pipe(fds) == -1) {
984: *err = "Couldn't create pipe for \"%s\"";
985: goto bad;
986: }
987:
988: /*
989: * Fork
990: */
991: switch (cpid = vfork()) {
992: case 0:
993: /*
994: * Close input side of pipe
995: */
996: (void) close(fds[0]);
997:
998: /*
999: * Duplicate the output stream to the shell's output, then
1000: * shut the extra thing down. Note we don't fetch the error
1001: * stream...why not? Why?
1002: */
1003: (void) dup2(fds[1], 1);
1004: (void) close(fds[1]);
1.9 millert 1005:
1.8 briggs 1006: (void) execv("/bin/sh", args);
1007: _exit(1);
1008: /*NOTREACHED*/
1009:
1010: case -1:
1011: *err = "Couldn't exec \"%s\"";
1012: goto bad;
1013:
1014: default:
1015: /*
1016: * No need for the writing half
1017: */
1018: (void) close(fds[1]);
1.9 millert 1019:
1.22 espie 1020: Buf_Init(&buf, MAKE_BSIZE);
1.8 briggs 1021:
1022: do {
1023: char result[BUFSIZ];
1024: cc = read(fds[0], result, sizeof(result));
1.9 millert 1025: if (cc > 0)
1.22 espie 1026: Buf_AddChars(&buf, cc, result);
1.8 briggs 1027: }
1028: while (cc > 0 || (cc == -1 && errno == EINTR));
1029:
1030: /*
1031: * Close the input side of the pipe.
1032: */
1033: (void) close(fds[0]);
1034:
1035: /*
1036: * Wait for the process to exit.
1037: */
1038: while(((pid = wait(&status)) != cpid) && (pid >= 0))
1039: continue;
1040:
1.22 espie 1041: res = Buf_Retrieve(&buf);
1042: length = Buf_Size(&buf);
1.8 briggs 1043:
1.17 espie 1044: if (cc == -1)
1.8 briggs 1045: *err = "Couldn't read shell's output for \"%s\"";
1046:
1047: if (status)
1048: *err = "\"%s\" returned non-zero status";
1049:
1050: /*
1051: * Null-terminate the result, convert newlines to spaces and
1052: * install it in the variable.
1053: */
1.17 espie 1054: res[length] = '\0';
1055: cp = res + length - 1;
1.8 briggs 1056:
1057: if (*cp == '\n') {
1058: /*
1059: * A final newline is just stripped
1060: */
1061: *cp-- = '\0';
1062: }
1063: while (cp >= res) {
1064: if (*cp == '\n') {
1065: *cp = ' ';
1066: }
1067: cp--;
1068: }
1069: break;
1070: }
1071: return res;
1072: bad:
1073: res = emalloc(1);
1074: *res = '\0';
1075: return res;
1076: }
1077:
1078: /*-
1.1 deraadt 1079: * Error --
1080: * Print an error message given its format.
1081: *
1082: * Results:
1083: * None.
1084: *
1085: * Side Effects:
1086: * The message is printed.
1087: */
1088: /* VARARGS */
1089: void
1.12 millert 1090: #ifdef __STDC__
1.1 deraadt 1091: Error(char *fmt, ...)
1092: #else
1093: Error(va_alist)
1094: va_dcl
1095: #endif
1096: {
1097: va_list ap;
1.12 millert 1098: #ifdef __STDC__
1.1 deraadt 1099: va_start(ap, fmt);
1100: #else
1101: char *fmt;
1102:
1103: va_start(ap);
1104: fmt = va_arg(ap, char *);
1105: #endif
1106: (void)vfprintf(stderr, fmt, ap);
1107: va_end(ap);
1108: (void)fprintf(stderr, "\n");
1109: (void)fflush(stderr);
1110: }
1111:
1112: /*-
1113: * Fatal --
1114: * Produce a Fatal error message. If jobs are running, waits for them
1115: * to finish.
1116: *
1117: * Results:
1118: * None
1119: *
1120: * Side Effects:
1121: * The program exits
1122: */
1123: /* VARARGS */
1124: void
1.12 millert 1125: #ifdef __STDC__
1.1 deraadt 1126: Fatal(char *fmt, ...)
1127: #else
1128: Fatal(va_alist)
1129: va_dcl
1130: #endif
1131: {
1132: va_list ap;
1.12 millert 1133: #ifdef __STDC__
1.1 deraadt 1134: va_start(ap, fmt);
1135: #else
1136: char *fmt;
1137:
1138: va_start(ap);
1139: fmt = va_arg(ap, char *);
1140: #endif
1141: if (jobsRunning)
1142: Job_Wait();
1143:
1144: (void)vfprintf(stderr, fmt, ap);
1145: va_end(ap);
1146: (void)fprintf(stderr, "\n");
1147: (void)fflush(stderr);
1148:
1149: if (DEBUG(GRAPH2))
1150: Targ_PrintGraph(2);
1151: exit(2); /* Not 1 so -q can distinguish error */
1152: }
1153:
1154: /*
1155: * Punt --
1156: * Major exception once jobs are being created. Kills all jobs, prints
1157: * a message and exits.
1158: *
1159: * Results:
1.9 millert 1160: * None
1.1 deraadt 1161: *
1162: * Side Effects:
1163: * All children are killed indiscriminately and the program Lib_Exits
1164: */
1165: /* VARARGS */
1166: void
1.12 millert 1167: #ifdef __STDC__
1.1 deraadt 1168: Punt(char *fmt, ...)
1169: #else
1170: Punt(va_alist)
1171: va_dcl
1172: #endif
1173: {
1174: va_list ap;
1.12 millert 1175: #ifdef __STDC__
1.1 deraadt 1176: va_start(ap, fmt);
1177: #else
1178: char *fmt;
1179:
1180: va_start(ap);
1181: fmt = va_arg(ap, char *);
1182: #endif
1183:
1184: (void)fprintf(stderr, "make: ");
1185: (void)vfprintf(stderr, fmt, ap);
1186: va_end(ap);
1187: (void)fprintf(stderr, "\n");
1188: (void)fflush(stderr);
1189:
1190: DieHorribly();
1191: }
1192:
1193: /*-
1194: * DieHorribly --
1195: * Exit without giving a message.
1196: *
1197: * Results:
1198: * None
1199: *
1200: * Side Effects:
1201: * A big one...
1202: */
1203: void
1204: DieHorribly()
1205: {
1206: if (jobsRunning)
1207: Job_AbortAll();
1208: if (DEBUG(GRAPH2))
1209: Targ_PrintGraph(2);
1210: exit(2); /* Not 1, so -q can distinguish error */
1211: }
1212:
1213: /*
1214: * Finish --
1215: * Called when aborting due to errors in child shell to signal
1.9 millert 1216: * abnormal exit.
1.1 deraadt 1217: *
1218: * Results:
1.9 millert 1219: * None
1.1 deraadt 1220: *
1221: * Side Effects:
1222: * The program exits
1223: */
1224: void
1225: Finish(errors)
1226: int errors; /* number of errors encountered in Make_Make */
1227: {
1228: Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1229: }
1230:
1231: /*
1232: * usage --
1233: * exit with usage message
1234: */
1235: static void
1236: usage()
1237: {
1238: (void)fprintf(stderr,
1.9 millert 1239: "usage: make [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
1240: [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
1241: [variable=value] [target ...]\n");
1.1 deraadt 1242: exit(2);
1243: }
1244:
1245:
1.31 espie 1246: void
1247: PrintAddr(a)
1.32 espie 1248: void *a;
1.1 deraadt 1249: {
1250: printf("%lx ", (unsigned long) a);
1251: }