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