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