Annotation of src/usr.bin/make/main.c, Revision 1.45
1.45 ! espie 1: /* $OpenBSD: main.c,v 1.44 2000/10/13 08:29:20 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>
1.43 espie 81: #include <stddef.h>
1.1 deraadt 82: #include <stdio.h>
1.12 millert 83: #include <stdlib.h>
1.14 espie 84: #include <time.h>
1.12 millert 85: #ifdef __STDC__
1.1 deraadt 86: #include <stdarg.h>
87: #else
88: #include <varargs.h>
89: #endif
90: #include "make.h"
1.43 espie 91: #include "ohash.h"
1.1 deraadt 92: #include "dir.h"
93: #include "job.h"
94: #include "pathnames.h"
1.41 espie 95:
96: #ifndef lint
97: UNUSED
98: static char copyright[] =
99: "@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
100: The Regents of the University of California. All rights reserved.\n";
101: #endif /* not lint */
102:
103: #ifndef lint
104: #if 0
105: static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
106: #else
107: UNUSED
1.45 ! espie 108: static char rcsid[] = "$OpenBSD: main.c,v 1.44 2000/10/13 08:29:20 espie Exp $";
1.41 espie 109: #endif
110: #endif /* not lint */
111:
1.1 deraadt 112:
113: #ifndef DEFMAXLOCAL
114: #define DEFMAXLOCAL DEFMAXJOBS
1.4 niklas 115: #endif /* DEFMAXLOCAL */
1.1 deraadt 116:
117: #define MAKEFLAGS ".MAKEFLAGS"
118:
1.33 espie 119: LIST create; /* Targets to be made */
1.45 ! espie 120: TIMESTAMP now; /* Time at start of make */
1.1 deraadt 121: GNode *DEFAULT; /* .DEFAULT node */
122: Boolean allPrecious; /* .PRECIOUS given on line by itself */
123:
124: static Boolean noBuiltins; /* -r flag */
1.33 espie 125: static LIST makefiles; /* ordered list of makefiles to read */
1.9 millert 126: static Boolean printVars; /* print value of one or more vars */
1.33 espie 127: static LIST variables; /* list of variables to print */
1.2 deraadt 128: int maxJobs; /* -j argument */
1.1 deraadt 129: static int maxLocal; /* -L argument */
130: Boolean compatMake; /* -B argument */
131: Boolean debug; /* -d flag */
132: Boolean noExecute; /* -n flag */
133: Boolean keepgoing; /* -k flag */
134: Boolean queryFlag; /* -q flag */
135: Boolean touchFlag; /* -t flag */
136: Boolean usePipes; /* !-P flag */
137: Boolean ignoreErrors; /* -i flag */
138: Boolean beSilent; /* -s flag */
139: Boolean oldVars; /* variable substitution style */
140: Boolean checkEnvFirst; /* -e flag */
141: static Boolean jobsRunning; /* TRUE if the jobs might be running */
142:
1.9 millert 143: static void MainParseArgs __P((int, char **));
144: char * chdir_verify_path __P((char *, char *));
1.32 espie 145: static int ReadMakefile __P((void *, void *));
1.42 espie 146: static void add_dirpath __P((Lst, const char *));
1.9 millert 147: static void usage __P((void));
1.39 espie 148: static void posixParseOptLetter __P((char));
1.16 espie 149: int main __P((int, char **));
1.1 deraadt 150:
151: static char *curdir; /* startup directory */
152: static char *objdir; /* where we chdir'ed to */
153:
1.39 espie 154: static void
155: posixParseOptLetter(c)
156: char c;
157: {
158: switch(c) {
159: case 'B':
160: compatMake = TRUE;
161: break;
162: case 'P':
163: usePipes = FALSE;
164: Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
165: break;
166: case 'S':
167: keepgoing = FALSE;
168: Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
169: break;
170: case 'e':
171: checkEnvFirst = TRUE;
172: Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
173: break;
174: case 'i':
175: ignoreErrors = TRUE;
176: Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
177: break;
178: case 'k':
179: keepgoing = TRUE;
180: Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
181: break;
182: case 'n':
183: noExecute = TRUE;
184: Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
185: break;
186: case 'q':
187: queryFlag = TRUE;
188: /* Kind of nonsensical, wot? */
189: Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
190: break;
191: case 'r':
192: noBuiltins = TRUE;
193: Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
194: break;
195: case 's':
196: beSilent = TRUE;
197: Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
198: break;
199: case 't':
200: touchFlag = TRUE;
201: Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
202: break;
203: default:
204: case '?':
205: usage();
206: }
207: }
208:
1.1 deraadt 209: /*-
210: * MainParseArgs --
211: * Parse a given argument vector. Called from main() and from
212: * Main_ParseArgLine() when the .MAKEFLAGS target is used.
213: *
214: * XXX: Deal with command line overriding .MAKEFLAGS in makefile
215: *
216: * Results:
217: * None
218: *
219: * Side Effects:
220: * Various global and local flags will be set depending on the flags
221: * given
222: */
223: static void
224: MainParseArgs(argc, argv)
225: int argc;
226: char **argv;
227: {
228: extern int optind;
229: extern char *optarg;
230: int c;
1.2 deraadt 231: int forceJobs = 0;
1.1 deraadt 232:
233: optind = 1; /* since we're called more than once */
1.2 deraadt 234: #ifdef REMOTE
1.9 millert 235: # define OPTFLAGS "BD:I:L:PSV:d:ef:ij:km:nqrst"
1.1 deraadt 236: #else
1.9 millert 237: # define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"
1.1 deraadt 238: #endif
1.39 espie 239: # define OPTLETTERS "BPSiknqrst"
1.10 millert 240: rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
1.1 deraadt 241: switch(c) {
242: case 'D':
243: Var_Set(optarg, "1", VAR_GLOBAL);
244: Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
245: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
246: break;
247: case 'I':
248: Parse_AddIncludeDir(optarg);
249: Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
250: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
251: break;
1.9 millert 252: case 'V':
253: printVars = TRUE;
1.33 espie 254: Lst_AtEnd(&variables, optarg);
1.9 millert 255: Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
256: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
257: break;
1.2 deraadt 258: #ifdef REMOTE
1.15 espie 259: case 'L': {
260: char *endptr;
261:
262: maxLocal = strtol(optarg, &endptr, 0);
263: if (endptr == optarg) {
264: fprintf(stderr,
265: "make: illegal argument to -L option -- %s -- not a number\n",
266: optarg);
267: usage();
268: }
1.1 deraadt 269: Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
270: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
271: break;
1.15 espie 272: }
1.2 deraadt 273: #endif
1.1 deraadt 274: case 'd': {
275: char *modules = optarg;
276:
277: for (; *modules; ++modules)
278: switch (*modules) {
279: case 'A':
280: debug = ~0;
281: break;
282: case 'a':
283: debug |= DEBUG_ARCH;
284: break;
285: case 'c':
286: debug |= DEBUG_COND;
287: break;
288: case 'd':
289: debug |= DEBUG_DIR;
290: break;
291: case 'f':
292: debug |= DEBUG_FOR;
293: break;
294: case 'g':
295: if (modules[1] == '1') {
296: debug |= DEBUG_GRAPH1;
297: ++modules;
298: }
299: else if (modules[1] == '2') {
300: debug |= DEBUG_GRAPH2;
301: ++modules;
302: }
303: break;
304: case 'j':
305: debug |= DEBUG_JOB;
306: break;
307: case 'm':
308: debug |= DEBUG_MAKE;
309: break;
310: case 's':
311: debug |= DEBUG_SUFF;
312: break;
313: case 't':
314: debug |= DEBUG_TARG;
315: break;
316: case 'v':
317: debug |= DEBUG_VAR;
318: break;
319: default:
320: (void)fprintf(stderr,
321: "make: illegal argument to d option -- %c\n",
322: *modules);
323: usage();
324: }
325: Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
326: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
327: break;
328: }
329: case 'f':
1.33 espie 330: Lst_AtEnd(&makefiles, optarg);
1.1 deraadt 331: break;
1.15 espie 332: case 'j': {
333: char *endptr;
334:
1.2 deraadt 335: forceJobs = TRUE;
1.15 espie 336: maxJobs = strtol(optarg, &endptr, 0);
337: if (endptr == optarg) {
338: fprintf(stderr,
339: "make: illegal argument to -j option -- %s -- not a number\n",
340: optarg);
341: usage();
342: }
1.1 deraadt 343: maxJobs = atoi(optarg);
1.2 deraadt 344: #ifndef REMOTE
345: maxLocal = maxJobs;
346: #endif
1.1 deraadt 347: Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
348: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
349: break;
1.15 espie 350: }
1.5 niklas 351: case 'm':
1.42 espie 352: Dir_AddDir(&sysIncPath, optarg, NULL);
1.5 niklas 353: Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
354: Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
355: break;
1.1 deraadt 356: default:
1.39 espie 357: posixParseOptLetter(c);
1.1 deraadt 358: }
359: }
360:
1.2 deraadt 361: /*
362: * Be compatible if user did not specify -j and did not explicitly
363: * turned compatibility on
364: */
365: if (!compatMake && !forceJobs)
366: compatMake = TRUE;
367:
1.1 deraadt 368: oldVars = TRUE;
369:
370: /*
371: * See if the rest of the arguments are variable assignments and
372: * perform them if so. Else take them to be targets and stuff them
373: * on the end of the "create" list.
374: */
375: for (argv += optind, argc -= optind; *argv; ++argv, --argc)
1.3 deraadt 376: if (Parse_IsVar(*argv)) {
1.9 millert 377: char *var = estrdup(*argv);
1.3 deraadt 378:
379: Parse_DoVar(var, VAR_CMD);
380: free(var);
381: } else {
1.1 deraadt 382: if (!**argv)
383: Punt("illegal (null) argument.");
384: if (**argv == '-') {
385: if ((*argv)[1])
386: optind = 0; /* -flag... */
387: else
388: optind = 1; /* - */
389: goto rearg;
390: }
1.33 espie 391: Lst_AtEnd(&create, estrdup(*argv));
1.1 deraadt 392: }
393: }
394:
395: /*-
396: * Main_ParseArgLine --
397: * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
398: * is encountered and by main() when reading the .MAKEFLAGS envariable.
399: * Takes a line of arguments and breaks it into its
400: * component words and passes those words and the number of them to the
401: * MainParseArgs function.
402: * The line should have all its leading whitespace removed.
403: *
404: * Results:
405: * None
406: *
407: * Side Effects:
408: * Only those that come from the various arguments.
409: */
410: void
411: Main_ParseArgLine(line)
412: char *line; /* Line to fracture */
413: {
414: char **argv; /* Manufactured argument vector */
415: int argc; /* Number of arguments in argv */
1.14 espie 416: char *args; /* Space used by the args */
1.19 espie 417: char *buf;
1.39 espie 418: char *argv0;
419: char *s;
1.1 deraadt 420:
421: if (line == NULL)
422: return;
423: for (; *line == ' '; ++line)
424: continue;
425: if (!*line)
426: return;
427:
1.39 espie 428: /* POSIX rule: MAKEFLAGS can hold a set of option letters without
429: * any blanks or dashes. */
430: for (s = line;; s++) {
431: if (*s == '\0') {
432: while (line != s)
433: posixParseOptLetter(*line++);
434: return;
435: }
436: if (strchr(OPTLETTERS, *s) == NULL)
437: break;
438: }
439: argv0 = Var_Value(".MAKE", VAR_GLOBAL);
1.14 espie 440: buf = emalloc(strlen(line) + strlen(argv0) + 2);
441: (void)sprintf(buf, "%s %s", argv0, line);
442:
443: argv = brk_string(buf, &argc, TRUE, &args);
444: free(buf);
1.1 deraadt 445: MainParseArgs(argc, argv);
1.14 espie 446:
447: free(args);
448: free(argv);
1.1 deraadt 449: }
450:
1.9 millert 451: char *
452: chdir_verify_path(path, obpath)
453: char *path;
454: char *obpath;
455: {
456: struct stat sb;
457:
458: if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
459: if (chdir(path)) {
460: (void)fprintf(stderr, "make warning: %s: %s.\n",
461: path, strerror(errno));
462: return 0;
463: }
464: else {
465: if (path[0] != '/') {
466: (void) snprintf(obpath, MAXPATHLEN, "%s/%s",
467: curdir, path);
468: return obpath;
469: }
470: else
471: return path;
472: }
473: }
474:
475: return 0;
476: }
477:
1.42 espie 478: /* Add a :-separated path to a Lst of directories. */
479: static void
480: add_dirpath(l, n)
481: Lst l;
482: const char *n;
483: {
484: const char *start;
485: const char *cp;
486:
487: for (start = n;;) {
488: for (cp = start; *cp != '\0' && *cp != ':';)
489: cp++;
490: Dir_AddDir(l, start, cp);
491: if (*cp == '\0')
492: break;
493: else
494: start= cp+1;
495: }
496: }
497:
1.9 millert 498:
1.1 deraadt 499: /*-
500: * main --
501: * The main function, for obvious reasons. Initializes variables
502: * and a few modules, then parses the arguments give it in the
503: * environment and on the command line. Reads the system makefile
504: * followed by either Makefile, makefile or the file given by the
505: * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
506: * flags it has received by then uses either the Make or the Compat
507: * module to create the initial list of targets.
508: *
509: * Results:
510: * If -q was given, exits -1 if anything was out-of-date. Else it exits
511: * 0.
512: *
513: * Side Effects:
514: * The program exits when done. Targets are created. etc. etc. etc.
515: */
516: int
517: main(argc, argv)
518: int argc;
519: char **argv;
520: {
1.34 espie 521: LIST targs; /* target nodes to create -- passed to Make_Init */
1.1 deraadt 522: Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
523: struct stat sb, sa;
1.19 espie 524: char *p, *path, *pathp, *pwd;
1.1 deraadt 525: char mdpath[MAXPATHLEN + 1];
526: char obpath[MAXPATHLEN + 1];
527: char cdpath[MAXPATHLEN + 1];
528: char *machine = getenv("MACHINE");
1.12 millert 529: char *machine_arch = getenv("MACHINE_ARCH");
1.5 niklas 530: /* avoid faults on read-only strings */
531: static char syspath[] = _PATH_DEFSYSPATH;
1.1 deraadt 532:
1.45 ! espie 533: set_out_of_date(now);
1.2 deraadt 534: #ifdef RLIMIT_NOFILE
535: /*
536: * get rid of resource limit on file descriptors
537: */
538: {
539: struct rlimit rl;
540: if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
541: rl.rlim_cur != rl.rlim_max) {
542: rl.rlim_cur = rl.rlim_max;
543: (void) setrlimit(RLIMIT_NOFILE, &rl);
544: }
545: }
546: #endif
1.1 deraadt 547: /*
548: * Find where we are and take care of PWD for the automounter...
549: * All this code is so that we know where we are when we start up
550: * on a different machine with pmake.
551: */
552: curdir = cdpath;
553: if (getcwd(curdir, MAXPATHLEN) == NULL) {
554: (void)fprintf(stderr, "make: %s.\n", strerror(errno));
555: exit(2);
556: }
557:
558: if (stat(curdir, &sa) == -1) {
559: (void)fprintf(stderr, "make: %s: %s.\n",
560: curdir, strerror(errno));
561: exit(2);
562: }
563:
564: if ((pwd = getenv("PWD")) != NULL) {
565: if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
1.9 millert 566: sa.st_dev == sb.st_dev)
1.1 deraadt 567: (void) strcpy(curdir, pwd);
568: }
569:
570: /*
571: * Get the name of this type of MACHINE from utsname
572: * so we can share an executable for similar machines.
573: * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
574: *
1.12 millert 575: * Note that both MACHINE and MACHINE_ARCH are decided at
576: * run-time.
1.1 deraadt 577: */
1.12 millert 578: if (!machine) {
579: #ifndef MAKE_BOOTSTRAP
1.9 millert 580: struct utsname utsname;
581:
1.2 deraadt 582: if (uname(&utsname) == -1) {
1.1 deraadt 583: perror("make: uname");
584: exit(2);
585: }
586: machine = utsname.machine;
1.6 niklas 587: #else
588: machine = MACHINE;
589: #endif
1.1 deraadt 590: }
591:
1.12 millert 592: if (!machine_arch) {
593: #ifndef MACHINE_ARCH
594: machine_arch = "unknown"; /* XXX: no uname -p yet */
595: #else
596: machine_arch = MACHINE_ARCH;
597: #endif
598: }
599:
1.1 deraadt 600: /*
1.9 millert 601: * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
602: * exists, change into it and build there. (If a .${MACHINE} suffix
603: * exists, use that directory instead).
604: * Otherwise check MAKEOBJDIRPREFIX`cwd` (or by default,
605: * _PATH_OBJDIRPREFIX`cwd`) and build there if it exists.
606: * If all fails, use the current directory to build.
607: *
608: * Once things are initted,
609: * have to add the original directory to the search path,
1.1 deraadt 610: * and modify the paths for the Makefiles apropriately. The
611: * current directory is also placed as a variable for make scripts.
612: */
1.9 millert 613: if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
614: if (!(path = getenv("MAKEOBJDIR"))) {
615: path = _PATH_OBJDIR;
616: pathp = _PATH_OBJDIRPREFIX;
617: (void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
618: path, machine);
619: if (!(objdir = chdir_verify_path(mdpath, obpath)))
620: if (!(objdir=chdir_verify_path(path, obpath))) {
621: (void) snprintf(mdpath, MAXPATHLEN,
622: "%s%s", pathp, curdir);
623: if (!(objdir=chdir_verify_path(mdpath,
624: obpath)))
625: objdir = curdir;
626: }
627: }
628: else if (!(objdir = chdir_verify_path(path, obpath)))
1.1 deraadt 629: objdir = curdir;
630: }
631: else {
1.9 millert 632: (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
633: if (!(objdir = chdir_verify_path(mdpath, obpath)))
1.1 deraadt 634: objdir = curdir;
635: }
636:
1.44 espie 637: esetenv("PWD", objdir);
1.30 espie 638: unsetenv("CDPATH");
1.1 deraadt 639:
1.33 espie 640: Lst_Init(&create);
641: Lst_Init(&makefiles);
1.9 millert 642: printVars = FALSE;
1.33 espie 643: Lst_Init(&variables);
1.1 deraadt 644: beSilent = FALSE; /* Print commands as executed */
645: ignoreErrors = FALSE; /* Pay attention to non-zero returns */
646: noExecute = FALSE; /* Execute all commands */
647: keepgoing = FALSE; /* Stop on error */
648: allPrecious = FALSE; /* Remove targets when interrupted */
649: queryFlag = FALSE; /* This is not just a check-run */
650: noBuiltins = FALSE; /* Read the built-in rules */
651: touchFlag = FALSE; /* Actually update targets */
652: usePipes = TRUE; /* Catch child output in pipes */
653: debug = 0; /* No debug verbosity, please. */
654: jobsRunning = FALSE;
655:
1.2 deraadt 656: maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
657: #ifdef REMOTE
1.1 deraadt 658: maxJobs = DEFMAXJOBS; /* Set default max concurrency */
659: #else
1.2 deraadt 660: maxJobs = maxLocal;
1.1 deraadt 661: #endif
1.2 deraadt 662: compatMake = FALSE; /* No compat mode */
1.9 millert 663:
1.1 deraadt 664:
665: /*
666: * Initialize the parsing, directory and variable modules to prepare
667: * for the reading of inclusion paths and variable settings on the
668: * command line
669: */
670: Dir_Init(); /* Initialize directory structures so -I flags
671: * can be processed correctly */
672: Parse_Init(); /* Need to initialize the paths of #include
673: * directories */
674: Var_Init(); /* As well as the lists of variables for
675: * parsing arguments */
676: if (objdir != curdir)
1.42 espie 677: Dir_AddDir(&dirSearchPath, curdir, NULL);
1.1 deraadt 678: Var_Set(".CURDIR", curdir, VAR_GLOBAL);
679: Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
680:
681: /*
682: * Initialize various variables.
683: * MAKE also gets this name, for compatibility
684: * .MAKEFLAGS gets set to the empty string just in case.
685: * MFLAGS also gets initialized empty, for compatibility.
686: */
687: Var_Set("MAKE", argv[0], VAR_GLOBAL);
1.14 espie 688: Var_Set(".MAKE", argv[0], VAR_GLOBAL);
1.1 deraadt 689: Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
690: Var_Set("MFLAGS", "", VAR_GLOBAL);
691: Var_Set("MACHINE", machine, VAR_GLOBAL);
1.12 millert 692: Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
1.1 deraadt 693:
694: /*
695: * First snag any flags out of the MAKE environment variable.
696: * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
697: * in a different format).
698: */
699: #ifdef POSIX
700: Main_ParseArgLine(getenv("MAKEFLAGS"));
701: #else
702: Main_ParseArgLine(getenv("MAKE"));
703: #endif
1.9 millert 704:
1.1 deraadt 705: MainParseArgs(argc, argv);
1.30 espie 706:
1.40 espie 707: #ifdef POSIX
1.39 espie 708: Var_AddCmdline(MAKEFLAGS);
709: #endif
1.1 deraadt 710:
711: /*
712: * Initialize archive, target and suffix modules in preparation for
713: * parsing the makefile(s)
714: */
715: Arch_Init();
716: Targ_Init();
717: Suff_Init();
718:
1.25 espie 719: DEFAULT = NULL;
1.45 ! espie 720: grab(now);
1.1 deraadt 721:
722: /*
723: * Set up the .TARGETS variable to contain the list of targets to be
724: * created. If none specified, make the variable empty -- the parser
725: * will fill the thing in with the default or .MAIN target.
726: */
1.33 espie 727: if (!Lst_IsEmpty(&create)) {
1.1 deraadt 728: LstNode ln;
729:
1.35 espie 730: for (ln = Lst_First(&create); ln != NULL; ln = Lst_Adv(ln)) {
1.1 deraadt 731: char *name = (char *)Lst_Datum(ln);
732:
733: Var_Append(".TARGETS", name, VAR_GLOBAL);
734: }
735: } else
736: Var_Set(".TARGETS", "", VAR_GLOBAL);
737:
1.5 niklas 738:
739: /*
740: * If no user-supplied system path was given (through the -m option)
741: * add the directories from the DEFSYSPATH (more than one may be given
742: * as dir1:...:dirn) to the system include path.
743: */
1.42 espie 744: if (Lst_IsEmpty(&sysIncPath))
745: add_dirpath(&sysIncPath, syspath);
1.5 niklas 746:
1.1 deraadt 747: /*
1.5 niklas 748: * Read in the built-in rules first, followed by the specified
749: * makefile, if it was (makefile != (char *) NULL), or the default
750: * Makefile and makefile, in that order, if it wasn't.
1.1 deraadt 751: */
1.5 niklas 752: if (!noBuiltins) {
753: LstNode ln;
1.33 espie 754: LIST sysMkPath; /* Path of sys.mk */
1.5 niklas 755:
1.33 espie 756: Lst_Init(&sysMkPath);
757: Dir_Expand(_PATH_DEFSYSMK, &sysIncPath, &sysMkPath);
758: if (Lst_IsEmpty(&sysMkPath))
1.5 niklas 759: Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
1.33 espie 760: ln = Lst_Find(&sysMkPath, ReadMakefile, NULL);
1.25 espie 761: if (ln != NULL)
1.5 niklas 762: Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1.34 espie 763: #ifdef CLEANUP
764: Lst_Destroy(&sysMkPath, (SimpleProc)free);
765: #endif
1.5 niklas 766: }
1.1 deraadt 767:
1.33 espie 768: if (!Lst_IsEmpty(&makefiles)) {
1.1 deraadt 769: LstNode ln;
770:
1.33 espie 771: ln = Lst_Find(&makefiles, ReadMakefile, NULL);
1.25 espie 772: if (ln != NULL)
1.1 deraadt 773: Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1.13 niklas 774: } else if (!ReadMakefile("BSDmakefile", NULL))
775: if (!ReadMakefile("makefile", NULL))
776: (void)ReadMakefile("Makefile", NULL);
1.1 deraadt 777:
1.9 millert 778: (void)ReadMakefile(".depend", NULL);
1.1 deraadt 779:
1.19 espie 780: Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
1.1 deraadt 781:
782: /* Install all the flags into the MAKE envariable. */
1.19 espie 783: if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) != NULL) && *p)
1.1 deraadt 784: #ifdef POSIX
1.44 espie 785: esetenv("MAKEFLAGS", p);
1.1 deraadt 786: #else
1.44 espie 787: esetenv("MAKE", p);
1.1 deraadt 788: #endif
789:
790: /*
791: * For compatibility, look at the directories in the VPATH variable
792: * and add them to the search path, if the variable is defined. The
793: * variable's value is in the same format as the PATH envariable, i.e.
794: * <directory>:<directory>:<directory>...
795: */
796: if (Var_Exists("VPATH", VAR_CMD)) {
1.42 espie 797: char *vpath;
1.1 deraadt 798: /*
799: * GCC stores string constants in read-only memory, but
800: * Var_Subst will want to write this thing, so store it
801: * in an array
802: */
803: static char VPATH[] = "${VPATH}";
804:
1.36 espie 805: vpath = Var_Subst(VPATH, (SymTable *)VAR_CMD, FALSE);
1.42 espie 806: add_dirpath(&dirSearchPath, vpath);
807: (void)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: }