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