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