Annotation of src/usr.bin/make/main.c, Revision 1.172
1.172 ! dholland 1: /* $NetBSD: main.c,v 1.171 2009/08/26 23:17:11 sjg Exp $ */
1.19 christos 2:
1.1 cgd 3: /*
1.31 christos 4: * Copyright (c) 1988, 1989, 1990, 1993
5: * The Regents of the University of California. All rights reserved.
1.91 agc 6: *
7: * This code is derived from software contributed to Berkeley by
8: * Adam de Boor.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. Neither the name of the University nor the names of its contributors
19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: */
34:
35: /*
1.1 cgd 36: * Copyright (c) 1989 by Berkeley Softworks
37: * All rights reserved.
38: *
39: * This code is derived from software contributed to Berkeley by
40: * Adam de Boor.
41: *
42: * Redistribution and use in source and binary forms, with or without
43: * modification, are permitted provided that the following conditions
44: * are met:
45: * 1. Redistributions of source code must retain the above copyright
46: * notice, this list of conditions and the following disclaimer.
47: * 2. Redistributions in binary form must reproduce the above copyright
48: * notice, this list of conditions and the following disclaimer in the
49: * documentation and/or other materials provided with the distribution.
50: * 3. All advertising materials mentioning features or use of this software
51: * must display the following acknowledgement:
52: * This product includes software developed by the University of
53: * California, Berkeley and its contributors.
54: * 4. Neither the name of the University nor the names of its contributors
55: * may be used to endorse or promote products derived from this software
56: * without specific prior written permission.
57: *
58: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68: * SUCH DAMAGE.
69: */
70:
1.102 ross 71: #ifndef MAKE_NATIVE
1.172 ! dholland 72: static char rcsid[] = "$NetBSD: main.c,v 1.171 2009/08/26 23:17:11 sjg Exp $";
1.38 lukem 73: #else
1.37 christos 74: #include <sys/cdefs.h>
1.1 cgd 75: #ifndef lint
1.150 lukem 76: __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
77: The Regents of the University of California. All rights reserved.");
1.1 cgd 78: #endif /* not lint */
79:
80: #ifndef lint
1.19 christos 81: #if 0
1.31 christos 82: static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
1.19 christos 83: #else
1.172 ! dholland 84: __RCSID("$NetBSD: main.c,v 1.171 2009/08/26 23:17:11 sjg Exp $");
1.19 christos 85: #endif
1.1 cgd 86: #endif /* not lint */
1.38 lukem 87: #endif
1.1 cgd 88:
89: /*-
90: * main.c --
91: * The main file for this entire program. Exit routines etc
92: * reside here.
93: *
94: * Utility functions defined in this file:
95: * Main_ParseArgLine Takes a line of arguments, breaks them and
96: * treats them as if they were given when first
97: * invoked. Used by the parse module to implement
98: * the .MFLAGS target.
99: *
100: * Error Print a tagged error message. The global
101: * MAKE variable must have been defined. This
102: * takes a format string and two optional
103: * arguments for it.
104: *
105: * Fatal Print an error message and exit. Also takes
106: * a format string and two arguments.
107: *
108: * Punt Aborts all jobs and exits with a message. Also
109: * takes a format string and two arguments.
110: *
111: * Finish Finish things up by printing the number of
1.72 wiz 112: * errors which occurred, as passed to it, and
1.1 cgd 113: * exiting.
114: */
115:
1.13 cgd 116: #include <sys/types.h>
117: #include <sys/time.h>
1.1 cgd 118: #include <sys/param.h>
1.13 cgd 119: #include <sys/resource.h>
1.21 christos 120: #include <sys/signal.h>
1.1 cgd 121: #include <sys/stat.h>
1.102 ross 122: #ifdef MAKE_NATIVE
1.17 gwr 123: #include <sys/utsname.h>
1.31 christos 124: #endif
1.29 christos 125: #include <sys/wait.h>
1.85 wiz 126:
1.1 cgd 127: #include <errno.h>
128: #include <fcntl.h>
1.85 wiz 129: #include <stdarg.h>
1.1 cgd 130: #include <stdio.h>
1.32 christos 131: #include <stdlib.h>
1.42 kleink 132: #include <time.h>
1.85 wiz 133:
1.1 cgd 134: #include "make.h"
1.13 cgd 135: #include "hash.h"
136: #include "dir.h"
137: #include "job.h"
1.1 cgd 138: #include "pathnames.h"
1.58 sommerfe 139: #include "trace.h"
1.1 cgd 140:
1.66 christos 141: #ifdef USE_IOVEC
142: #include <sys/uio.h>
143: #endif
144:
1.1 cgd 145: #ifndef DEFMAXLOCAL
146: #define DEFMAXLOCAL DEFMAXJOBS
1.24 christos 147: #endif /* DEFMAXLOCAL */
1.1 cgd 148:
149: Lst create; /* Targets to be made */
150: time_t now; /* Time at start of make */
151: GNode *DEFAULT; /* .DEFAULT node */
152: Boolean allPrecious; /* .PRECIOUS given on line by itself */
153:
154: static Boolean noBuiltins; /* -r flag */
155: static Lst makefiles; /* ordered list of makefiles to read */
1.31 christos 156: static Boolean printVars; /* print value of one or more vars */
157: static Lst variables; /* list of variables to print */
1.21 christos 158: int maxJobs; /* -j argument */
1.132 dsl 159: static int maxJobTokens; /* -j argument */
1.13 cgd 160: Boolean compatMake; /* -B argument */
1.113 christos 161: int debug; /* -d argument */
1.1 cgd 162: Boolean noExecute; /* -n flag */
1.61 sommerfe 163: Boolean noRecursiveExecute; /* -N flag */
1.1 cgd 164: Boolean keepgoing; /* -k flag */
165: Boolean queryFlag; /* -q flag */
166: Boolean touchFlag; /* -t flag */
167: Boolean ignoreErrors; /* -i flag */
168: Boolean beSilent; /* -s flag */
169: Boolean oldVars; /* variable substitution style */
170: Boolean checkEnvFirst; /* -e flag */
1.63 christos 171: Boolean parseWarnFatal; /* -W flag */
1.58 sommerfe 172: Boolean jobServer; /* -J flag */
1.132 dsl 173: static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
1.87 thorpej 174: Boolean varNoExportEnv; /* -X flag */
1.145 dsl 175: Boolean doing_depend; /* Set while reading .depend */
1.1 cgd 176: static Boolean jobsRunning; /* TRUE if the jobs might be running */
1.58 sommerfe 177: static const char * tracefile;
1.149 christos 178: static char * Check_Cwd_av(int, char **, int);
179: static void MainParseArgs(int, char **);
1.165 dsl 180: static int ReadMakefile(const void *, const void *);
1.85 wiz 181: static void usage(void);
1.1 cgd 182:
1.74 tv 183: static char curdir[MAXPATHLEN + 1]; /* startup directory */
184: static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
1.63 christos 185: char *progname; /* the program name */
1.1 cgd 186:
1.58 sommerfe 187: Boolean forceJobs = FALSE;
188:
1.63 christos 189: extern Lst parseIncPath;
190:
1.133 dsl 191: static void
192: parse_debug_options(const char *argvalue)
193: {
194: const char *modules;
1.136 dsl 195: const char *mode;
196: char *fname;
1.149 christos 197: int len;
1.133 dsl 198:
199: for (modules = argvalue; *modules; ++modules) {
200: switch (*modules) {
201: case 'A':
202: debug = ~0;
203: break;
204: case 'a':
205: debug |= DEBUG_ARCH;
206: break;
1.155 christos 207: case 'C':
208: debug |= DEBUG_CWD;
209: break;
1.133 dsl 210: case 'c':
211: debug |= DEBUG_COND;
212: break;
213: case 'd':
214: debug |= DEBUG_DIR;
215: break;
216: case 'e':
217: debug |= DEBUG_ERROR;
218: break;
219: case 'f':
220: debug |= DEBUG_FOR;
221: break;
222: case 'g':
223: if (modules[1] == '1') {
224: debug |= DEBUG_GRAPH1;
225: ++modules;
226: }
227: else if (modules[1] == '2') {
228: debug |= DEBUG_GRAPH2;
229: ++modules;
230: }
231: else if (modules[1] == '3') {
232: debug |= DEBUG_GRAPH3;
233: ++modules;
234: }
235: break;
236: case 'j':
237: debug |= DEBUG_JOB;
238: break;
1.146 sjg 239: case 'l':
240: debug |= DEBUG_LOUD;
241: break;
1.133 dsl 242: case 'm':
243: debug |= DEBUG_MAKE;
244: break;
245: case 'n':
246: debug |= DEBUG_SCRIPT;
247: break;
248: case 'p':
249: debug |= DEBUG_PARSE;
250: break;
251: case 's':
252: debug |= DEBUG_SUFF;
253: break;
254: case 't':
255: debug |= DEBUG_TARG;
256: break;
257: case 'v':
258: debug |= DEBUG_VAR;
259: break;
260: case 'x':
261: debug |= DEBUG_SHELL;
262: break;
263: case 'F':
264: if (debug_file != stdout && debug_file != stderr)
265: fclose(debug_file);
266: if (*++modules == '+')
1.136 dsl 267: mode = "a";
1.153 apb 268: else
1.136 dsl 269: mode = "w";
1.153 apb 270: if (strcmp(modules, "stdout") == 0) {
1.152 apb 271: debug_file = stdout;
1.153 apb 272: goto debug_setbuf;
1.152 apb 273: }
1.153 apb 274: if (strcmp(modules, "stderr") == 0) {
1.152 apb 275: debug_file = stderr;
1.153 apb 276: goto debug_setbuf;
1.152 apb 277: }
1.136 dsl 278: len = strlen(modules);
279: fname = malloc(len + 20);
280: memcpy(fname, modules, len + 1);
281: /* Let the filename be modified by the pid */
282: if (strcmp(fname + len - 3, ".%d") == 0)
1.149 christos 283: snprintf(fname + len - 2, 20, "%d", getpid());
1.136 dsl 284: debug_file = fopen(fname, mode);
1.133 dsl 285: if (!debug_file) {
1.139 dsl 286: fprintf(stderr, "Cannot open debug file %s\n",
1.136 dsl 287: fname);
1.133 dsl 288: usage();
289: }
1.136 dsl 290: free(fname);
1.153 apb 291: goto debug_setbuf;
1.133 dsl 292: default:
293: (void)fprintf(stderr,
294: "%s: illegal argument to d option -- %c\n",
295: progname, *modules);
296: usage();
297: }
298: }
1.153 apb 299: debug_setbuf:
300: /*
301: * Make the debug_file unbuffered, and make
302: * stdout line buffered (unless debugfile == stdout).
303: */
304: setvbuf(debug_file, NULL, _IONBF, 0);
305: if (debug_file != stdout) {
306: setvbuf(stdout, NULL, _IOLBF, 0);
307: }
1.133 dsl 308: }
309:
1.1 cgd 310: /*-
311: * MainParseArgs --
312: * Parse a given argument vector. Called from main() and from
313: * Main_ParseArgLine() when the .MAKEFLAGS target is used.
314: *
315: * XXX: Deal with command line overriding .MAKEFLAGS in makefile
316: *
317: * Results:
318: * None
319: *
320: * Side Effects:
321: * Various global and local flags will be set depending on the flags
322: * given
323: */
324: static void
1.149 christos 325: MainParseArgs(int argc, char **argv)
1.1 cgd 326: {
1.47 hubertf 327: char *p;
1.122 christos 328: int c = '?';
1.98 ross 329: int arginc;
1.133 dsl 330: char *argvalue;
1.98 ross 331: const char *getopt_def;
332: char *optscan;
1.101 ross 333: Boolean inOption, dashDash = FALSE;
1.97 chuck 334: char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
1.1 cgd 335:
1.171 sjg 336: #define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst"
1.98 ross 337: /* Can't actually use getopt(3) because rescanning is not portable */
338:
339: getopt_def = OPTFLAGS;
340: rearg:
341: inOption = FALSE;
1.108 lukem 342: optscan = NULL;
1.98 ross 343: while(argc > 1) {
344: char *getopt_spec;
345: if(!inOption)
346: optscan = argv[1];
347: c = *optscan++;
348: arginc = 0;
349: if(inOption) {
350: if(c == '\0') {
351: ++argv;
352: --argc;
353: inOption = FALSE;
354: continue;
355: }
356: } else {
1.101 ross 357: if (c != '-' || dashDash)
1.98 ross 358: break;
359: inOption = TRUE;
360: c = *optscan++;
361: }
362: /* '-' found at some earlier point */
363: getopt_spec = strchr(getopt_def, c);
364: if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') {
365: /* -<something> found, and <something> should have an arg */
366: inOption = FALSE;
367: arginc = 1;
368: argvalue = optscan;
369: if(*argvalue == '\0') {
1.122 christos 370: if (argc < 3)
371: goto noarg;
1.98 ross 372: argvalue = argv[2];
373: arginc = 2;
374: }
1.108 lukem 375: } else {
376: argvalue = NULL;
1.98 ross 377: }
1.1 cgd 378: switch(c) {
1.98 ross 379: case '\0':
380: arginc = 1;
381: inOption = FALSE;
382: break;
1.92 sjg 383: case 'B':
384: compatMake = TRUE;
385: Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
386: break;
1.171 sjg 387: case 'C':
388: if (chdir(argvalue) == -1) {
389: (void)fprintf(stderr,
390: "%s: chdir %s: %s\n",
391: progname, argvalue,
392: strerror(errno));
393: exit(1);
394: }
395: break;
1.1 cgd 396: case 'D':
1.156 dsl 397: if (argvalue == NULL || argvalue[0] == 0) goto noarg;
1.122 christos 398: Var_Set(argvalue, "1", VAR_GLOBAL, 0);
1.1 cgd 399: Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
1.122 christos 400: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
1.1 cgd 401: break;
402: case 'I':
1.122 christos 403: if (argvalue == NULL) goto noarg;
404: Parse_AddIncludeDir(argvalue);
1.1 cgd 405: Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
1.122 christos 406: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
1.1 cgd 407: break;
1.58 sommerfe 408: case 'J':
1.122 christos 409: if (argvalue == NULL) goto noarg;
1.132 dsl 410: if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
1.63 christos 411: (void)fprintf(stderr,
1.132 dsl 412: "%s: internal error -- J option malformed (%s)\n",
1.122 christos 413: progname, argvalue);
1.58 sommerfe 414: usage();
415: }
1.132 dsl 416: if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
417: (fcntl(jp_1, F_GETFD, 0) < 0)) {
1.61 sommerfe 418: #if 0
1.58 sommerfe 419: (void)fprintf(stderr,
1.121 dsl 420: "%s: ###### warning -- J descriptors were closed!\n",
1.63 christos 421: progname);
1.118 dsl 422: exit(2);
1.61 sommerfe 423: #endif
1.132 dsl 424: jp_0 = -1;
425: jp_1 = -1;
1.61 sommerfe 426: compatMake = TRUE;
1.58 sommerfe 427: } else {
428: Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
1.122 christos 429: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
1.58 sommerfe 430: jobServer = TRUE;
431: }
432: break;
1.61 sommerfe 433: case 'N':
434: noExecute = TRUE;
435: noRecursiveExecute = TRUE;
436: Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
437: break;
1.1 cgd 438: case 'S':
439: keepgoing = FALSE;
440: Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
441: break;
1.58 sommerfe 442: case 'T':
1.122 christos 443: if (argvalue == NULL) goto noarg;
1.151 joerg 444: tracefile = bmake_strdup(argvalue);
1.58 sommerfe 445: Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
1.122 christos 446: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
1.58 sommerfe 447: break;
1.92 sjg 448: case 'V':
1.122 christos 449: if (argvalue == NULL) goto noarg;
1.92 sjg 450: printVars = TRUE;
1.134 dsl 451: (void)Lst_AtEnd(variables, argvalue);
1.92 sjg 452: Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
1.122 christos 453: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
1.92 sjg 454: break;
1.63 christos 455: case 'W':
456: parseWarnFatal = TRUE;
1.87 thorpej 457: break;
458: case 'X':
459: varNoExportEnv = TRUE;
460: Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
1.63 christos 461: break;
1.133 dsl 462: case 'd':
1.122 christos 463: if (argvalue == NULL) goto noarg;
1.133 dsl 464: /* If '-d-opts' don't pass to children */
465: if (argvalue[0] == '-')
466: argvalue++;
467: else {
468: Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
469: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
470: }
471: parse_debug_options(argvalue);
1.1 cgd 472: break;
473: case 'e':
474: checkEnvFirst = TRUE;
475: Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
476: break;
477: case 'f':
1.122 christos 478: if (argvalue == NULL) goto noarg;
1.134 dsl 479: (void)Lst_AtEnd(makefiles, argvalue);
1.1 cgd 480: break;
481: case 'i':
482: ignoreErrors = TRUE;
483: Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
484: break;
485: case 'j':
1.122 christos 486: if (argvalue == NULL) goto noarg;
1.22 christos 487: forceJobs = TRUE;
1.122 christos 488: maxJobs = strtol(argvalue, &p, 0);
1.47 hubertf 489: if (*p != '\0' || maxJobs < 1) {
1.112 christos 490: (void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
1.63 christos 491: progname);
1.46 hubertf 492: exit(1);
493: }
1.9 jtc 494: Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
1.122 christos 495: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
1.123 dsl 496: maxJobTokens = maxJobs;
1.1 cgd 497: break;
498: case 'k':
499: keepgoing = TRUE;
500: Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
501: break;
1.25 christos 502: case 'm':
1.122 christos 503: if (argvalue == NULL) goto noarg;
1.97 chuck 504: /* look for magic parent directory search string */
1.122 christos 505: if (strncmp(".../", argvalue, 4) == 0) {
506: if (!Dir_FindHereOrAbove(curdir, argvalue+4,
1.97 chuck 507: found_path, sizeof(found_path)))
508: break; /* nothing doing */
1.112 christos 509: (void)Dir_AddDir(sysIncPath, found_path);
1.97 chuck 510:
511: } else {
1.122 christos 512: (void)Dir_AddDir(sysIncPath, argvalue);
1.97 chuck 513: }
1.25 christos 514: Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
1.122 christos 515: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
1.25 christos 516: break;
1.1 cgd 517: case 'n':
518: noExecute = TRUE;
519: Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
520: break;
521: case 'q':
522: queryFlag = TRUE;
523: /* Kind of nonsensical, wot? */
524: Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
525: break;
526: case 'r':
527: noBuiltins = TRUE;
528: Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
529: break;
530: case 's':
531: beSilent = TRUE;
532: Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
533: break;
534: case 't':
535: touchFlag = TRUE;
536: Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
537: break;
1.101 ross 538: case '-':
539: dashDash = TRUE;
540: break;
1.1 cgd 541: default:
542: case '?':
543: usage();
544: }
1.98 ross 545: argv += arginc;
546: argc -= arginc;
1.1 cgd 547: }
548:
549: oldVars = TRUE;
550:
551: /*
552: * See if the rest of the arguments are variable assignments and
553: * perform them if so. Else take them to be targets and stuff them
554: * on the end of the "create" list.
555: */
1.98 ross 556: for (; argc > 1; ++argv, --argc)
557: if (Parse_IsVar(argv[1])) {
558: Parse_DoVar(argv[1], VAR_CMD);
1.67 sjg 559: } else {
1.98 ross 560: if (!*argv[1])
1.1 cgd 561: Punt("illegal (null) argument.");
1.101 ross 562: if (*argv[1] == '-' && !dashDash)
1.1 cgd 563: goto rearg;
1.151 joerg 564: (void)Lst_AtEnd(create, bmake_strdup(argv[1]));
1.1 cgd 565: }
1.122 christos 566:
567: return;
568: noarg:
569: (void)fprintf(stderr, "%s: option requires an argument -- %c\n",
570: progname, c);
571: usage();
1.1 cgd 572: }
573:
574: /*-
575: * Main_ParseArgLine --
576: * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
577: * is encountered and by main() when reading the .MAKEFLAGS envariable.
578: * Takes a line of arguments and breaks it into its
579: * component words and passes those words and the number of them to the
580: * MainParseArgs function.
581: * The line should have all its leading whitespace removed.
582: *
1.85 wiz 583: * Input:
584: * line Line to fracture
585: *
1.1 cgd 586: * Results:
587: * None
588: *
589: * Side Effects:
590: * Only those that come from the various arguments.
591: */
592: void
1.161 dsl 593: Main_ParseArgLine(const char *line)
1.1 cgd 594: {
595: char **argv; /* Manufactured argument vector */
1.149 christos 596: int argc; /* Number of arguments in argv */
1.40 christos 597: char *args; /* Space used by the args */
598: char *buf, *p1;
599: char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
1.48 christos 600: size_t len;
1.1 cgd 601:
602: if (line == NULL)
603: return;
1.13 cgd 604: for (; *line == ' '; ++line)
605: continue;
1.1 cgd 606: if (!*line)
607: return;
608:
1.151 joerg 609: buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2);
1.48 christos 610: (void)snprintf(buf, len, "%s %s", argv0, line);
1.40 christos 611: if (p1)
612: free(p1);
613:
1.41 christos 614: argv = brk_string(buf, &argc, TRUE, &args);
1.159 christos 615: if (argv == NULL) {
616: Error("Unterminated quoted string [%s]", buf);
617: free(buf);
618: return;
619: }
1.45 itohy 620: free(buf);
1.1 cgd 621: MainParseArgs(argc, argv);
1.40 christos 622:
623: free(args);
624: free(argv);
1.1 cgd 625: }
626:
1.74 tv 627: Boolean
1.85 wiz 628: Main_SetObjdir(const char *path)
1.31 christos 629: {
630: struct stat sb;
1.74 tv 631: char *p = NULL;
632: char buf[MAXPATHLEN + 1];
1.76 tv 633: Boolean rc = FALSE;
1.31 christos 634:
1.74 tv 635: /* expand variable substitutions */
1.51 sjg 636: if (strchr(path, '$') != 0) {
1.74 tv 637: snprintf(buf, MAXPATHLEN, "%s", path);
638: path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0);
1.51 sjg 639: }
1.74 tv 640:
641: if (path[0] != '/') {
642: snprintf(buf, MAXPATHLEN, "%s/%s", curdir, path);
643: path = buf;
644: }
645:
646: /* look for the directory and try to chdir there */
1.31 christos 647: if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
648: if (chdir(path)) {
649: (void)fprintf(stderr, "make warning: %s: %s.\n",
650: path, strerror(errno));
1.74 tv 651: } else {
652: strncpy(objdir, path, MAXPATHLEN);
653: Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0);
654: setenv("PWD", objdir, 1);
1.79 tv 655: Dir_InitDot();
1.74 tv 656: rc = TRUE;
1.31 christos 657: }
658: }
659:
1.74 tv 660: if (p)
661: free(p);
662: return rc;
1.31 christos 663: }
664:
1.124 sjg 665: /*-
666: * ReadAllMakefiles --
667: * wrapper around ReadMakefile() to read all.
668: *
669: * Results:
670: * TRUE if ok, FALSE on error
671: */
672: static int
1.165 dsl 673: ReadAllMakefiles(const void *p, const void *q)
1.124 sjg 674: {
675: return (ReadMakefile(p, q) == 0);
676: }
1.31 christos 677:
1.167 christos 678: #ifdef SIGINFO
679: /*ARGSUSED*/
680: static void
681: siginfo(int signo)
682: {
683: char dir[MAXPATHLEN];
684: char str[2 * MAXPATHLEN];
685: int len;
686: if (getcwd(dir, sizeof(dir)) == NULL)
687: return;
1.168 christos 688: len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir);
1.167 christos 689: if (len > 0)
690: (void)write(STDERR_FILENO, str, (size_t)len);
691: }
692: #endif
693:
1.1 cgd 694: /*-
695: * main --
696: * The main function, for obvious reasons. Initializes variables
697: * and a few modules, then parses the arguments give it in the
698: * environment and on the command line. Reads the system makefile
699: * followed by either Makefile, makefile or the file given by the
700: * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
701: * flags it has received by then uses either the Make or the Compat
702: * module to create the initial list of targets.
703: *
704: * Results:
705: * If -q was given, exits -1 if anything was out-of-date. Else it exits
706: * 0.
707: *
708: * Side Effects:
709: * The program exits when done. Targets are created. etc. etc. etc.
710: */
1.13 cgd 711: int
1.85 wiz 712: main(int argc, char **argv)
1.1 cgd 713: {
714: Lst targs; /* target nodes to create -- passed to Make_Init */
1.137 dsl 715: Boolean outOfDate = FALSE; /* FALSE if all targets up to date */
1.77 tv 716: struct stat sb, sa;
717: char *p1, *path, *pwd;
1.74 tv 718: char mdpath[MAXPATHLEN];
1.18 christos 719: char *machine = getenv("MACHINE");
1.89 christos 720: const char *machine_arch = getenv("MACHINE_ARCH");
1.55 sjg 721: char *syspath = getenv("MAKESYSPATH");
1.25 christos 722: Lst sysMkPath; /* Path of sys.mk */
723: char *cp = NULL, *start;
724: /* avoid faults on read-only strings */
1.55 sjg 725: static char defsyspath[] = _PATH_DEFSYSPATH;
1.97 chuck 726: char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
1.107 sjg 727: struct timeval rightnow; /* to initialize random seed */
1.119 tsutsui 728: #ifdef MAKE_NATIVE
729: struct utsname utsname;
730: #endif
1.107 sjg 731:
1.154 apb 732: /* default to writing debug to stderr */
733: debug_file = stderr;
1.133 dsl 734:
1.167 christos 735: #ifdef SIGINFO
736: (void)signal(SIGINFO, siginfo);
737: #endif
1.107 sjg 738: /*
1.158 dholland 739: * Set the seed to produce a different random sequence
1.107 sjg 740: * on each program execution.
741: */
742: gettimeofday(&rightnow, NULL);
1.149 christos 743: srandom(rightnow.tv_sec + rightnow.tv_usec);
1.55 sjg 744:
1.53 christos 745: if ((progname = strrchr(argv[0], '/')) != NULL)
746: progname++;
747: else
748: progname = argv[0];
1.21 christos 749: #ifdef RLIMIT_NOFILE
750: /*
751: * get rid of resource limit on file descriptors
752: */
753: {
754: struct rlimit rl;
755: if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
756: rl.rlim_cur != rl.rlim_max) {
757: rl.rlim_cur = rl.rlim_max;
1.112 christos 758: (void)setrlimit(RLIMIT_NOFILE, &rl);
1.21 christos 759: }
760: }
761: #endif
1.13 cgd 762: /*
763: * Find where we are and take care of PWD for the automounter...
764: * All this code is so that we know where we are when we start up
765: * on a different machine with pmake.
766: */
1.16 mycroft 767: if (getcwd(curdir, MAXPATHLEN) == NULL) {
1.63 christos 768: (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
1.13 cgd 769: exit(2);
770: }
771:
1.77 tv 772: if (stat(curdir, &sa) == -1) {
1.63 christos 773: (void)fprintf(stderr, "%s: %s: %s.\n",
774: progname, curdir, strerror(errno));
1.13 cgd 775: exit(2);
1.77 tv 776: }
777:
778: /*
779: * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
780: * since the value of curdir can very depending on how we got
781: * here. Ie sitting at a shell prompt (shell that provides $PWD)
782: * or via subdir.mk in which case its likely a shell which does
783: * not provide it.
784: * So, to stop it breaking this case only, we ignore PWD if
785: * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
786: */
787: if ((pwd = getenv("PWD")) != NULL && getenv("MAKEOBJDIRPREFIX") == NULL) {
788: const char *makeobjdir = getenv("MAKEOBJDIR");
789:
790: if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
791: if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
792: sa.st_dev == sb.st_dev)
1.112 christos 793: (void)strncpy(curdir, pwd, MAXPATHLEN);
1.77 tv 794: }
1.13 cgd 795: }
796:
1.17 gwr 797: /*
798: * Get the name of this type of MACHINE from utsname
799: * so we can share an executable for similar machines.
800: * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
801: *
1.33 christos 802: * Note that both MACHINE and MACHINE_ARCH are decided at
803: * run-time.
1.17 gwr 804: */
1.34 gwr 805: if (!machine) {
1.102 ross 806: #ifdef MAKE_NATIVE
1.23 christos 807: if (uname(&utsname) == -1) {
1.63 christos 808: (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
809: strerror(errno));
810: exit(2);
1.18 christos 811: }
812: machine = utsname.machine;
1.26 christos 813: #else
1.81 tv 814: #ifdef MAKE_MACHINE
1.80 thorpej 815: machine = MAKE_MACHINE;
1.81 tv 816: #else
817: machine = "unknown";
818: #endif
1.26 christos 819: #endif
1.17 gwr 820: }
1.1 cgd 821:
1.33 christos 822: if (!machine_arch) {
823: #ifndef MACHINE_ARCH
1.80 thorpej 824: #ifdef MAKE_MACHINE_ARCH
825: machine_arch = MAKE_MACHINE_ARCH;
1.43 wsanchez 826: #else
1.81 tv 827: machine_arch = "unknown";
1.43 wsanchez 828: #endif
1.33 christos 829: #else
830: machine_arch = MACHINE_ARCH;
831: #endif
832: }
833:
1.1 cgd 834: /*
1.51 sjg 835: * Just in case MAKEOBJDIR wants us to do something tricky.
836: */
837: Var_Init(); /* Initialize the lists of variables for
838: * parsing arguments */
1.71 sjg 839: Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
840: Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
841: Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
1.170 perry 842: #ifdef MAKE_VERSION
843: Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
844: #endif
1.71 sjg 845: Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
1.51 sjg 846:
847: /*
1.74 tv 848: * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that,
849: * MAKEOBJDIR is set in the environment, try only that value
850: * and fall back to .CURDIR if it does not exist.
1.111 lukem 851: *
852: * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and
853: * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
854: * of these paths exist, just use .CURDIR.
1.74 tv 855: */
1.79 tv 856: Dir_Init(curdir);
1.112 christos 857: (void)Main_SetObjdir(curdir);
1.79 tv 858:
1.74 tv 859: if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) {
1.112 christos 860: (void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir);
861: (void)Main_SetObjdir(mdpath);
1.74 tv 862: } else if ((path = getenv("MAKEOBJDIR")) != NULL) {
1.112 christos 863: (void)Main_SetObjdir(path);
1.111 lukem 864: } else {
1.112 christos 865: (void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine);
1.111 lukem 866: if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) {
1.112 christos 867: (void)snprintf(mdpath, MAXPATHLEN, "%s%s",
1.111 lukem 868: _PATH_OBJDIRPREFIX, curdir);
1.112 christos 869: (void)Main_SetObjdir(mdpath);
1.111 lukem 870: }
1.4 cgd 871: }
1.13 cgd 872:
1.1 cgd 873: create = Lst_Init(FALSE);
874: makefiles = Lst_Init(FALSE);
1.31 christos 875: printVars = FALSE;
876: variables = Lst_Init(FALSE);
1.1 cgd 877: beSilent = FALSE; /* Print commands as executed */
878: ignoreErrors = FALSE; /* Pay attention to non-zero returns */
879: noExecute = FALSE; /* Execute all commands */
1.61 sommerfe 880: noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
1.1 cgd 881: keepgoing = FALSE; /* Stop on error */
882: allPrecious = FALSE; /* Remove targets when interrupted */
883: queryFlag = FALSE; /* This is not just a check-run */
884: noBuiltins = FALSE; /* Read the built-in rules */
885: touchFlag = FALSE; /* Actually update targets */
886: debug = 0; /* No debug verbosity, please. */
887: jobsRunning = FALSE;
888:
1.121 dsl 889: maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */
1.123 dsl 890: maxJobTokens = maxJobs;
1.21 christos 891: compatMake = FALSE; /* No compat mode */
1.31 christos 892:
1.13 cgd 893:
1.1 cgd 894: /*
895: * Initialize the parsing, directory and variable modules to prepare
896: * for the reading of inclusion paths and variable settings on the
897: * command line
898: */
1.36 gwr 899:
900: /*
1.1 cgd 901: * Initialize various variables.
902: * MAKE also gets this name, for compatibility
903: * .MAKEFLAGS gets set to the empty string just in case.
904: * MFLAGS also gets initialized empty, for compatibility.
905: */
1.79 tv 906: Parse_Init();
1.71 sjg 907: Var_Set("MAKE", argv[0], VAR_GLOBAL, 0);
908: Var_Set(".MAKE", argv[0], VAR_GLOBAL, 0);
909: Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0);
910: Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
911: Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
1.78 tv 912: Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);
1.1 cgd 913:
914: /*
1.142 sjg 915: * Set some other useful macros
916: */
917: {
918: char tmp[64];
919:
1.149 christos 920: snprintf(tmp, sizeof(tmp), "%u", getpid());
1.142 sjg 921: Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
1.149 christos 922: snprintf(tmp, sizeof(tmp), "%u", getppid());
1.142 sjg 923: Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
924: }
925: Job_SetPrefix();
926:
927: /*
1.1 cgd 928: * First snag any flags out of the MAKE environment variable.
929: * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
930: * in a different format).
931: */
932: #ifdef POSIX
933: Main_ParseArgLine(getenv("MAKEFLAGS"));
934: #else
935: Main_ParseArgLine(getenv("MAKE"));
936: #endif
1.31 christos 937:
1.149 christos 938: MainParseArgs(argc, argv);
1.1 cgd 939:
940: /*
1.58 sommerfe 941: * Be compatible if user did not specify -j and did not explicitly
942: * turned compatibility on
943: */
944: if (!compatMake && !forceJobs) {
945: compatMake = TRUE;
946: }
947:
948: /*
1.1 cgd 949: * Initialize archive, target and suffix modules in preparation for
950: * parsing the makefile(s)
951: */
952: Arch_Init();
953: Targ_Init();
954: Suff_Init();
1.58 sommerfe 955: Trace_Init(tracefile);
1.1 cgd 956:
1.157 dsl 957: DEFAULT = NULL;
1.1 cgd 958: (void)time(&now);
959:
1.58 sommerfe 960: Trace_Log(MAKESTART, NULL);
961:
1.1 cgd 962: /*
963: * Set up the .TARGETS variable to contain the list of targets to be
964: * created. If none specified, make the variable empty -- the parser
965: * will fill the thing in with the default or .MAIN target.
966: */
967: if (!Lst_IsEmpty(create)) {
968: LstNode ln;
969:
1.157 dsl 970: for (ln = Lst_First(create); ln != NULL;
1.1 cgd 971: ln = Lst_Succ(ln)) {
972: char *name = (char *)Lst_Datum(ln);
973:
974: Var_Append(".TARGETS", name, VAR_GLOBAL);
975: }
976: } else
1.71 sjg 977: Var_Set(".TARGETS", "", VAR_GLOBAL, 0);
1.1 cgd 978:
1.25 christos 979:
1.1 cgd 980: /*
1.25 christos 981: * If no user-supplied system path was given (through the -m option)
982: * add the directories from the DEFSYSPATH (more than one may be given
983: * as dir1:...:dirn) to the system include path.
1.1 cgd 984: */
1.73 tv 985: if (syspath == NULL || *syspath == '\0')
986: syspath = defsyspath;
987: else
1.151 joerg 988: syspath = bmake_strdup(syspath);
1.73 tv 989:
990: for (start = syspath; *start != '\0'; start = cp) {
991: for (cp = start; *cp != '\0' && *cp != ':'; cp++)
992: continue;
1.97 chuck 993: if (*cp == ':') {
994: *cp++ = '\0';
995: }
996: /* look for magic parent directory search string */
997: if (strncmp(".../", start, 4) != 0) {
1.112 christos 998: (void)Dir_AddDir(defIncPath, start);
1.73 tv 999: } else {
1.97 chuck 1000: if (Dir_FindHereOrAbove(curdir, start+4,
1001: found_path, sizeof(found_path))) {
1.112 christos 1002: (void)Dir_AddDir(defIncPath, found_path);
1.97 chuck 1003: }
1.25 christos 1004: }
1005: }
1.73 tv 1006: if (syspath != defsyspath)
1007: free(syspath);
1.25 christos 1008:
1009: /*
1010: * Read in the built-in rules first, followed by the specified
1.115 christos 1011: * makefile, if it was (makefile != NULL), or the default
1.99 fair 1012: * makefile and Makefile, in that order, if it wasn't.
1.25 christos 1013: */
1014: if (!noBuiltins) {
1015: LstNode ln;
1016:
1.106 christos 1017: sysMkPath = Lst_Init(FALSE);
1.73 tv 1018: Dir_Expand(_PATH_DEFSYSMK,
1019: Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
1020: sysMkPath);
1.25 christos 1021: if (Lst_IsEmpty(sysMkPath))
1.63 christos 1022: Fatal("%s: no system rules (%s).", progname,
1023: _PATH_DEFSYSMK);
1.134 dsl 1024: ln = Lst_Find(sysMkPath, NULL, ReadMakefile);
1.157 dsl 1025: if (ln == NULL)
1.63 christos 1026: Fatal("%s: cannot open %s.", progname,
1027: (char *)Lst_Datum(ln));
1.25 christos 1028: }
1.1 cgd 1029:
1030: if (!Lst_IsEmpty(makefiles)) {
1031: LstNode ln;
1032:
1.134 dsl 1033: ln = Lst_Find(makefiles, NULL, ReadAllMakefiles);
1.157 dsl 1034: if (ln != NULL)
1.63 christos 1035: Fatal("%s: cannot open %s.", progname,
1036: (char *)Lst_Datum(ln));
1.165 dsl 1037: } else if (ReadMakefile("makefile", NULL) != 0)
1038: (void)ReadMakefile("Makefile", NULL);
1.1 cgd 1039:
1.138 dsl 1040: /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
1.145 dsl 1041: if (!noBuiltins || !printVars) {
1042: doing_depend = TRUE;
1.165 dsl 1043: (void)ReadMakefile(".depend", NULL);
1.145 dsl 1044: doing_depend = FALSE;
1045: }
1.1 cgd 1046:
1.14 jtc 1047: Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
1048: if (p1)
1049: free(p1);
1.1 cgd 1050:
1.132 dsl 1051: if (!compatMake)
1052: Job_ServerStart(maxJobTokens, jp_0, jp_1);
1.58 sommerfe 1053: if (DEBUG(JOB))
1.133 dsl 1054: fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
1.132 dsl 1055: jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
1.58 sommerfe 1056:
1.73 tv 1057: Main_ExportMAKEFLAGS(TRUE); /* initial export */
1.1 cgd 1058:
1.54 sjg 1059: Check_Cwd_av(0, NULL, 0); /* initialize it */
1060:
1061:
1.1 cgd 1062: /*
1063: * For compatibility, look at the directories in the VPATH variable
1064: * and add them to the search path, if the variable is defined. The
1065: * variable's value is in the same format as the PATH envariable, i.e.
1066: * <directory>:<directory>:<directory>...
1067: */
1068: if (Var_Exists("VPATH", VAR_CMD)) {
1.82 reinoud 1069: char *vpath, savec;
1.1 cgd 1070: /*
1071: * GCC stores string constants in read-only memory, but
1072: * Var_Subst will want to write this thing, so store it
1073: * in an array
1074: */
1075: static char VPATH[] = "${VPATH}";
1076:
1.13 cgd 1077: vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
1.1 cgd 1078: path = vpath;
1079: do {
1080: /* skip to end of directory */
1.13 cgd 1081: for (cp = path; *cp != ':' && *cp != '\0'; cp++)
1082: continue;
1.1 cgd 1083: /* Save terminator character so know when to stop */
1084: savec = *cp;
1085: *cp = '\0';
1086: /* Add directory to search path */
1.112 christos 1087: (void)Dir_AddDir(dirSearchPath, path);
1.1 cgd 1088: *cp = savec;
1089: path = cp + 1;
1090: } while (savec == ':');
1.114 christos 1091: free(vpath);
1.1 cgd 1092: }
1093:
1094: /*
1095: * Now that all search paths have been read for suffixes et al, it's
1096: * time to add the default search path to their lists...
1097: */
1098: Suff_DoPaths();
1.50 mycroft 1099:
1100: /*
1101: * Propagate attributes through :: dependency lists.
1102: */
1103: Targ_Propagate();
1.1 cgd 1104:
1105: /* print the initial graph, if the user requested it */
1106: if (DEBUG(GRAPH1))
1107: Targ_PrintGraph(1);
1108:
1.31 christos 1109: /* print the values of any variables requested by the user */
1110: if (printVars) {
1111: LstNode ln;
1112:
1.157 dsl 1113: for (ln = Lst_First(variables); ln != NULL;
1.31 christos 1114: ln = Lst_Succ(ln)) {
1.92 sjg 1115: char *var = (char *)Lst_Datum(ln);
1116: char *value;
1117:
1118: if (strchr(var, '$')) {
1119: value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0);
1120: } else {
1121: value = Var_Value(var, VAR_GLOBAL, &p1);
1122: }
1.31 christos 1123: printf("%s\n", value ? value : "");
1124: if (p1)
1125: free(p1);
1126: }
1.138 dsl 1127: } else {
1.1 cgd 1128: /*
1.138 dsl 1129: * Have now read the entire graph and need to make a list of
1130: * targets to create. If none was given on the command line,
1131: * we consult the parsing module to find the main target(s)
1132: * to create.
1.1 cgd 1133: */
1.138 dsl 1134: if (Lst_IsEmpty(create))
1135: targs = Parse_MainName();
1136: else
1137: targs = Targ_FindList(create, TARG_CREATE);
1138:
1139: if (!compatMake) {
1140: /*
1141: * Initialize job module before traversing the graph
1142: * now that any .BEGIN and .END targets have been read.
1143: * This is done only if the -q flag wasn't given
1144: * (to prevent the .BEGIN from being executed should
1145: * it exist).
1146: */
1147: if (!queryFlag) {
1148: Job_Init();
1149: jobsRunning = TRUE;
1150: }
1151:
1152: /* Traverse the graph, checking on all the targets */
1153: outOfDate = Make_Run(targs);
1154: } else {
1155: /*
1156: * Compat_Init will take care of creating all the
1157: * targets as well as initializing the module.
1158: */
1159: Compat_Run(targs);
1.1 cgd 1160: }
1.31 christos 1161: }
1162:
1.49 mycroft 1163: #ifdef CLEANUP
1.157 dsl 1164: Lst_Destroy(targs, NULL);
1165: Lst_Destroy(variables, NULL);
1166: Lst_Destroy(makefiles, NULL);
1.116 christos 1167: Lst_Destroy(create, (FreeProc *)free);
1.49 mycroft 1168: #endif
1.14 jtc 1169:
1.1 cgd 1170: /* print the graph now it's been processed if the user requested it */
1171: if (DEBUG(GRAPH2))
1172: Targ_PrintGraph(2);
1173:
1.58 sommerfe 1174: Trace_Log(MAKEEND, 0);
1175:
1.14 jtc 1176: Suff_End();
1177: Targ_End();
1178: Arch_End();
1179: Var_End();
1180: Parse_End();
1181: Dir_End();
1.40 christos 1182: Job_End();
1.58 sommerfe 1183: Trace_End();
1.14 jtc 1184:
1.137 dsl 1185: return outOfDate ? 1 : 0;
1.1 cgd 1186: }
1187:
1188: /*-
1189: * ReadMakefile --
1190: * Open and parse the given makefile.
1191: *
1192: * Results:
1.124 sjg 1193: * 0 if ok. -1 if couldn't open file.
1.1 cgd 1194: *
1195: * Side Effects:
1196: * lots
1197: */
1.124 sjg 1198: static int
1.165 dsl 1199: ReadMakefile(const void *p, const void *q __unused)
1.1 cgd 1200: {
1.165 dsl 1201: const char *fname = p; /* makefile to read */
1.140 dsl 1202: int fd;
1.48 christos 1203: size_t len = MAXPATHLEN;
1.151 joerg 1204: char *name, *path = bmake_malloc(len);
1.67 sjg 1205: int setMAKEFILE;
1.1 cgd 1206:
1207: if (!strcmp(fname, "-")) {
1.140 dsl 1208: Parse_File("(stdin)", dup(fileno(stdin)));
1.71 sjg 1209: Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
1.1 cgd 1210: } else {
1.67 sjg 1211: setMAKEFILE = strcmp(fname, ".depend");
1212:
1.1 cgd 1213: /* if we've chdir'd, rebuild the path name */
1.74 tv 1214: if (strcmp(curdir, objdir) && *fname != '/') {
1.48 christos 1215: size_t plen = strlen(curdir) + strlen(fname) + 2;
1216: if (len < plen)
1.151 joerg 1217: path = bmake_realloc(path, len = 2 * plen);
1.48 christos 1218:
1219: (void)snprintf(path, len, "%s/%s", curdir, fname);
1.140 dsl 1220: fd = open(path, O_RDONLY);
1221: if (fd != -1) {
1.1 cgd 1222: fname = path;
1223: goto found;
1224: }
1.95 jmc 1225:
1226: /* If curdir failed, try objdir (ala .depend) */
1227: plen = strlen(objdir) + strlen(fname) + 2;
1228: if (len < plen)
1.151 joerg 1229: path = bmake_realloc(path, len = 2 * plen);
1.95 jmc 1230: (void)snprintf(path, len, "%s/%s", objdir, fname);
1.140 dsl 1231: fd = open(path, O_RDONLY);
1232: if (fd != -1) {
1.95 jmc 1233: fname = path;
1234: goto found;
1235: }
1.140 dsl 1236: } else {
1237: fd = open(fname, O_RDONLY);
1238: if (fd != -1)
1239: goto found;
1240: }
1.1 cgd 1241: /* look in -I and system include directories. */
1242: name = Dir_FindFile(fname, parseIncPath);
1243: if (!name)
1.73 tv 1244: name = Dir_FindFile(fname,
1245: Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
1.140 dsl 1246: if (!name || (fd = open(name, O_RDONLY)) == -1) {
1.126 christos 1247: if (name)
1248: free(name);
1.48 christos 1249: free(path);
1.124 sjg 1250: return(-1);
1.48 christos 1251: }
1.1 cgd 1252: fname = name;
1253: /*
1254: * set the MAKEFILE variable desired by System V fans -- the
1255: * placement of the setting here means it gets set to the last
1256: * makefile specified, as it is set by SysV make.
1257: */
1.67 sjg 1258: found:
1259: if (setMAKEFILE)
1.71 sjg 1260: Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
1.140 dsl 1261: Parse_File(fname, fd);
1.1 cgd 1262: }
1.48 christos 1263: free(path);
1.124 sjg 1264: return(0);
1.54 sjg 1265: }
1266:
1267:
1268: /*
1269: * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR
1270: * in situations that would not arrise with ./obj (links or not).
1271: * This tends to break things like:
1272: *
1273: * build:
1274: * ${MAKE} includes
1275: *
1276: * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as
1277: * opposed to an argument) in a command line and if so returns
1278: * ${.CURDIR} so caller can chdir() so that the assumptions made by
1279: * the Makefile hold true.
1280: *
1281: * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped.
1282: *
1283: * The chdir() only happens in the child process, and does nothing if
1284: * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it
1285: * should not break anything. Also if NOCHECKMAKECHDIR is set we
1286: * do nothing - to ensure historic semantics can be retained.
1287: */
1288: static int Check_Cwd_Off = 0;
1289:
1290: static char *
1.149 christos 1291: Check_Cwd_av(int ac, char **av, int copy)
1.54 sjg 1292: {
1293: static char *make[4];
1.82 reinoud 1294: static char *cur_dir = NULL;
1.89 christos 1295: char **mp;
1296: char *cp;
1.54 sjg 1297: int is_cmd, next_cmd;
1298: int i;
1299: int n;
1300:
1.155 christos 1301: if (Check_Cwd_Off) {
1302: if (DEBUG(CWD))
1303: fprintf(debug_file, "check_cwd: check is off.\n");
1.54 sjg 1304: return NULL;
1.155 christos 1305: }
1.54 sjg 1306:
1307: if (make[0] == NULL) {
1308: if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
1309: Check_Cwd_Off = 1;
1.155 christos 1310: if (DEBUG(CWD))
1311: fprintf(debug_file, "check_cwd: turning check off.\n");
1.54 sjg 1312: return NULL;
1313: }
1314:
1315: make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
1316: if ((make[0] = strrchr(make[1], '/')) == NULL) {
1317: make[0] = make[1];
1318: make[1] = NULL;
1319: } else
1320: ++make[0];
1321: make[2] = NULL;
1.82 reinoud 1322: cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
1.54 sjg 1323: }
1.155 christos 1324: if (ac == 0 || av == NULL) {
1325: if (DEBUG(CWD))
1326: fprintf(debug_file, "check_cwd: empty command.\n");
1.54 sjg 1327: return NULL; /* initialization only */
1.155 christos 1328: }
1.54 sjg 1329:
1330: if (getenv("MAKEOBJDIR") == NULL &&
1.155 christos 1331: getenv("MAKEOBJDIRPREFIX") == NULL) {
1332: if (DEBUG(CWD))
1333: fprintf(debug_file, "check_cwd: no obj dirs.\n");
1.54 sjg 1334: return NULL;
1.155 christos 1335: }
1.54 sjg 1336:
1337:
1338: next_cmd = 1;
1339: for (i = 0; i < ac; ++i) {
1340: is_cmd = next_cmd;
1341:
1342: n = strlen(av[i]);
1343: cp = &(av[i])[n - 1];
1.127 rillig 1344: if (strspn(av[i], "|&;") == (size_t)n) {
1.54 sjg 1345: next_cmd = 1;
1346: continue;
1347: } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
1348: next_cmd = 1;
1349: if (copy) {
1350: do {
1351: *cp-- = '\0';
1352: } while (*cp == ';' || *cp == '&' || *cp == '|' ||
1353: *cp == ')' || *cp == '}') ;
1354: } else {
1355: /*
1356: * XXX this should not happen.
1357: */
1.155 christos 1358: fprintf(stderr, "%s: WARNING: raw arg ends in shell meta '%s'\n",
1359: progname, av[i]);
1.54 sjg 1360: }
1361: } else
1362: next_cmd = 0;
1363:
1364: cp = av[i];
1365: if (*cp == ';' || *cp == '&' || *cp == '|')
1366: is_cmd = 1;
1367:
1.155 christos 1368: if (DEBUG(CWD))
1369: fprintf(debug_file, "av[%d] == %s '%s'",
1.54 sjg 1370: i, (is_cmd) ? "cmd" : "arg", av[i]);
1371: if (is_cmd != 0) {
1.57 sjg 1372: if (*cp == '(' || *cp == '{' ||
1373: *cp == ';' || *cp == '&' || *cp == '|') {
1374: do {
1375: ++cp;
1376: } while (*cp == '(' || *cp == '{' ||
1377: *cp == ';' || *cp == '&' || *cp == '|');
1378: if (*cp == '\0') {
1379: next_cmd = 1;
1380: continue;
1381: }
1382: }
1.54 sjg 1383: if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
1.155 christos 1384: if (DEBUG(CWD))
1385: fprintf(debug_file, " == cd, done.\n");
1.54 sjg 1386: return NULL;
1387: }
1388: for (mp = make; *mp != NULL; ++mp) {
1389: n = strlen(*mp);
1390: if (strcmp(cp, *mp) == 0) {
1.155 christos 1391: if (DEBUG(CWD))
1392: fprintf(debug_file, " %s == '%s', chdir(%s)\n",
1.82 reinoud 1393: cp, *mp, cur_dir);
1394: return cur_dir;
1.54 sjg 1395: }
1396: }
1397: }
1.155 christos 1398: if (DEBUG(CWD))
1399: fprintf(debug_file, "\n");
1.54 sjg 1400: }
1401: return NULL;
1402: }
1403:
1404: char *
1.89 christos 1405: Check_Cwd_Cmd(const char *cmd)
1.54 sjg 1406: {
1.89 christos 1407: char *cp, *bp;
1408: char **av;
1.149 christos 1409: int ac;
1.54 sjg 1410:
1411: if (Check_Cwd_Off)
1412: return NULL;
1413:
1414: if (cmd) {
1415: av = brk_string(cmd, &ac, TRUE, &bp);
1.155 christos 1416: if (DEBUG(CWD))
1417: fprintf(debug_file, "splitting: '%s' -> %d words\n",
1.54 sjg 1418: cmd, ac);
1419: } else {
1420: ac = 0;
1421: av = NULL;
1422: bp = NULL;
1423: }
1424: cp = Check_Cwd_av(ac, av, 1);
1.125 christos 1425: if (bp)
1426: free(bp);
1427: if (av)
1.54 sjg 1428: free(av);
1429: return cp;
1430: }
1431:
1432: void
1.89 christos 1433: Check_Cwd(const char **argv)
1.54 sjg 1434: {
1435: char *cp;
1.149 christos 1436: int ac;
1.54 sjg 1437:
1438: if (Check_Cwd_Off)
1439: return;
1440:
1441: for (ac = 0; argv[ac] != NULL; ++ac)
1442: /* NOTHING */;
1443: if (ac == 3 && *argv[1] == '-') {
1444: cp = Check_Cwd_Cmd(argv[2]);
1445: } else {
1.89 christos 1446: cp = Check_Cwd_av(ac, UNCONST(argv), 0);
1.54 sjg 1447: }
1448: if (cp) {
1449: chdir(cp);
1450: }
1.29 christos 1451: }
1452:
1453: /*-
1454: * Cmd_Exec --
1455: * Execute the command in cmd, and return the output of that command
1456: * in a string.
1457: *
1458: * Results:
1459: * A string containing the output of the command, or the empty string
1.129 christos 1460: * If errnum is not NULL, it contains the reason for the command failure
1.29 christos 1461: *
1462: * Side Effects:
1463: * The string must be freed by the caller.
1464: */
1465: char *
1.129 christos 1466: Cmd_Exec(const char *cmd, const char **errnum)
1.29 christos 1467: {
1.89 christos 1468: const char *args[4]; /* Args for invoking the shell */
1.29 christos 1469: int fds[2]; /* Pipe streams */
1.149 christos 1470: int cpid; /* Child PID */
1471: int pid; /* PID from wait() */
1.29 christos 1472: char *res; /* result */
1473: int status; /* command exit status */
1474: Buffer buf; /* buffer to store the result */
1475: char *cp;
1.149 christos 1476: int cc;
1.29 christos 1477:
1478:
1.129 christos 1479: *errnum = NULL;
1.29 christos 1480:
1.90 sjg 1481: if (!shellName)
1482: Shell_Init();
1.29 christos 1483: /*
1484: * Set up arguments for shell
1485: */
1.90 sjg 1486: args[0] = shellName;
1.29 christos 1487: args[1] = "-c";
1488: args[2] = cmd;
1489: args[3] = NULL;
1490:
1491: /*
1492: * Open a pipe for fetching its output
1493: */
1494: if (pipe(fds) == -1) {
1.129 christos 1495: *errnum = "Couldn't create pipe for \"%s\"";
1.29 christos 1496: goto bad;
1497: }
1498:
1499: /*
1500: * Fork
1501: */
1502: switch (cpid = vfork()) {
1503: case 0:
1504: /*
1505: * Close input side of pipe
1506: */
1.112 christos 1507: (void)close(fds[0]);
1.29 christos 1508:
1509: /*
1510: * Duplicate the output stream to the shell's output, then
1511: * shut the extra thing down. Note we don't fetch the error
1512: * stream...why not? Why?
1513: */
1.112 christos 1514: (void)dup2(fds[1], 1);
1515: (void)close(fds[1]);
1.31 christos 1516:
1.143 sjg 1517: Var_ExportVars();
1518:
1.112 christos 1519: (void)execv(shellPath, UNCONST(args));
1.29 christos 1520: _exit(1);
1521: /*NOTREACHED*/
1522:
1523: case -1:
1.129 christos 1524: *errnum = "Couldn't exec \"%s\"";
1.29 christos 1525: goto bad;
1526:
1527: default:
1528: /*
1529: * No need for the writing half
1530: */
1.112 christos 1531: (void)close(fds[1]);
1.31 christos 1532:
1.163 dsl 1533: Buf_Init(&buf, 0);
1.29 christos 1534:
1535: do {
1536: char result[BUFSIZ];
1537: cc = read(fds[0], result, sizeof(result));
1.31 christos 1538: if (cc > 0)
1.163 dsl 1539: Buf_AddBytes(&buf, cc, result);
1.29 christos 1540: }
1541: while (cc > 0 || (cc == -1 && errno == EINTR));
1542:
1543: /*
1544: * Close the input side of the pipe.
1545: */
1.112 christos 1546: (void)close(fds[0]);
1.29 christos 1547:
1548: /*
1549: * Wait for the process to exit.
1550: */
1.138 dsl 1551: while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0))
1.29 christos 1552: continue;
1553:
1.163 dsl 1554: cc = Buf_Size(&buf);
1555: res = Buf_Destroy(&buf, FALSE);
1.29 christos 1556:
1.149 christos 1557: if (cc == 0)
1.129 christos 1558: *errnum = "Couldn't read shell's output for \"%s\"";
1.29 christos 1559:
1.172 ! dholland 1560: if (WIFSIGNALED(status))
! 1561: *errnum = "\"%s\" exited on a signal";
! 1562: else if (WEXITSTATUS(status) != 0)
1.129 christos 1563: *errnum = "\"%s\" returned non-zero status";
1.29 christos 1564:
1565: /*
1566: * Null-terminate the result, convert newlines to spaces and
1567: * install it in the variable.
1568: */
1.149 christos 1569: res[cc] = '\0';
1570: cp = &res[cc];
1.29 christos 1571:
1.149 christos 1572: if (cc > 0 && *--cp == '\n') {
1.29 christos 1573: /*
1574: * A final newline is just stripped
1575: */
1576: *cp-- = '\0';
1577: }
1578: while (cp >= res) {
1579: if (*cp == '\n') {
1580: *cp = ' ';
1581: }
1582: cp--;
1583: }
1584: break;
1585: }
1586: return res;
1587: bad:
1.151 joerg 1588: res = bmake_malloc(1);
1.29 christos 1589: *res = '\0';
1590: return res;
1.1 cgd 1591: }
1592:
1593: /*-
1594: * Error --
1595: * Print an error message given its format.
1596: *
1597: * Results:
1598: * None.
1599: *
1600: * Side Effects:
1601: * The message is printed.
1602: */
1603: /* VARARGS */
1604: void
1.89 christos 1605: Error(const char *fmt, ...)
1.1 cgd 1606: {
1607: va_list ap;
1.162 dsl 1608: FILE *err_file;
1.85 wiz 1609:
1.162 dsl 1610: err_file = debug_file;
1611: if (err_file == stdout)
1612: err_file = stderr;
1613: for (;;) {
1614: va_start(ap, fmt);
1615: fprintf(err_file, "%s: ", progname);
1616: (void)vfprintf(err_file, fmt, ap);
1617: va_end(ap);
1618: (void)fprintf(err_file, "\n");
1619: (void)fflush(err_file);
1620: if (err_file == stderr)
1621: break;
1622: err_file = stderr;
1623: }
1.1 cgd 1624: }
1625:
1626: /*-
1627: * Fatal --
1628: * Produce a Fatal error message. If jobs are running, waits for them
1629: * to finish.
1630: *
1631: * Results:
1632: * None
1633: *
1634: * Side Effects:
1635: * The program exits
1636: */
1637: /* VARARGS */
1638: void
1.89 christos 1639: Fatal(const char *fmt, ...)
1.1 cgd 1640: {
1641: va_list ap;
1.85 wiz 1642:
1.13 cgd 1643: va_start(ap, fmt);
1.1 cgd 1644: if (jobsRunning)
1645: Job_Wait();
1646:
1647: (void)vfprintf(stderr, fmt, ap);
1648: va_end(ap);
1649: (void)fprintf(stderr, "\n");
1650: (void)fflush(stderr);
1651:
1.67 sjg 1652: PrintOnError(NULL);
1653:
1.94 dsl 1654: if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
1.1 cgd 1655: Targ_PrintGraph(2);
1.58 sommerfe 1656: Trace_Log(MAKEERROR, 0);
1.1 cgd 1657: exit(2); /* Not 1 so -q can distinguish error */
1658: }
1659:
1660: /*
1661: * Punt --
1662: * Major exception once jobs are being created. Kills all jobs, prints
1663: * a message and exits.
1664: *
1665: * Results:
1.31 christos 1666: * None
1.1 cgd 1667: *
1668: * Side Effects:
1669: * All children are killed indiscriminately and the program Lib_Exits
1670: */
1671: /* VARARGS */
1672: void
1.89 christos 1673: Punt(const char *fmt, ...)
1.1 cgd 1674: {
1675: va_list ap;
1.85 wiz 1676:
1.13 cgd 1677: va_start(ap, fmt);
1.63 christos 1678: (void)fprintf(stderr, "%s: ", progname);
1.1 cgd 1679: (void)vfprintf(stderr, fmt, ap);
1680: va_end(ap);
1681: (void)fprintf(stderr, "\n");
1682: (void)fflush(stderr);
1683:
1.67 sjg 1684: PrintOnError(NULL);
1685:
1.1 cgd 1686: DieHorribly();
1687: }
1688:
1689: /*-
1690: * DieHorribly --
1691: * Exit without giving a message.
1692: *
1693: * Results:
1694: * None
1695: *
1696: * Side Effects:
1697: * A big one...
1698: */
1699: void
1.85 wiz 1700: DieHorribly(void)
1.1 cgd 1701: {
1702: if (jobsRunning)
1703: Job_AbortAll();
1704: if (DEBUG(GRAPH2))
1705: Targ_PrintGraph(2);
1.58 sommerfe 1706: Trace_Log(MAKEERROR, 0);
1.1 cgd 1707: exit(2); /* Not 1, so -q can distinguish error */
1708: }
1709:
1710: /*
1711: * Finish --
1712: * Called when aborting due to errors in child shell to signal
1.31 christos 1713: * abnormal exit.
1.1 cgd 1714: *
1715: * Results:
1.31 christos 1716: * None
1.1 cgd 1717: *
1718: * Side Effects:
1719: * The program exits
1720: */
1721: void
1.85 wiz 1722: Finish(int errors)
1723: /* number of errors encountered in Make_Make */
1.1 cgd 1724: {
1725: Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1726: }
1727:
1.21 christos 1728: /*
1729: * enunlink --
1730: * Remove a file carefully, avoiding directories.
1731: */
1732: int
1.85 wiz 1733: eunlink(const char *file)
1.21 christos 1734: {
1735: struct stat st;
1736:
1737: if (lstat(file, &st) == -1)
1738: return -1;
1739:
1740: if (S_ISDIR(st.st_mode)) {
1741: errno = EISDIR;
1742: return -1;
1743: }
1744: return unlink(file);
1.1 cgd 1745: }
1746:
1747: /*
1.66 christos 1748: * execError --
1749: * Print why exec failed, avoiding stdio.
1750: */
1751: void
1.85 wiz 1752: execError(const char *af, const char *av)
1.66 christos 1753: {
1754: #ifdef USE_IOVEC
1755: int i = 0;
1.83 pk 1756: struct iovec iov[8];
1.66 christos 1757: #define IOADD(s) \
1.89 christos 1758: (void)(iov[i].iov_base = UNCONST(s), \
1.66 christos 1759: iov[i].iov_len = strlen(iov[i].iov_base), \
1760: i++)
1761: #else
1.112 christos 1762: #define IOADD(void)write(2, s, strlen(s))
1.66 christos 1763: #endif
1764:
1765: IOADD(progname);
1.83 pk 1766: IOADD(": ");
1.89 christos 1767: IOADD(af);
1.83 pk 1768: IOADD("(");
1.89 christos 1769: IOADD(av);
1.83 pk 1770: IOADD(") failed (");
1.66 christos 1771: IOADD(strerror(errno));
1772: IOADD(")\n");
1773:
1774: #ifdef USE_IOVEC
1.83 pk 1775: (void)writev(2, iov, 8);
1.66 christos 1776: #endif
1777: }
1778:
1779: /*
1.1 cgd 1780: * usage --
1781: * exit with usage message
1782: */
1.13 cgd 1783: static void
1.85 wiz 1784: usage(void)
1.1 cgd 1785: {
1786: (void)fprintf(stderr,
1.171 sjg 1787: "usage: %s [-BeikNnqrstWX] \n\
1788: [-C directory] [-D variable] [-d flags] [-f makefile]\n\
1.105 wiz 1789: [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
1790: [-V variable] [variable=value] [target ...]\n", progname);
1.1 cgd 1791: exit(2);
1.14 jtc 1792: }
1793:
1794:
1795: int
1.164 dsl 1796: PrintAddr(void *a, void *b)
1.14 jtc 1797: {
1798: printf("%lx ", (unsigned long) a);
1799: return b ? 0 : 0;
1.67 sjg 1800: }
1.149 christos 1801:
1.67 sjg 1802:
1803:
1804: void
1.89 christos 1805: PrintOnError(const char *s)
1.67 sjg 1806: {
1807: char tmp[64];
1.128 sjg 1808: char *cp;
1809:
1.67 sjg 1810: if (s)
1811: printf("%s", s);
1812:
1813: printf("\n%s: stopped in %s\n", progname, curdir);
1814: strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
1815: sizeof(tmp) - 1);
1.128 sjg 1816: cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
1817: if (cp) {
1818: if (*cp)
1819: printf("%s", cp);
1820: free(cp);
1821: }
1.68 sjg 1822: }
1823:
1824: void
1.85 wiz 1825: Main_ExportMAKEFLAGS(Boolean first)
1.68 sjg 1826: {
1827: static int once = 1;
1828: char tmp[64];
1829: char *s;
1830:
1831: if (once != first)
1832: return;
1833: once = 0;
1834:
1.70 sjg 1835: strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
1836: sizeof(tmp));
1837: s = Var_Subst(NULL, tmp, VAR_CMD, 0);
1.68 sjg 1838: if (s && *s) {
1839: #ifdef POSIX
1840: setenv("MAKEFLAGS", s, 1);
1841: #else
1842: setenv("MAKE", s, 1);
1843: #endif
1844: }
1.1 cgd 1845: }
CVSweb <webmaster@jp.NetBSD.org>