Annotation of src/usr.bin/make/main.c, Revision 1.80
1.46 espie 1: /* $OpenPackages$ */
1.80 ! espie 2: /* $OpenBSD: main.c,v 1.79 2007/09/16 12:30:35 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.
1.62 millert 22: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: */
38:
1.49 espie 39: #include <sys/param.h>
1.1 deraadt 40: #include <sys/types.h>
41: #include <sys/stat.h>
1.12 millert 42: #ifndef MAKE_BOOTSTRAP
1.1 deraadt 43: #include <sys/utsname.h>
1.9 millert 44: #endif
1.1 deraadt 45: #include <errno.h>
46: #include <stdio.h>
1.49 espie 47: #include <stdlib.h>
1.48 espie 48: #include <string.h>
49: #include <unistd.h>
50: #include "config.h"
51: #include "defines.h"
52: #include "var.h"
53: #include "parse.h"
54: #include "parsevar.h"
1.1 deraadt 55: #include "dir.h"
1.78 espie 56: #include "direxpand.h"
1.48 espie 57: #include "error.h"
58: #include "pathnames.h"
59: #include "init.h"
1.1 deraadt 60: #include "job.h"
1.48 espie 61: #include "compat.h"
62: #include "targ.h"
63: #include "suff.h"
64: #include "str.h"
65: #include "main.h"
66: #include "lst.h"
67: #include "memory.h"
68: #include "make.h"
1.1 deraadt 69:
1.53 espie 70: #ifndef PATH_MAX
71: # ifdef MAXPATHLEN
72: # define PATH_MAX (MAXPATHLEN+1)
73: # else
74: # define PATH_MAX 1024
75: # endif
76: #endif
77:
1.46 espie 78: #ifndef DEFMAXLOCAL
79: #define DEFMAXLOCAL DEFMAXJOBS
1.4 niklas 80: #endif /* DEFMAXLOCAL */
1.1 deraadt 81:
1.46 espie 82: #define MAKEFLAGS ".MAKEFLAGS"
1.1 deraadt 83:
1.48 espie 84: static LIST to_create; /* Targets to be made */
85: Lst create = &to_create;
1.1 deraadt 86: GNode *DEFAULT; /* .DEFAULT node */
1.48 espie 87: bool allPrecious; /* .PRECIOUS given on line by itself */
1.1 deraadt 88:
1.48 espie 89: static bool noBuiltins; /* -r flag */
1.33 espie 90: static LIST makefiles; /* ordered list of makefiles to read */
1.48 espie 91: static LIST varstoprint; /* list of variables to print */
1.2 deraadt 92: int maxJobs; /* -j argument */
1.1 deraadt 93: static int maxLocal; /* -L argument */
1.48 espie 94: bool compatMake; /* -B argument */
1.63 espie 95: int debug; /* -d flag */
1.48 espie 96: bool noExecute; /* -n flag */
97: bool keepgoing; /* -k flag */
98: bool queryFlag; /* -q flag */
99: bool touchFlag; /* -t flag */
100: bool usePipes; /* !-P flag */
101: bool ignoreErrors; /* -i flag */
102: bool beSilent; /* -s flag */
1.1 deraadt 103:
1.75 espie 104: struct dirs {
105: char *current;
106: char *object;
107: };
108:
109: static void MainParseArgs(int, char **);
110: static void add_dirpath(Lst, const char *);
111: static void usage(void);
112: static void posixParseOptLetter(int);
113: static void record_option(int, const char *);
114:
115: static char *figure_out_MACHINE(void);
116: static char *figure_out_MACHINE_ARCH(void);
117: static void no_fd_limits(void);
118:
119: static char *chdir_verify_path(const char *, struct dirs *);
120: static char *concat_verify(const char *, const char *, char, struct dirs *);
121: static char *figure_out_CURDIR(void);
122: static void setup_CURDIR_OBJDIR(struct dirs *, const char *);
123:
124: static void setup_VPATH(void);
125:
126: static void read_all_make_rules(bool, Lst, struct dirs *);
127: static void read_makefile_list(Lst, struct dirs *);
128: static int ReadMakefile(void *, void *);
1.1 deraadt 129:
1.46 espie 130:
1.64 espie 131: static void record_option(int c, const char *arg)
1.48 espie 132: {
133: char opt[3];
134:
1.75 espie 135: opt[0] = '-';
136: opt[1] = c;
137: opt[2] = '\0';
1.76 espie 138: Var_Append(MAKEFLAGS, opt);
1.75 espie 139: if (arg != NULL)
1.76 espie 140: Var_Append(MAKEFLAGS, arg);
1.48 espie 141: }
142:
1.39 espie 143: static void
1.64 espie 144: posixParseOptLetter(int c)
1.39 espie 145: {
146: switch(c) {
147: case 'B':
1.48 espie 148: compatMake = true;
149: return; /* XXX don't pass to submakes. */
1.39 espie 150: case 'P':
1.48 espie 151: usePipes = false;
1.39 espie 152: break;
153: case 'S':
1.48 espie 154: keepgoing = false;
1.39 espie 155: break;
156: case 'e':
1.70 espie 157: Var_setCheckEnvFirst(true);
1.39 espie 158: break;
159: case 'i':
1.48 espie 160: ignoreErrors = true;
1.39 espie 161: break;
162: case 'k':
1.48 espie 163: keepgoing = true;
1.39 espie 164: break;
165: case 'n':
1.48 espie 166: noExecute = true;
1.39 espie 167: break;
168: case 'q':
1.48 espie 169: queryFlag = true;
1.39 espie 170: /* Kind of nonsensical, wot? */
171: break;
172: case 'r':
1.48 espie 173: noBuiltins = true;
1.39 espie 174: break;
175: case 's':
1.48 espie 176: beSilent = true;
1.39 espie 177: break;
178: case 't':
1.48 espie 179: touchFlag = true;
1.39 espie 180: break;
181: default:
182: case '?':
183: usage();
184: }
1.48 espie 185: record_option(c, NULL);
1.39 espie 186: }
187:
1.1 deraadt 188: /*-
189: * MainParseArgs --
190: * Parse a given argument vector. Called from main() and from
191: * Main_ParseArgLine() when the .MAKEFLAGS target is used.
192: *
193: * XXX: Deal with command line overriding .MAKEFLAGS in makefile
194: *
195: * Side Effects:
196: * Various global and local flags will be set depending on the flags
197: * given
198: */
199: static void
1.64 espie 200: MainParseArgs(int argc, char **argv)
1.1 deraadt 201: {
1.61 millert 202: int c, optend;
1.2 deraadt 203: int forceJobs = 0;
1.1 deraadt 204:
1.58 millert 205: #define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"
206: #define OPTLETTERS "BPSiknqrst"
207:
1.1 deraadt 208: optind = 1; /* since we're called more than once */
1.58 millert 209: optreset = 1;
1.61 millert 210: optend = 0;
1.58 millert 211: while (optind < argc) {
1.61 millert 212: if (!optend && argv[optind][0] == '-') {
213: if (argv[optind][1] == '\0')
214: optind++; /* ignore "-" */
215: else if (argv[optind][1] == '-' &&
216: argv[optind][2] == '\0') {
217: optind++; /* ignore "--" */
218: optend++; /* "--" denotes end of flags */
219: }
220: }
221: c = optend ? -1 : getopt(argc, argv, OPTFLAGS);
222: switch (c) {
1.1 deraadt 223: case 'D':
1.76 espie 224: Var_Set(optarg, "1");
1.48 espie 225: record_option(c, optarg);
1.1 deraadt 226: break;
227: case 'I':
228: Parse_AddIncludeDir(optarg);
1.48 espie 229: record_option(c, optarg);
1.1 deraadt 230: break;
1.9 millert 231: case 'V':
1.48 espie 232: Lst_AtEnd(&varstoprint, optarg);
233: record_option(c, optarg);
1.9 millert 234: break;
1.1 deraadt 235: case 'd': {
236: char *modules = optarg;
237:
238: for (; *modules; ++modules)
239: switch (*modules) {
240: case 'A':
241: debug = ~0;
242: break;
243: case 'a':
244: debug |= DEBUG_ARCH;
245: break;
246: case 'c':
247: debug |= DEBUG_COND;
248: break;
249: case 'd':
250: debug |= DEBUG_DIR;
251: break;
252: case 'f':
253: debug |= DEBUG_FOR;
254: break;
255: case 'g':
256: if (modules[1] == '1') {
257: debug |= DEBUG_GRAPH1;
258: ++modules;
259: }
260: else if (modules[1] == '2') {
261: debug |= DEBUG_GRAPH2;
262: ++modules;
263: }
264: break;
265: case 'j':
266: debug |= DEBUG_JOB;
267: break;
1.46 espie 268: case 'l':
269: debug |= DEBUG_LOUD;
270: break;
1.1 deraadt 271: case 'm':
272: debug |= DEBUG_MAKE;
273: break;
274: case 's':
275: debug |= DEBUG_SUFF;
276: break;
277: case 't':
278: debug |= DEBUG_TARG;
279: break;
280: case 'v':
281: debug |= DEBUG_VAR;
282: break;
283: default:
284: (void)fprintf(stderr,
1.67 jmc 285: "make: illegal argument to -d option -- %c\n",
1.1 deraadt 286: *modules);
287: usage();
288: }
1.48 espie 289: record_option(c, optarg);
1.1 deraadt 290: break;
291: }
292: case 'f':
1.33 espie 293: Lst_AtEnd(&makefiles, optarg);
1.1 deraadt 294: break;
1.15 espie 295: case 'j': {
296: char *endptr;
297:
1.48 espie 298: forceJobs = true;
1.15 espie 299: maxJobs = strtol(optarg, &endptr, 0);
300: if (endptr == optarg) {
301: fprintf(stderr,
302: "make: illegal argument to -j option -- %s -- not a number\n",
303: optarg);
304: usage();
305: }
1.2 deraadt 306: maxLocal = maxJobs;
1.48 espie 307: record_option(c, optarg);
1.1 deraadt 308: break;
1.15 espie 309: }
1.5 niklas 310: case 'm':
1.48 espie 311: Dir_AddDir(sysIncPath, optarg);
312: record_option(c, optarg);
1.5 niklas 313: break;
1.58 millert 314: case -1:
315: /* Check for variable assignments and targets. */
1.59 millert 316: if (argv[optind] != NULL &&
1.70 espie 317: !Parse_CmdlineVar(argv[optind])) {
1.58 millert 318: if (!*argv[optind])
319: Punt("illegal (null) argument.");
1.61 millert 320: Lst_AtEnd(create, estrdup(argv[optind]));
1.58 millert 321: }
322: optind++; /* skip over non-option */
323: break;
1.1 deraadt 324: default:
1.39 espie 325: posixParseOptLetter(c);
1.1 deraadt 326: }
327: }
328:
1.2 deraadt 329: /*
330: * Be compatible if user did not specify -j and did not explicitly
1.48 espie 331: * turn compatibility on
1.2 deraadt 332: */
333: if (!compatMake && !forceJobs)
1.48 espie 334: compatMake = true;
1.1 deraadt 335: }
336:
337: /*-
338: * Main_ParseArgLine --
1.46 espie 339: * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
1.1 deraadt 340: * is encountered and by main() when reading the .MAKEFLAGS envariable.
341: * Takes a line of arguments and breaks it into its
1.46 espie 342: * component words and passes those words and the number of them to the
1.1 deraadt 343: * MainParseArgs function.
344: * The line should have all its leading whitespace removed.
345: *
346: * Side Effects:
347: * Only those that come from the various arguments.
348: */
349: void
1.64 espie 350: Main_ParseArgLine(const char *line) /* Line to fracture */
1.1 deraadt 351: {
352: char **argv; /* Manufactured argument vector */
353: int argc; /* Number of arguments in argv */
1.14 espie 354: char *args; /* Space used by the args */
1.19 espie 355: char *buf;
1.39 espie 356: char *argv0;
1.48 espie 357: const char *s;
1.60 espie 358: size_t len;
1.1 deraadt 359:
1.46 espie 360:
1.1 deraadt 361: if (line == NULL)
362: return;
363: for (; *line == ' '; ++line)
364: continue;
365: if (!*line)
366: return;
367:
1.39 espie 368: /* POSIX rule: MAKEFLAGS can hold a set of option letters without
369: * any blanks or dashes. */
370: for (s = line;; s++) {
371: if (*s == '\0') {
1.46 espie 372: while (line != s)
1.39 espie 373: posixParseOptLetter(*line++);
374: return;
1.46 espie 375: }
1.39 espie 376: if (strchr(OPTLETTERS, *s) == NULL)
377: break;
378: }
1.46 espie 379: argv0 = Var_Value(".MAKE");
1.60 espie 380: len = strlen(line) + strlen(argv0) + 2;
381: buf = emalloc(len);
382: (void)snprintf(buf, len, "%s %s", argv0, line);
1.14 espie 383:
1.46 espie 384: argv = brk_string(buf, &argc, &args);
1.14 espie 385: free(buf);
1.1 deraadt 386: MainParseArgs(argc, argv);
1.14 espie 387:
388: free(args);
389: free(argv);
1.1 deraadt 390: }
391:
1.75 espie 392: /* Add a :-separated path to a Lst of directories. */
393: static void
394: add_dirpath(Lst l, const char *n)
1.9 millert 395: {
1.75 espie 396: const char *start;
397: const char *cp;
1.9 millert 398:
1.75 espie 399: for (start = n;;) {
400: for (cp = start; *cp != '\0' && *cp != ':';)
401: cp++;
402: Dir_AddDiri(l, start, cp);
403: if (*cp == '\0')
404: break;
405: else
406: start= cp+1;
1.9 millert 407: }
408: }
409:
1.75 espie 410: /*
1.80 ! espie 411: * Get the name of this type of MACHINE from utsname so we can share an
1.75 espie 412: * executable for similar machines. (i.e. m68k: amiga hp300, mac68k, sun3, ...)
413: *
414: * Note that both MACHINE and MACHINE_ARCH are decided at
415: * run-time.
416: */
417: static char *
418: figure_out_MACHINE()
1.42 espie 419: {
1.75 espie 420: char *r = getenv("MACHINE");
421: if (r == NULL) {
422: #ifndef MAKE_BOOTSTRAP
423: static struct utsname utsname;
1.42 espie 424:
1.75 espie 425: if (uname(&utsname) == -1) {
426: perror("make: uname");
427: exit(2);
428: }
429: r = utsname.machine;
430: #else
431: r = MACHINE;
432: #endif
433: }
434: return r;
1.42 espie 435: }
436:
1.75 espie 437: static char *
438: figure_out_MACHINE_ARCH()
1.1 deraadt 439: {
1.75 espie 440: char *r = getenv("MACHINE_ARCH");
441: if (r == NULL) {
442: #ifndef MACHINE_ARCH
443: r = "unknown"; /* XXX: no uname -p yet */
444: #else
445: r = MACHINE_ARCH;
446: #endif
447: }
448: return r;
449: }
1.46 espie 450:
1.75 espie 451: /* get rid of resource limit on file descriptors */
452: static void
453: no_fd_limits()
454: {
1.2 deraadt 455: #ifdef RLIMIT_NOFILE
1.75 espie 456: struct rlimit rl;
457: if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
458: rl.rlim_cur != rl.rlim_max) {
459: rl.rlim_cur = rl.rlim_max;
460: (void)setrlimit(RLIMIT_NOFILE, &rl);
1.2 deraadt 461: }
462: #endif
1.75 espie 463: }
464:
465: static char *
466: figure_out_CURDIR()
467: {
468: char *dir, *cwd;
469: struct stat sa, sb;
470:
471: /* curdir is cwd... */
472: cwd = dogetcwd();
473: if (cwd == NULL) {
1.1 deraadt 474: (void)fprintf(stderr, "make: %s.\n", strerror(errno));
475: exit(2);
476: }
477:
1.75 espie 478: if (stat(cwd, &sa) == -1) {
479: (void)fprintf(stderr, "make: %s: %s.\n", cwd, strerror(errno));
480: exit(2);
1.1 deraadt 481: }
482:
1.80 ! espie 483: /* ...but we can use the alias $PWD if we can prove it is the same
1.75 espie 484: * directory */
485: if ((dir = getenv("PWD")) != NULL) {
486: if (stat(dir, &sb) == 0 && sa.st_ino == sb.st_ino &&
487: sa.st_dev == sb.st_dev)
488: free(cwd);
489: return estrdup(dir);
1.1 deraadt 490: }
491:
1.75 espie 492: return cwd;
493: }
494:
495: static char *
496: chdir_verify_path(const char *path, struct dirs *d)
497: {
498: struct stat sb;
1.9 millert 499:
1.75 espie 500: if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
501: if (chdir(path)) {
502: (void)fprintf(stderr, "make warning: %s: %s.\n",
503: path, strerror(errno));
504: return NULL;
505: } else {
506: if (path[0] != '/')
507: return Str_concat(d->current, path, '/');
508: else
509: return estrdup(path);
510: }
1.1 deraadt 511: }
512:
1.75 espie 513: return NULL;
514: }
515:
516: static char *
517: concat_verify(const char *p1, const char *p2, char c, struct dirs *d)
518: {
519: char *tmp = Str_concat(p1, p2, c);
520: char *result = chdir_verify_path(tmp, d);
521: free(tmp);
522: return result;
523: }
524:
525: static void
526: setup_CURDIR_OBJDIR(struct dirs *d, const char *machine)
527: {
528: char *path, *prefix;
1.12 millert 529:
1.75 espie 530: d->current = figure_out_CURDIR();
531: d->object = NULL;
1.1 deraadt 532: /*
1.9 millert 533: * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
534: * exists, change into it and build there. (If a .${MACHINE} suffix
535: * exists, use that directory instead).
536: * Otherwise check MAKEOBJDIRPREFIX`cwd` (or by default,
537: * _PATH_OBJDIRPREFIX`cwd`) and build there if it exists.
538: * If all fails, use the current directory to build.
539: *
540: * Once things are initted,
541: * have to add the original directory to the search path,
1.66 jolan 542: * and modify the paths for the Makefiles appropriately. The
1.1 deraadt 543: * current directory is also placed as a variable for make scripts.
544: */
1.75 espie 545: if ((prefix = getenv("MAKEOBJDIRPREFIX")) != NULL) {
546: d->object = concat_verify(prefix, d->current, 0, d);
547: } else if ((path = getenv("MAKEOBJDIR")) != NULL) {
548: d->object = chdir_verify_path(path, d);
549: } else {
550: path = _PATH_OBJDIR;
551: prefix = _PATH_OBJDIRPREFIX;
552: d->object = concat_verify(path, machine, '.', d);
553: if (!d->object)
554: d->object=chdir_verify_path(path, d);
555: if (!d->object)
556: d->object = concat_verify(prefix, d->current, 0, d);
557: }
558: if (d->object == NULL)
559: d->object = d->current;
560: }
561:
562: #ifdef CLEANUP
563: static void
564: free_CURDIR_OBJDIR(struct dirs *d)
565: {
566: if (d->object != d->current)
567: free(d->object);
568: free(d->current);
569: }
570: #endif
571:
572:
573: /*
574: * if the VPATH variable is defined, add its contents to the search path.
575: * Uses the same format as the PATH env variable, i.e.,
576: * <directory>:<directory>:<directory>...
577: */
578: static void
579: setup_VPATH()
580: {
581: if (Var_Value("VPATH") != NULL) {
582: char *vpath;
583:
584: vpath = Var_Subst("${VPATH}", NULL, false);
1.79 espie 585: add_dirpath(defaultPath, vpath);
1.75 espie 586: (void)free(vpath);
1.1 deraadt 587: }
1.75 espie 588: }
589:
590: static void
591: read_makefile_list(Lst mk, struct dirs *d)
592: {
593: LstNode ln;
594: ln = Lst_Find(mk, ReadMakefile, d);
595: if (ln != NULL)
596: Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
597: }
598:
599: static void
600: read_all_make_rules(bool noBuiltins, Lst makefiles, struct dirs *d)
601: {
602: /*
603: * Read in the built-in rules first, followed by the specified
604: * makefile(s), or the default BSDmakefile, Makefile or
605: * makefile, in that order.
606: */
607: if (!noBuiltins) {
608: LIST sysMkPath; /* Path of sys.mk */
609:
610: Lst_Init(&sysMkPath);
611: Dir_Expand(_PATH_DEFSYSMK, sysIncPath, &sysMkPath);
612: if (Lst_IsEmpty(&sysMkPath))
613: Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
614:
615: read_makefile_list(&sysMkPath, d);
616: #ifdef CLEANUP
617: Lst_Destroy(&sysMkPath, (SimpleProc)free);
618: #endif
1.1 deraadt 619: }
620:
1.75 espie 621: if (!Lst_IsEmpty(makefiles)) {
622: read_makefile_list(makefiles, d);
623: } else if (!ReadMakefile("BSDmakefile", d))
624: if (!ReadMakefile("makefile", d))
625: (void)ReadMakefile("Makefile", d);
626:
627: /* Always read a .depend file, if it exists. */
628: (void)ReadMakefile(".depend", d);
629: }
630:
631:
632: int main(int, char **);
633: /*-
634: * main --
635: * The main function, for obvious reasons. Initializes variables
636: * and a few modules, then parses the arguments give it in the
637: * environment and on the command line. Reads the system makefile
638: * followed by either Makefile, makefile or the file given by the
639: * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
640: * flags it has received by then uses either the Make or the Compat
641: * module to create the initial list of targets.
642: *
643: * Results:
644: * If -q was given, exits -1 if anything was out-of-date. Else it exits
645: * 0.
646: *
647: * Side Effects:
648: * The program exits when done. Targets are created. etc. etc. etc.
649: */
650: int
651: main(int argc, char **argv)
652: {
653: static LIST targs; /* target nodes to create */
654: bool outOfDate = true; /* false if all targets up to date */
655: char *machine = figure_out_MACHINE();
656: char *machine_arch = figure_out_MACHINE_ARCH();
657: const char *syspath = _PATH_DEFSYSPATH;
658: char *p;
659: static struct dirs d;
660:
661: no_fd_limits();
662: setup_CURDIR_OBJDIR(&d, machine);
663:
664: esetenv("PWD", d.object);
1.30 espie 665: unsetenv("CDPATH");
1.1 deraadt 666:
1.56 espie 667: Static_Lst_Init(create);
668: Static_Lst_Init(&makefiles);
669: Static_Lst_Init(&varstoprint);
670: Static_Lst_Init(&targs);
1.52 espie 671:
1.48 espie 672: beSilent = false; /* Print commands as executed */
673: ignoreErrors = false; /* Pay attention to non-zero returns */
674: noExecute = false; /* Execute all commands */
675: keepgoing = false; /* Stop on error */
676: allPrecious = false; /* Remove targets when interrupted */
677: queryFlag = false; /* This is not just a check-run */
678: noBuiltins = false; /* Read the built-in rules */
679: touchFlag = false; /* Actually update targets */
680: usePipes = true; /* Catch child output in pipes */
1.1 deraadt 681: debug = 0; /* No debug verbosity, please. */
682:
1.46 espie 683: maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
1.2 deraadt 684: maxJobs = maxLocal;
1.48 espie 685: compatMake = false; /* No compat mode */
1.9 millert 686:
1.1 deraadt 687:
688: /*
1.48 espie 689: * Initialize all external modules.
1.1 deraadt 690: */
1.48 espie 691: Init();
692:
1.75 espie 693: if (d.object != d.current)
1.79 espie 694: Dir_AddDir(defaultPath, d.current);
1.76 espie 695: Var_Set(".CURDIR", d.current);
696: Var_Set(".OBJDIR", d.object);
1.1 deraadt 697:
698: /*
699: * Initialize various variables.
700: * MAKE also gets this name, for compatibility
701: * .MAKEFLAGS gets set to the empty string just in case.
702: * MFLAGS also gets initialized empty, for compatibility.
703: */
1.76 espie 704: Var_Set("MAKE", argv[0]);
705: Var_Set(".MAKE", argv[0]);
706: Var_Set(MAKEFLAGS, "");
707: Var_Set("MFLAGS", "");
708: Var_Set("MACHINE", machine);
709: Var_Set("MACHINE_ARCH", machine_arch);
1.1 deraadt 710:
711: /*
1.46 espie 712: * First snag any flags out of the MAKEFLAGS environment variable.
1.1 deraadt 713: */
714: Main_ParseArgLine(getenv("MAKEFLAGS"));
1.9 millert 715:
1.1 deraadt 716: MainParseArgs(argc, argv);
1.30 espie 717:
1.46 espie 718: /* And set up everything for sub-makes */
1.39 espie 719: Var_AddCmdline(MAKEFLAGS);
1.46 espie 720:
1.1 deraadt 721:
1.25 espie 722: DEFAULT = NULL;
1.1 deraadt 723:
724: /*
725: * Set up the .TARGETS variable to contain the list of targets to be
726: * created. If none specified, make the variable empty -- the parser
727: * will fill the thing in with the default or .MAIN target.
728: */
1.48 espie 729: if (!Lst_IsEmpty(create)) {
1.1 deraadt 730: LstNode ln;
731:
1.48 espie 732: for (ln = Lst_First(create); ln != NULL; ln = Lst_Adv(ln)) {
1.1 deraadt 733: char *name = (char *)Lst_Datum(ln);
734:
1.76 espie 735: Var_Append(".TARGETS", name);
1.1 deraadt 736: }
737: } else
1.76 espie 738: Var_Set(".TARGETS", "");
1.1 deraadt 739:
1.5 niklas 740:
741: /*
742: * If no user-supplied system path was given (through the -m option)
743: * add the directories from the DEFSYSPATH (more than one may be given
744: * as dir1:...:dirn) to the system include path.
745: */
1.48 espie 746: if (Lst_IsEmpty(sysIncPath))
747: add_dirpath(sysIncPath, syspath);
1.5 niklas 748:
1.75 espie 749: read_all_make_rules(noBuiltins, &makefiles, &d);
1.1 deraadt 750:
1.76 espie 751: Var_Append("MFLAGS", Var_Value(MAKEFLAGS));
1.1 deraadt 752:
1.46 espie 753: /* Install all the flags into the MAKEFLAGS env variable. */
754: if (((p = Var_Value(MAKEFLAGS)) != NULL) && *p)
1.44 espie 755: esetenv("MAKEFLAGS", p);
1.1 deraadt 756:
1.75 espie 757: setup_VPATH();
1.1 deraadt 758:
1.46 espie 759: /* Now that all search paths have been read for suffixes et al, it's
760: * time to add the default search path to their lists... */
1.1 deraadt 761: Suff_DoPaths();
762:
1.46 espie 763: /* Print the initial graph, if the user requested it. */
1.1 deraadt 764: if (DEBUG(GRAPH1))
765: Targ_PrintGraph(1);
766:
1.46 espie 767: /* Print the values of any variables requested by the user. */
1.48 espie 768: if (!Lst_IsEmpty(&varstoprint)) {
1.75 espie 769: LstNode ln;
1.9 millert 770:
1.80 ! espie 771: for (ln = Lst_First(&varstoprint); ln != NULL;
1.75 espie 772: ln = Lst_Adv(ln)) {
773: char *value = Var_Value((char *)Lst_Datum(ln));
1.9 millert 774:
1.75 espie 775: printf("%s\n", value ? value : "");
776: }
1.48 espie 777: } else {
1.80 ! espie 778: /* Have now read the entire graph and need to make a list
! 779: * of targets to create. If none was given on the command
! 780: * line, we consult the parsing module to find the main
1.75 espie 781: * target(s) to create. */
782: if (Lst_IsEmpty(create))
783: Parse_MainName(&targs);
784: else
785: Targ_FindList(&targs, create);
786:
787: if (compatMake)
1.80 ! espie 788: /* Compat_Init will take care of creating all the
1.75 espie 789: * targets as well as initializing the module. */
790: Compat_Run(&targs);
791: else {
1.80 ! espie 792: /* Initialize job module before traversing the graph,
! 793: * now that any .BEGIN and .END targets have been
! 794: * read. This is done only if the -q flag wasn't given
! 795: * (to prevent the .BEGIN from being executed should
1.75 espie 796: * it exist). */
797: if (!queryFlag) {
798: if (maxLocal == -1)
799: maxLocal = maxJobs;
800: Job_Init(maxJobs, maxLocal);
801: }
802:
803: /* Traverse the graph, checking on all the targets. */
804: outOfDate = Make_Run(&targs);
1.1 deraadt 805: }
1.9 millert 806: }
807:
1.52 espie 808: #ifdef CLEANUP
1.34 espie 809: Lst_Destroy(&targs, NOFREE);
1.48 espie 810: Lst_Destroy(&varstoprint, NOFREE);
1.33 espie 811: Lst_Destroy(&makefiles, NOFREE);
1.48 espie 812: Lst_Destroy(create, (SimpleProc)free);
1.52 espie 813: #endif
1.1 deraadt 814:
815: /* print the graph now it's been processed if the user requested it */
816: if (DEBUG(GRAPH2))
817: Targ_PrintGraph(2);
818:
1.53 espie 819: #ifdef CLEANUP
1.75 espie 820: free_CURDIR_OBJDIR(&d);
1.68 espie 821: End();
1.53 espie 822: #endif
1.1 deraadt 823: if (queryFlag && outOfDate)
1.46 espie 824: return 1;
1.1 deraadt 825: else
1.46 espie 826: return 0;
1.1 deraadt 827: }
828:
829: /*-
830: * ReadMakefile --
831: * Open and parse the given makefile.
832: *
833: * Results:
1.48 espie 834: * true if ok. false if couldn't open file.
1.1 deraadt 835: *
836: * Side Effects:
837: * lots
838: */
1.48 espie 839: static bool
1.75 espie 840: ReadMakefile(void *p, void *q)
1.1 deraadt 841: {
1.64 espie 842: char *fname = (char *)p; /* makefile to read */
1.75 espie 843: struct dirs *d = (struct dirs *)q;
1.1 deraadt 844: FILE *stream;
1.53 espie 845: char *name;
1.1 deraadt 846:
847: if (!strcmp(fname, "-")) {
1.76 espie 848: Var_Set("MAKEFILE", "");
1.37 espie 849: Parse_File(estrdup("(stdin)"), stdin);
1.1 deraadt 850: } else {
851: if ((stream = fopen(fname, "r")) != NULL)
852: goto found;
853: /* if we've chdir'd, rebuild the path name */
1.75 espie 854: if (d->current != d->object && *fname != '/') {
1.53 espie 855: char *path;
856:
1.75 espie 857: path = Str_concat(d->current, fname, '/');
1.53 espie 858: if ((stream = fopen(path, "r")) == NULL)
1.75 espie 859: free(path);
1.53 espie 860: else {
1.75 espie 861: fname = path;
862: goto found;
1.1 deraadt 863: }
864: }
865: /* look in -I and system include directories. */
1.48 espie 866: name = Dir_FindFile(fname, parseIncPath);
1.1 deraadt 867: if (!name)
1.48 espie 868: name = Dir_FindFile(fname, sysIncPath);
1.1 deraadt 869: if (!name || !(stream = fopen(name, "r")))
1.48 espie 870: return false;
1.1 deraadt 871: fname = name;
872: /*
873: * set the MAKEFILE variable desired by System V fans -- the
874: * placement of the setting here means it gets set to the last
875: * makefile specified, as it is set by SysV make.
876: */
1.76 espie 877: found: Var_Set("MAKEFILE", fname);
1.1 deraadt 878: Parse_File(fname, stream);
879: }
1.48 espie 880: return true;
1.1 deraadt 881: }
882:
1.46 espie 883:
1.1 deraadt 884: /*
885: * usage --
886: * exit with usage message
887: */
888: static void
889: usage()
890: {
891: (void)fprintf(stderr,
1.65 jmc 892: "usage: make [-BeiknPqrSst] [-D variable] [-d flags] [-f makefile]\n\
1.46 espie 893: [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
1.65 jmc 894: [NAME=value] [target ...]\n");
1.1 deraadt 895: exit(2);
896: }
897:
898: