Annotation of src/usr.bin/make/main.c, Revision 1.421
1.421 ! rillig 1: /* $NetBSD: main.c,v 1.420 2020/10/31 21:09:22 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:
71: /*-
72: * main.c --
73: * The main file for this entire program. Exit routines etc
74: * reside here.
75: *
76: * Utility functions defined in this file:
77: * Main_ParseArgLine Takes a line of arguments, breaks them and
78: * treats them as if they were given when first
79: * invoked. Used by the parse module to implement
80: * the .MFLAGS target.
81: *
82: * Error Print a tagged error message. The global
83: * MAKE variable must have been defined. This
1.227 gson 84: * takes a format string and optional arguments
85: * for it.
1.1 cgd 86: *
87: * Fatal Print an error message and exit. Also takes
1.227 gson 88: * a format string and arguments for it.
1.1 cgd 89: *
90: * Punt Aborts all jobs and exits with a message. Also
1.227 gson 91: * takes a format string and arguments for it.
1.1 cgd 92: *
93: * Finish Finish things up by printing the number of
1.72 wiz 94: * errors which occurred, as passed to it, and
1.1 cgd 95: * exiting.
96: */
97:
1.13 cgd 98: #include <sys/types.h>
99: #include <sys/time.h>
1.1 cgd 100: #include <sys/param.h>
1.13 cgd 101: #include <sys/resource.h>
1.1 cgd 102: #include <sys/stat.h>
1.225 matt 103: #ifdef MAKE_NATIVE
104: #include <sys/sysctl.h>
105: #endif
1.17 gwr 106: #include <sys/utsname.h>
1.29 christos 107: #include <sys/wait.h>
1.85 wiz 108:
1.1 cgd 109: #include <errno.h>
1.215 christos 110: #include <signal.h>
1.85 wiz 111: #include <stdarg.h>
1.42 kleink 112: #include <time.h>
1.85 wiz 113:
1.1 cgd 114: #include "make.h"
1.13 cgd 115: #include "dir.h"
116: #include "job.h"
1.1 cgd 117: #include "pathnames.h"
1.58 sommerfe 118: #include "trace.h"
1.1 cgd 119:
1.337 rillig 120: /* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
1.421 ! rillig 121: MAKE_RCSID("$NetBSD: main.c,v 1.420 2020/10/31 21:09:22 sjg Exp $");
1.337 rillig 122: #if defined(MAKE_NATIVE) && !defined(lint)
1.369 rillig 123: __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
124: "The Regents of the University of California. "
125: "All rights reserved.");
1.337 rillig 126: #endif
127:
1.1 cgd 128: #ifndef DEFMAXLOCAL
129: #define DEFMAXLOCAL DEFMAXJOBS
1.336 rillig 130: #endif
1.1 cgd 131:
1.391 rillig 132: CmdOpts opts;
1.1 cgd 133: time_t now; /* Time at start of make */
134: GNode *DEFAULT; /* .DEFAULT node */
135: Boolean allPrecious; /* .PRECIOUS given on line by itself */
1.251 dholland 136: Boolean deleteOnError; /* .DELETE_ON_ERROR: set */
1.1 cgd 137:
1.132 dsl 138: static int maxJobTokens; /* -j argument */
1.233 sjg 139: Boolean enterFlagObj; /* -w and objdir != srcdir */
1.391 rillig 140:
1.1 cgd 141: Boolean oldVars; /* variable substitution style */
1.132 dsl 142: static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
1.145 dsl 143: Boolean doing_depend; /* Set while reading .depend */
1.1 cgd 144: static Boolean jobsRunning; /* TRUE if the jobs might be running */
1.58 sommerfe 145: static const char * tracefile;
1.325 rillig 146: static int ReadMakefile(const char *);
1.200 joerg 147: static void usage(void) MAKE_ATTR_DEAD;
1.262 riastrad 148: static void purge_cached_realpaths(void);
1.1 cgd 149:
1.174 sjg 150: static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
1.74 tv 151: static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
1.196 joerg 152: char curdir[MAXPATHLEN + 1]; /* Startup directory */
1.63 christos 153: char *progname; /* the program name */
1.176 sjg 154: char *makeDependfile;
1.183 sjg 155: pid_t myPid;
1.220 christos 156: int makelevel;
1.1 cgd 157:
1.58 sommerfe 158: Boolean forceJobs = FALSE;
1.421 ! rillig 159: static int errors = 0;
1.58 sommerfe 160:
1.338 rillig 161: extern SearchPath *parseIncPath;
1.63 christos 162:
1.220 christos 163: /*
164: * For compatibility with the POSIX version of MAKEFLAGS that includes
165: * all the options with out -, convert flags to -f -l -a -g -s.
166: */
167: static char *
168: explode(const char *flags)
169: {
170: size_t len;
171: char *nf, *st;
172: const char *f;
173:
174: if (flags == NULL)
175: return NULL;
176:
177: for (f = flags; *f; f++)
1.332 rillig 178: if (!ch_isalpha(*f))
1.220 christos 179: break;
180:
181: if (*f)
1.221 christos 182: return bmake_strdup(flags);
1.220 christos 183:
184: len = strlen(flags);
1.221 christos 185: st = nf = bmake_malloc(len * 3 + 1);
1.220 christos 186: while (*flags) {
187: *nf++ = '-';
188: *nf++ = *flags++;
189: *nf++ = ' ';
190: }
191: *nf = '\0';
192: return st;
193: }
1.279 rillig 194:
1.133 dsl 195: static void
1.344 rillig 196: parse_debug_option_F(const char *modules)
197: {
198: const char *mode;
199: size_t len;
200: char *fname;
201:
1.391 rillig 202: if (opts.debug_file != stdout && opts.debug_file != stderr)
203: fclose(opts.debug_file);
1.344 rillig 204:
205: if (*modules == '+') {
206: modules++;
207: mode = "a";
208: } else
209: mode = "w";
210:
211: if (strcmp(modules, "stdout") == 0) {
1.391 rillig 212: opts.debug_file = stdout;
1.344 rillig 213: return;
214: }
215: if (strcmp(modules, "stderr") == 0) {
1.391 rillig 216: opts.debug_file = stderr;
1.344 rillig 217: return;
218: }
219:
220: len = strlen(modules);
221: fname = bmake_malloc(len + 20);
222: memcpy(fname, modules, len + 1);
223:
224: /* Let the filename be modified by the pid */
225: if (strcmp(fname + len - 3, ".%d") == 0)
226: snprintf(fname + len - 2, 20, "%d", getpid());
227:
1.391 rillig 228: opts.debug_file = fopen(fname, mode);
229: if (!opts.debug_file) {
1.344 rillig 230: fprintf(stderr, "Cannot open debug file %s\n",
231: fname);
232: usage();
233: }
234: free(fname);
235: }
236:
237: static void
1.133 dsl 238: parse_debug_options(const char *argvalue)
239: {
240: const char *modules;
241:
242: for (modules = argvalue; *modules; ++modules) {
243: switch (*modules) {
1.369 rillig 244: case '0': /* undocumented, only intended for tests */
1.391 rillig 245: opts.debug &= DEBUG_LINT;
1.369 rillig 246: break;
1.133 dsl 247: case 'A':
1.391 rillig 248: opts.debug = ~(0|DEBUG_LINT);
1.133 dsl 249: break;
250: case 'a':
1.391 rillig 251: opts.debug |= DEBUG_ARCH;
1.133 dsl 252: break;
1.155 christos 253: case 'C':
1.391 rillig 254: opts.debug |= DEBUG_CWD;
1.155 christos 255: break;
1.133 dsl 256: case 'c':
1.391 rillig 257: opts.debug |= DEBUG_COND;
1.133 dsl 258: break;
259: case 'd':
1.391 rillig 260: opts.debug |= DEBUG_DIR;
1.133 dsl 261: break;
262: case 'e':
1.391 rillig 263: opts.debug |= DEBUG_ERROR;
1.133 dsl 264: break;
265: case 'f':
1.391 rillig 266: opts.debug |= DEBUG_FOR;
1.133 dsl 267: break;
268: case 'g':
269: if (modules[1] == '1') {
1.391 rillig 270: opts.debug |= DEBUG_GRAPH1;
1.133 dsl 271: ++modules;
272: }
273: else if (modules[1] == '2') {
1.391 rillig 274: opts.debug |= DEBUG_GRAPH2;
1.133 dsl 275: ++modules;
276: }
277: else if (modules[1] == '3') {
1.391 rillig 278: opts.debug |= DEBUG_GRAPH3;
1.133 dsl 279: ++modules;
280: }
281: break;
1.280 sjg 282: case 'h':
1.391 rillig 283: opts.debug |= DEBUG_HASH;
1.280 sjg 284: break;
1.133 dsl 285: case 'j':
1.391 rillig 286: opts.debug |= DEBUG_JOB;
1.133 dsl 287: break;
1.285 sjg 288: case 'L':
1.391 rillig 289: opts.debug |= DEBUG_LINT;
1.285 sjg 290: break;
1.146 sjg 291: case 'l':
1.391 rillig 292: opts.debug |= DEBUG_LOUD;
1.146 sjg 293: break;
1.190 sjg 294: case 'M':
1.391 rillig 295: opts.debug |= DEBUG_META;
1.190 sjg 296: break;
1.133 dsl 297: case 'm':
1.391 rillig 298: opts.debug |= DEBUG_MAKE;
1.133 dsl 299: break;
300: case 'n':
1.391 rillig 301: opts.debug |= DEBUG_SCRIPT;
1.133 dsl 302: break;
303: case 'p':
1.391 rillig 304: opts.debug |= DEBUG_PARSE;
1.133 dsl 305: break;
306: case 's':
1.391 rillig 307: opts.debug |= DEBUG_SUFF;
1.133 dsl 308: break;
309: case 't':
1.391 rillig 310: opts.debug |= DEBUG_TARG;
1.133 dsl 311: break;
1.201 sjg 312: case 'V':
1.394 rillig 313: opts.debugVflag = TRUE;
1.201 sjg 314: break;
1.133 dsl 315: case 'v':
1.391 rillig 316: opts.debug |= DEBUG_VAR;
1.133 dsl 317: break;
318: case 'x':
1.391 rillig 319: opts.debug |= DEBUG_SHELL;
1.133 dsl 320: break;
321: case 'F':
1.344 rillig 322: parse_debug_option_F(modules + 1);
1.153 apb 323: goto debug_setbuf;
1.133 dsl 324: default:
325: (void)fprintf(stderr,
326: "%s: illegal argument to d option -- %c\n",
327: progname, *modules);
328: usage();
329: }
330: }
1.153 apb 331: debug_setbuf:
332: /*
333: * Make the debug_file unbuffered, and make
334: * stdout line buffered (unless debugfile == stdout).
335: */
1.391 rillig 336: setvbuf(opts.debug_file, NULL, _IONBF, 0);
337: if (opts.debug_file != stdout) {
1.153 apb 338: setvbuf(stdout, NULL, _IOLBF, 0);
339: }
1.133 dsl 340: }
341:
1.264 sjg 342: /*
343: * does path contain any relative components
344: */
1.286 rillig 345: static Boolean
1.264 sjg 346: is_relpath(const char *path)
347: {
348: const char *cp;
349:
350: if (path[0] != '/')
351: return TRUE;
352: cp = path;
1.286 rillig 353: while ((cp = strstr(cp, "/.")) != NULL) {
1.264 sjg 354: cp += 2;
355: if (cp[0] == '/' || cp[0] == '\0')
356: return TRUE;
357: else if (cp[0] == '.') {
358: if (cp[1] == '/' || cp[1] == '\0')
359: return TRUE;
360: }
1.286 rillig 361: }
1.264 sjg 362: return FALSE;
363: }
364:
1.355 rillig 365: static void
366: MainParseArgChdir(const char *argvalue)
367: {
368: struct stat sa, sb;
369:
370: if (chdir(argvalue) == -1) {
371: (void)fprintf(stderr, "%s: chdir %s: %s\n",
372: progname, argvalue, strerror(errno));
373: exit(1);
374: }
375: if (getcwd(curdir, MAXPATHLEN) == NULL) {
376: (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
377: exit(2);
378: }
379: if (!is_relpath(argvalue) &&
380: stat(argvalue, &sa) != -1 &&
381: stat(curdir, &sb) != -1 &&
382: sa.st_ino == sb.st_ino &&
383: sa.st_dev == sb.st_dev)
384: strncpy(curdir, argvalue, MAXPATHLEN);
385: ignorePWD = TRUE;
386: }
387:
1.356 rillig 388: static void
389: MainParseArgJobsInternal(const char *argvalue)
390: {
391: if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
392: (void)fprintf(stderr,
393: "%s: internal error -- J option malformed (%s)\n",
394: progname, argvalue);
395: usage();
396: }
397: if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
398: (fcntl(jp_1, F_GETFD, 0) < 0)) {
399: #if 0
400: (void)fprintf(stderr,
401: "%s: ###### warning -- J descriptors were closed!\n",
402: progname);
403: exit(2);
404: #endif
405: jp_0 = -1;
406: jp_1 = -1;
1.391 rillig 407: opts.compatMake = TRUE;
1.356 rillig 408: } else {
409: Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
410: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
411: }
412: }
413:
414: static void
415: MainParseArgJobs(const char *argvalue)
416: {
417: char *p;
418:
419: forceJobs = TRUE;
1.391 rillig 420: opts.maxJobs = (int)strtol(argvalue, &p, 0);
421: if (*p != '\0' || opts.maxJobs < 1) {
1.356 rillig 422: (void)fprintf(stderr,
423: "%s: illegal argument to -j -- must be positive integer!\n",
424: progname);
425: exit(1); /* XXX: why not 2? */
426: }
427: Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
428: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
429: Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL);
1.391 rillig 430: maxJobTokens = opts.maxJobs;
1.356 rillig 431: }
432:
1.357 rillig 433: static void
434: MainParseArgSysInc(const char *argvalue)
435: {
436: /* look for magic parent directory search string */
437: if (strncmp(".../", argvalue, 4) == 0) {
1.371 rillig 438: char *found_path = Dir_FindHereOrAbove(curdir, argvalue + 4);
439: if (found_path == NULL)
1.357 rillig 440: return;
441: (void)Dir_AddDir(sysIncPath, found_path);
1.371 rillig 442: free(found_path);
1.357 rillig 443: } else {
444: (void)Dir_AddDir(sysIncPath, argvalue);
445: }
446: Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
447: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
448: }
449:
1.354 rillig 450: static Boolean
1.360 rillig 451: MainParseArg(char c, const char *argvalue)
1.354 rillig 452: {
453: switch (c) {
454: case '\0':
455: break;
456: case 'B':
1.391 rillig 457: opts.compatMake = TRUE;
1.354 rillig 458: Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
459: Var_Set(MAKE_MODE, "compat", VAR_GLOBAL);
460: break;
461: case 'C':
1.355 rillig 462: MainParseArgChdir(argvalue);
1.354 rillig 463: break;
464: case 'D':
1.359 rillig 465: if (argvalue[0] == '\0') return FALSE;
1.354 rillig 466: Var_Set(argvalue, "1", VAR_GLOBAL);
467: Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
468: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
469: break;
470: case 'I':
471: Parse_AddIncludeDir(argvalue);
472: Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
473: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
474: break;
475: case 'J':
1.356 rillig 476: MainParseArgJobsInternal(argvalue);
1.354 rillig 477: break;
478: case 'N':
1.391 rillig 479: opts.noExecute = TRUE;
480: opts.noRecursiveExecute = TRUE;
1.354 rillig 481: Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
482: break;
483: case 'S':
1.391 rillig 484: opts.keepgoing = FALSE;
1.354 rillig 485: Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
486: break;
487: case 'T':
488: tracefile = bmake_strdup(argvalue);
489: Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
490: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
491: break;
492: case 'V':
493: case 'v':
1.391 rillig 494: opts.printVars = c == 'v' ? EXPAND_VARS : COMPAT_VARS;
495: Lst_Append(opts.variables, bmake_strdup(argvalue));
496: /* XXX: Why always -V? */
1.354 rillig 497: Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
498: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
499: break;
500: case 'W':
1.391 rillig 501: opts.parseWarnFatal = TRUE;
1.354 rillig 502: break;
503: case 'X':
1.391 rillig 504: opts.varNoExportEnv = TRUE;
1.354 rillig 505: Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
506: break;
507: case 'd':
508: /* If '-d-opts' don't pass to children */
509: if (argvalue[0] == '-')
510: argvalue++;
511: else {
512: Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
513: Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
514: }
515: parse_debug_options(argvalue);
516: break;
517: case 'e':
1.391 rillig 518: opts.checkEnvFirst = TRUE;
1.354 rillig 519: Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
520: break;
521: case 'f':
1.391 rillig 522: Lst_Append(opts.makefiles, bmake_strdup(argvalue));
1.354 rillig 523: break;
524: case 'i':
1.391 rillig 525: opts.ignoreErrors = TRUE;
1.354 rillig 526: Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
527: break;
528: case 'j':
1.356 rillig 529: MainParseArgJobs(argvalue);
1.354 rillig 530: break;
531: case 'k':
1.391 rillig 532: opts.keepgoing = TRUE;
1.354 rillig 533: Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
534: break;
535: case 'm':
1.357 rillig 536: MainParseArgSysInc(argvalue);
1.354 rillig 537: break;
538: case 'n':
1.391 rillig 539: opts.noExecute = TRUE;
1.354 rillig 540: Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
541: break;
542: case 'q':
1.391 rillig 543: opts.queryFlag = TRUE;
1.354 rillig 544: /* Kind of nonsensical, wot? */
545: Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
546: break;
547: case 'r':
1.391 rillig 548: opts.noBuiltins = TRUE;
1.354 rillig 549: Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
550: break;
551: case 's':
1.391 rillig 552: opts.beSilent = TRUE;
1.354 rillig 553: Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
554: break;
555: case 't':
1.391 rillig 556: opts.touchFlag = TRUE;
1.354 rillig 557: Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
558: break;
559: case 'w':
1.391 rillig 560: opts.enterFlag = TRUE;
1.354 rillig 561: Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
562: break;
563: default:
564: case '?':
565: usage();
566: }
567: return TRUE;
568: }
569:
1.345 rillig 570: /* Parse the given arguments. Called from main() and from
571: * Main_ParseArgLine() when the .MAKEFLAGS target is used.
1.1 cgd 572: *
1.345 rillig 573: * The arguments must be treated as read-only and will be freed after the
574: * call.
1.1 cgd 575: *
1.345 rillig 576: * XXX: Deal with command line overriding .MAKEFLAGS in makefile */
1.1 cgd 577: static void
1.149 christos 578: MainParseArgs(int argc, char **argv)
1.1 cgd 579: {
1.360 rillig 580: char c;
1.98 ross 581: int arginc;
1.133 dsl 582: char *argvalue;
1.98 ross 583: char *optscan;
1.101 ross 584: Boolean inOption, dashDash = FALSE;
1.1 cgd 585:
1.359 rillig 586: const char *optspecs = "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstv:w";
1.98 ross 587: /* Can't actually use getopt(3) because rescanning is not portable */
588:
1.279 rillig 589: rearg:
1.98 ross 590: inOption = FALSE;
1.108 lukem 591: optscan = NULL;
1.358 rillig 592: while (argc > 1) {
1.359 rillig 593: const char *optspec;
1.358 rillig 594: if (!inOption)
1.98 ross 595: optscan = argv[1];
596: c = *optscan++;
597: arginc = 0;
1.358 rillig 598: if (inOption) {
599: if (c == '\0') {
1.98 ross 600: ++argv;
601: --argc;
602: inOption = FALSE;
603: continue;
604: }
605: } else {
1.101 ross 606: if (c != '-' || dashDash)
1.98 ross 607: break;
608: inOption = TRUE;
609: c = *optscan++;
610: }
611: /* '-' found at some earlier point */
1.359 rillig 612: optspec = strchr(optspecs, c);
613: if (c != '\0' && optspec != NULL && optspec[1] == ':') {
1.98 ross 614: /* -<something> found, and <something> should have an arg */
615: inOption = FALSE;
616: arginc = 1;
617: argvalue = optscan;
1.358 rillig 618: if (*argvalue == '\0') {
1.122 christos 619: if (argc < 3)
620: goto noarg;
1.98 ross 621: argvalue = argv[2];
622: arginc = 2;
623: }
1.108 lukem 624: } else {
1.279 rillig 625: argvalue = NULL;
1.98 ross 626: }
1.354 rillig 627: switch (c) {
1.98 ross 628: case '\0':
1.358 rillig 629: arginc = 1;
630: inOption = FALSE;
631: break;
1.101 ross 632: case '-':
1.358 rillig 633: dashDash = TRUE;
634: break;
1.1 cgd 635: default:
1.358 rillig 636: if (!MainParseArg(c, argvalue))
637: goto noarg;
1.1 cgd 638: }
1.98 ross 639: argv += arginc;
640: argc -= arginc;
1.1 cgd 641: }
642:
643: oldVars = TRUE;
644:
645: /*
646: * See if the rest of the arguments are variable assignments and
647: * perform them if so. Else take them to be targets and stuff them
648: * on the end of the "create" list.
649: */
1.369 rillig 650: for (; argc > 1; ++argv, --argc) {
651: VarAssign var;
652: if (Parse_IsVar(argv[1], &var)) {
1.410 rillig 653: Parse_DoVar(&var, VAR_CMDLINE);
1.67 sjg 654: } else {
1.98 ross 655: if (!*argv[1])
1.1 cgd 656: Punt("illegal (null) argument.");
1.101 ross 657: if (*argv[1] == '-' && !dashDash)
1.1 cgd 658: goto rearg;
1.391 rillig 659: Lst_Append(opts.create, bmake_strdup(argv[1]));
1.1 cgd 660: }
1.369 rillig 661: }
1.122 christos 662:
663: return;
664: noarg:
665: (void)fprintf(stderr, "%s: option requires an argument -- %c\n",
666: progname, c);
667: usage();
1.1 cgd 668: }
669:
1.361 rillig 670: /* Break a line of arguments into words and parse them.
1.85 wiz 671: *
1.361 rillig 672: * Used when a .MFLAGS or .MAKEFLAGS target is encountered during parsing and
673: * by main() when reading the MAKEFLAGS environment variable. */
1.1 cgd 674: void
1.161 dsl 675: Main_ParseArgLine(const char *line)
1.1 cgd 676: {
1.331 rillig 677: Words words;
1.412 rillig 678: void *p1;
1.289 rillig 679: const char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
1.296 rillig 680: char *buf;
1.1 cgd 681:
682: if (line == NULL)
683: return;
1.13 cgd 684: for (; *line == ' '; ++line)
685: continue;
1.1 cgd 686: if (!*line)
687: return;
688:
1.303 rillig 689: buf = str_concat3(argv0, " ", line);
1.238 christos 690: free(p1);
1.40 christos 691:
1.331 rillig 692: words = Str_Words(buf, TRUE);
693: if (words.words == NULL) {
1.159 christos 694: Error("Unterminated quoted string [%s]", buf);
695: free(buf);
696: return;
697: }
1.45 itohy 698: free(buf);
1.331 rillig 699: MainParseArgs((int)words.len, words.words);
1.40 christos 700:
1.331 rillig 701: Words_Free(words);
1.1 cgd 702: }
703:
1.74 tv 704: Boolean
1.252 christos 705: Main_SetObjdir(const char *fmt, ...)
1.31 christos 706: {
707: struct stat sb;
1.260 christos 708: char *path;
709: char buf[MAXPATHLEN + 1];
1.265 sjg 710: char buf2[MAXPATHLEN + 1];
1.76 tv 711: Boolean rc = FALSE;
1.252 christos 712: va_list ap;
713:
714: va_start(ap, fmt);
1.260 christos 715: vsnprintf(path = buf, MAXPATHLEN, fmt, ap);
1.252 christos 716: va_end(ap);
1.31 christos 717:
1.74 tv 718: if (path[0] != '/') {
1.263 sjg 719: snprintf(buf2, MAXPATHLEN, "%s/%s", curdir, path);
720: path = buf2;
1.74 tv 721: }
722:
723: /* look for the directory and try to chdir there */
1.31 christos 724: if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
1.420 sjg 725: /* if not .CURDIR it must be writable */
726: if ((strcmp(path, curdir) != 0 && access(path, W_OK) != 0) ||
727: chdir(path)) {
1.31 christos 728: (void)fprintf(stderr, "make warning: %s: %s.\n",
729: path, strerror(errno));
1.74 tv 730: } else {
1.295 rillig 731: snprintf(objdir, sizeof objdir, "%s", path);
1.277 rillig 732: Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
1.74 tv 733: setenv("PWD", objdir, 1);
1.79 tv 734: Dir_InitDot();
1.262 riastrad 735: purge_cached_realpaths();
1.74 tv 736: rc = TRUE;
1.391 rillig 737: if (opts.enterFlag && strcmp(objdir, curdir) != 0)
1.233 sjg 738: enterFlagObj = TRUE;
1.31 christos 739: }
740: }
741:
1.74 tv 742: return rc;
1.31 christos 743: }
744:
1.252 christos 745: static Boolean
1.253 christos 746: Main_SetVarObjdir(const char *var, const char *suffix)
1.252 christos 747: {
1.412 rillig 748: void *path_freeIt;
1.410 rillig 749: const char *path = Var_Value(var, VAR_CMDLINE, &path_freeIt);
1.296 rillig 750: const char *xpath;
751: char *xpath_freeIt;
752:
1.288 rillig 753: if (path == NULL || path[0] == '\0') {
1.290 rillig 754: bmake_free(path_freeIt);
1.252 christos 755: return FALSE;
1.288 rillig 756: }
1.252 christos 757:
1.260 christos 758: /* expand variable substitutions */
1.296 rillig 759: xpath = path;
760: xpath_freeIt = NULL;
1.341 rillig 761: if (strchr(path, '$') != 0) {
762: (void)Var_Subst(path, VAR_GLOBAL, VARE_WANTRES, &xpath_freeIt);
763: /* TODO: handle errors */
764: xpath = xpath_freeIt;
765: }
1.260 christos 766:
767: (void)Main_SetObjdir("%s%s", xpath, suffix);
768:
1.290 rillig 769: bmake_free(xpath_freeIt);
770: bmake_free(path_freeIt);
1.252 christos 771: return TRUE;
772: }
773:
1.325 rillig 774: /* Read and parse the makefile.
1.387 rillig 775: * Return TRUE if reading the makefile succeeded. */
1.386 rillig 776: static int
777: ReadMakefileSucceeded(void *fname, void *unused)
1.325 rillig 778: {
779: return ReadMakefile(fname) == 0;
780: }
781:
1.197 sjg 782: int
1.338 rillig 783: str2Lst_Append(StringList *lp, char *str, const char *sep)
1.176 sjg 784: {
785: char *cp;
786: int n;
787:
788: if (!sep)
789: sep = " \t";
790:
791: for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
1.320 rillig 792: Lst_Append(lp, cp);
1.176 sjg 793: n++;
794: }
1.278 rillig 795: return n;
1.176 sjg 796: }
797:
1.167 christos 798: #ifdef SIGINFO
799: /*ARGSUSED*/
800: static void
1.200 joerg 801: siginfo(int signo MAKE_ATTR_UNUSED)
1.167 christos 802: {
803: char dir[MAXPATHLEN];
804: char str[2 * MAXPATHLEN];
805: int len;
806: if (getcwd(dir, sizeof(dir)) == NULL)
807: return;
1.168 christos 808: len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir);
1.167 christos 809: if (len > 0)
810: (void)write(STDERR_FILENO, str, (size_t)len);
811: }
812: #endif
813:
1.176 sjg 814: /*
815: * Allow makefiles some control over the mode we run in.
816: */
817: void
818: MakeMode(const char *mode)
819: {
1.322 rillig 820: char *mode_freeIt = NULL;
1.176 sjg 821:
1.341 rillig 822: if (mode == NULL) {
823: (void)Var_Subst("${" MAKE_MODE ":tl}",
824: VAR_GLOBAL, VARE_WANTRES, &mode_freeIt);
825: /* TODO: handle errors */
826: mode = mode_freeIt;
827: }
1.176 sjg 828:
1.322 rillig 829: if (mode[0] != '\0') {
1.176 sjg 830: if (strstr(mode, "compat")) {
1.391 rillig 831: opts.compatMake = TRUE;
1.176 sjg 832: forceJobs = FALSE;
833: }
1.190 sjg 834: #if USE_META
835: if (strstr(mode, "meta"))
1.210 sjg 836: meta_mode_init(mode);
1.190 sjg 837: #endif
1.176 sjg 838: }
1.238 christos 839:
1.322 rillig 840: free(mode_freeIt);
1.176 sjg 841: }
842:
1.266 christos 843: static void
1.383 rillig 844: PrintVar(const char *varname, Boolean expandVars)
845: {
846: if (strchr(varname, '$')) {
1.384 rillig 847: char *evalue;
848: (void)Var_Subst(varname, VAR_GLOBAL, VARE_WANTRES, &evalue);
1.383 rillig 849: /* TODO: handle errors */
1.384 rillig 850: printf("%s\n", evalue);
851: bmake_free(evalue);
852:
1.383 rillig 853: } else if (expandVars) {
854: char *expr = str_concat3("${", varname, "}");
1.384 rillig 855: char *evalue;
856: (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &evalue);
1.383 rillig 857: /* TODO: handle errors */
858: free(expr);
1.384 rillig 859: printf("%s\n", evalue);
860: bmake_free(evalue);
861:
1.383 rillig 862: } else {
1.412 rillig 863: void *freeIt;
1.384 rillig 864: const char *value = Var_Value(varname, VAR_GLOBAL, &freeIt);
865: printf("%s\n", value ? value : "");
866: bmake_free(freeIt);
1.383 rillig 867: }
868: }
869:
870: static void
1.266 christos 871: doPrintVars(void)
872: {
1.338 rillig 873: StringListNode *ln;
1.266 christos 874: Boolean expandVars;
875:
1.391 rillig 876: if (opts.printVars == EXPAND_VARS)
1.272 christos 877: expandVars = TRUE;
1.394 rillig 878: else if (opts.debugVflag)
1.266 christos 879: expandVars = FALSE;
880: else
1.272 christos 881: expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
1.266 christos 882:
1.391 rillig 883: for (ln = opts.variables->first; ln != NULL; ln = ln->next) {
1.383 rillig 884: const char *varname = ln->datum;
885: PrintVar(varname, expandVars);
1.266 christos 886: }
887: }
888:
889: static Boolean
890: runTargets(void)
891: {
1.338 rillig 892: GNodeList *targs; /* target nodes to create -- passed to Make_Init */
1.351 rillig 893: Boolean outOfDate; /* FALSE if all targets up to date */
1.266 christos 894:
895: /*
896: * Have now read the entire graph and need to make a list of
897: * targets to create. If none was given on the command line,
898: * we consult the parsing module to find the main target(s)
899: * to create.
900: */
1.391 rillig 901: if (Lst_IsEmpty(opts.create))
1.266 christos 902: targs = Parse_MainName();
903: else
1.391 rillig 904: targs = Targ_FindList(opts.create);
1.266 christos 905:
1.391 rillig 906: if (!opts.compatMake) {
1.266 christos 907: /*
908: * Initialize job module before traversing the graph
909: * now that any .BEGIN and .END targets have been read.
910: * This is done only if the -q flag wasn't given
911: * (to prevent the .BEGIN from being executed should
912: * it exist).
913: */
1.391 rillig 914: if (!opts.queryFlag) {
1.266 christos 915: Job_Init();
916: jobsRunning = TRUE;
917: }
918:
919: /* Traverse the graph, checking on all the targets */
920: outOfDate = Make_Run(targs);
921: } else {
922: /*
923: * Compat_Init will take care of creating all the
924: * targets as well as initializing the module.
925: */
926: Compat_Run(targs);
927: outOfDate = FALSE;
928: }
1.320 rillig 929: Lst_Free(targs);
1.266 christos 930: return outOfDate;
931: }
932:
1.343 rillig 933: /*
934: * Set up the .TARGETS variable to contain the list of targets to be
935: * created. If none specified, make the variable empty -- the parser
936: * will fill the thing in with the default or .MAIN target.
937: */
938: static void
939: InitVarTargets(void)
940: {
941: StringListNode *ln;
942:
1.391 rillig 943: if (Lst_IsEmpty(opts.create)) {
1.343 rillig 944: Var_Set(".TARGETS", "", VAR_GLOBAL);
945: return;
946: }
947:
1.391 rillig 948: for (ln = opts.create->first; ln != NULL; ln = ln->next) {
1.343 rillig 949: char *name = ln->datum;
950: Var_Append(".TARGETS", name, VAR_GLOBAL);
951: }
952: }
953:
1.404 rillig 954: static void
955: InitRandom(void)
956: {
957: struct timeval tv;
958:
959: gettimeofday(&tv, NULL);
960: srandom((unsigned int)(tv.tv_sec + tv.tv_usec));
961: }
962:
1.369 rillig 963: static const char *
964: init_machine(const struct utsname *utsname)
965: {
966: const char *machine = getenv("MACHINE");
967: if (machine != NULL)
968: return machine;
969:
970: #ifdef MAKE_NATIVE
971: return utsname->machine;
972: #else
973: #ifdef MAKE_MACHINE
974: return MAKE_MACHINE;
975: #else
976: return "unknown";
977: #endif
978: #endif
979: }
980:
981: static const char *
982: init_machine_arch(void)
983: {
984: const char *env = getenv("MACHINE_ARCH");
985: if (env != NULL)
986: return env;
987:
988: #ifdef MAKE_NATIVE
989: {
990: struct utsname utsname;
991: static char machine_arch_buf[sizeof(utsname.machine)];
992: const int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
993: size_t len = sizeof(machine_arch_buf);
994:
995: if (sysctl(mib, __arraycount(mib), machine_arch_buf,
996: &len, NULL, 0) < 0) {
997: (void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname,
998: strerror(errno));
999: exit(2);
1000: }
1001:
1002: return machine_arch_buf;
1003: }
1004: #else
1005: #ifndef MACHINE_ARCH
1006: #ifdef MAKE_MACHINE_ARCH
1007: return MAKE_MACHINE_ARCH;
1008: #else
1009: return "unknown";
1010: #endif
1011: #else
1012: return MACHINE_ARCH;
1013: #endif
1014: #endif
1015: }
1016:
1.381 rillig 1017: #ifndef NO_PWD_OVERRIDE
1018: /*
1019: * All this code is so that we know where we are when we start up
1020: * on a different machine with pmake.
1.382 rillig 1021: *
1.381 rillig 1022: * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
1023: * since the value of curdir can vary depending on how we got
1024: * here. Ie sitting at a shell prompt (shell that provides $PWD)
1025: * or via subdir.mk in which case its likely a shell which does
1026: * not provide it.
1.382 rillig 1027: *
1.381 rillig 1028: * So, to stop it breaking this case only, we ignore PWD if
1.382 rillig 1029: * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a variable expression.
1.381 rillig 1030: */
1031: static void
1.382 rillig 1032: HandlePWD(const struct stat *curdir_st)
1.381 rillig 1033: {
1.382 rillig 1034: char *pwd;
1.412 rillig 1035: void *prefix_freeIt, *makeobjdir_freeIt;
1.382 rillig 1036: const char *makeobjdir;
1037: struct stat pwd_st;
1.381 rillig 1038:
1039: if (ignorePWD || (pwd = getenv("PWD")) == NULL)
1040: return;
1041:
1.410 rillig 1042: if (Var_Value("MAKEOBJDIRPREFIX", VAR_CMDLINE, &prefix_freeIt) != NULL) {
1.382 rillig 1043: bmake_free(prefix_freeIt);
1044: return;
1.381 rillig 1045: }
1.382 rillig 1046:
1.410 rillig 1047: makeobjdir = Var_Value("MAKEOBJDIR", VAR_CMDLINE, &makeobjdir_freeIt);
1.382 rillig 1048: if (makeobjdir != NULL && strchr(makeobjdir, '$') != NULL)
1049: goto ignore_pwd;
1050:
1051: if (stat(pwd, &pwd_st) == 0 &&
1052: curdir_st->st_ino == pwd_st.st_ino &&
1053: curdir_st->st_dev == pwd_st.st_dev)
1054: (void)strncpy(curdir, pwd, MAXPATHLEN);
1055:
1056: ignore_pwd:
1057: bmake_free(makeobjdir_freeIt);
1.381 rillig 1058: }
1059: #endif
1060:
1.407 rillig 1061: /*
1062: * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that,
1063: * MAKEOBJDIR is set in the environment, try only that value
1064: * and fall back to .CURDIR if it does not exist.
1065: *
1066: * Otherwise, try _PATH_OBJDIR.MACHINE-MACHINE_ARCH, _PATH_OBJDIR.MACHINE,
1067: * and * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
1068: * of these paths exist, just use .CURDIR.
1069: */
1070: static void
1071: InitObjdir(const char *machine, const char *machine_arch)
1072: {
1073: Dir_InitDir(curdir);
1074: (void)Main_SetObjdir("%s", curdir);
1075:
1076: if (!Main_SetVarObjdir("MAKEOBJDIRPREFIX", curdir) &&
1077: !Main_SetVarObjdir("MAKEOBJDIR", "") &&
1078: !Main_SetObjdir("%s.%s-%s", _PATH_OBJDIR, machine, machine_arch) &&
1079: !Main_SetObjdir("%s.%s", _PATH_OBJDIR, machine) &&
1080: !Main_SetObjdir("%s", _PATH_OBJDIR))
1081: (void)Main_SetObjdir("%s%s", _PATH_OBJDIRPREFIX, curdir);
1082: }
1083:
1.393 rillig 1084: /* get rid of resource limit on file descriptors */
1085: static void
1086: UnlimitFiles(void)
1087: {
1088: #if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
1089: struct rlimit rl;
1090: if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
1091: rl.rlim_cur != rl.rlim_max) {
1092: rl.rlim_cur = rl.rlim_max;
1093: (void)setrlimit(RLIMIT_NOFILE, &rl);
1094: }
1095: #endif
1096: }
1097:
1.395 rillig 1098: static void
1099: CmdOpts_Init(void)
1100: {
1101: opts.compatMake = FALSE; /* No compat mode */
1102: opts.debug = 0; /* No debug verbosity, please. */
1103: /* opts.debug_file has been initialized earlier */
1104: opts.debugVflag = FALSE;
1.396 rillig 1105: opts.checkEnvFirst = FALSE;
1.395 rillig 1106: opts.makefiles = Lst_New();
1107: opts.ignoreErrors = FALSE; /* Pay attention to non-zero returns */
1108: opts.maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */
1109: opts.keepgoing = FALSE; /* Stop on error */
1110: opts.noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
1111: opts.noExecute = FALSE; /* Execute all commands */
1112: opts.queryFlag = FALSE; /* This is not just a check-run */
1113: opts.noBuiltins = FALSE; /* Read the built-in rules */
1114: opts.beSilent = FALSE; /* Print commands as executed */
1115: opts.touchFlag = FALSE; /* Actually update targets */
1116: opts.printVars = 0;
1117: opts.variables = Lst_New();
1.396 rillig 1118: opts.parseWarnFatal = FALSE;
1119: opts.enterFlag = FALSE;
1120: opts.varNoExportEnv = FALSE;
1.395 rillig 1121: opts.create = Lst_New();
1122: }
1123:
1.406 rillig 1124: /* Initialize MAKE and .MAKE to the path of the executable, so that it can be
1125: * found by execvp(3) and the shells, even after a chdir.
1126: *
1127: * If it's a relative path and contains a '/', resolve it to an absolute path.
1128: * Otherwise keep it as is, assuming it will be found in the PATH. */
1.397 rillig 1129: static void
1.406 rillig 1130: InitVarMake(const char *argv0)
1.405 rillig 1131: {
1.406 rillig 1132: const char *make = argv0;
1.405 rillig 1133:
1.406 rillig 1134: if (argv0[0] != '/' && strchr(argv0, '/') != NULL) {
1135: char pathbuf[MAXPATHLEN];
1136: const char *abs = cached_realpath(argv0, pathbuf);
1137: struct stat st;
1138: if (abs != NULL && abs[0] == '/' && stat(make, &st) == 0)
1139: make = abs;
1.405 rillig 1140: }
1.406 rillig 1141:
1142: Var_Set("MAKE", make, VAR_GLOBAL);
1143: Var_Set(".MAKE", make, VAR_GLOBAL);
1.405 rillig 1144: }
1145:
1146: static void
1.409 rillig 1147: InitDefSysIncPath(char *syspath)
1.397 rillig 1148: {
1149: static char defsyspath[] = _PATH_DEFSYSPATH;
1150: char *start, *cp;
1151:
1152: /*
1153: * If no user-supplied system path was given (through the -m option)
1154: * add the directories from the DEFSYSPATH (more than one may be given
1155: * as dir1:...:dirn) to the system include path.
1156: */
1157: /* XXX: mismatch: the -m option sets sysIncPath, not syspath */
1158: if (syspath == NULL || syspath[0] == '\0')
1159: syspath = defsyspath;
1160: else
1161: syspath = bmake_strdup(syspath);
1162:
1163: for (start = syspath; *start != '\0'; start = cp) {
1164: for (cp = start; *cp != '\0' && *cp != ':'; cp++)
1165: continue;
1166: if (*cp == ':') {
1167: *cp++ = '\0';
1168: }
1169: /* look for magic parent directory search string */
1170: if (strncmp(".../", start, 4) != 0) {
1.409 rillig 1171: (void)Dir_AddDir(defSysIncPath, start);
1.397 rillig 1172: } else {
1173: char *dir = Dir_FindHereOrAbove(curdir, start + 4);
1174: if (dir != NULL) {
1.409 rillig 1175: (void)Dir_AddDir(defSysIncPath, dir);
1.397 rillig 1176: free(dir);
1177: }
1178: }
1179: }
1180:
1181: if (syspath != defsyspath)
1182: free(syspath);
1183: }
1184:
1.398 rillig 1185: static void
1186: ReadBuiltinRules(void)
1187: {
1188: StringList *sysMkPath = Lst_New();
1189: Dir_Expand(_PATH_DEFSYSMK,
1.409 rillig 1190: Lst_IsEmpty(sysIncPath) ? defSysIncPath : sysIncPath,
1.398 rillig 1191: sysMkPath);
1192: if (Lst_IsEmpty(sysMkPath))
1193: Fatal("%s: no system rules (%s).", progname, _PATH_DEFSYSMK);
1194: if (!Lst_ForEachUntil(sysMkPath, ReadMakefileSucceeded, NULL))
1195: Fatal("%s: cannot open %s.", progname,
1196: (char *)sysMkPath->first->datum);
1197: /* XXX: sysMkPath is not freed */
1198: }
1199:
1.408 rillig 1200: static void
1201: InitMaxJobs(void)
1202: {
1203: char *value;
1204: int n;
1205:
1206: if (forceJobs || opts.compatMake ||
1207: !Var_Exists(".MAKE.JOBS", VAR_GLOBAL))
1208: return;
1209:
1210: (void)Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES, &value);
1211: /* TODO: handle errors */
1212: n = (int)strtol(value, NULL, 0);
1213: if (n < 1) {
1214: (void)fprintf(stderr,
1215: "%s: illegal value for .MAKE.JOBS "
1216: "-- must be positive integer!\n",
1217: progname);
1218: exit(1);
1219: }
1220:
1221: if (n != opts.maxJobs) {
1222: Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
1223: Var_Append(MAKEFLAGS, value, VAR_GLOBAL);
1224: }
1225:
1226: opts.maxJobs = n;
1227: maxJobTokens = opts.maxJobs;
1228: forceJobs = TRUE;
1229: free(value);
1230: }
1231:
1.400 rillig 1232: /*
1233: * For compatibility, look at the directories in the VPATH variable
1234: * and add them to the search path, if the variable is defined. The
1235: * variable's value is in the same format as the PATH environment
1236: * variable, i.e. <directory>:<directory>:<directory>...
1237: */
1238: static void
1239: InitVpath(void)
1240: {
1241: char *vpath, savec, *path;
1.410 rillig 1242: if (!Var_Exists("VPATH", VAR_CMDLINE))
1.400 rillig 1243: return;
1244:
1.410 rillig 1245: (void)Var_Subst("${VPATH}", VAR_CMDLINE, VARE_WANTRES, &vpath);
1.400 rillig 1246: /* TODO: handle errors */
1247: path = vpath;
1248: do {
1249: char *cp;
1250: /* skip to end of directory */
1251: for (cp = path; *cp != ':' && *cp != '\0'; cp++)
1252: continue;
1253: /* Save terminator character so know when to stop */
1254: savec = *cp;
1255: *cp = '\0';
1256: /* Add directory to search path */
1257: (void)Dir_AddDir(dirSearchPath, path);
1258: *cp = savec;
1259: path = cp + 1;
1260: } while (savec == ':');
1261: free(vpath);
1262: }
1263:
1.402 rillig 1264: static void
1.403 rillig 1265: ReadMakefiles(void)
1266: {
1267: if (opts.makefiles->first != NULL) {
1268: StringListNode *ln;
1269:
1270: for (ln = opts.makefiles->first; ln != NULL; ln = ln->next) {
1271: if (ReadMakefile(ln->datum) != 0)
1272: Fatal("%s: cannot open %s.",
1273: progname, (char *)ln->datum);
1274: }
1275: } else {
1276: char *p1;
1277: (void)Var_Subst("${" MAKEFILE_PREFERENCE "}",
1.410 rillig 1278: VAR_CMDLINE, VARE_WANTRES, &p1);
1.403 rillig 1279: /* TODO: handle errors */
1280: (void)str2Lst_Append(opts.makefiles, p1, NULL);
1281: (void)Lst_ForEachUntil(opts.makefiles,
1282: ReadMakefileSucceeded, NULL);
1283: free(p1);
1284: }
1285: }
1286:
1287: static void
1.402 rillig 1288: CleanUp(void)
1289: {
1290: #ifdef CLEANUP
1291: Lst_Destroy(opts.variables, free);
1292: Lst_Free(opts.makefiles); /* don't free, may be used in GNodes */
1293: Lst_Destroy(opts.create, free);
1294: #endif
1295:
1296: /* print the graph now it's been processed if the user requested it */
1297: if (DEBUG(GRAPH2))
1298: Targ_PrintGraph(2);
1299:
1300: Trace_Log(MAKEEND, 0);
1301:
1302: if (enterFlagObj)
1303: printf("%s: Leaving directory `%s'\n", progname, objdir);
1304: if (opts.enterFlag)
1305: printf("%s: Leaving directory `%s'\n", progname, curdir);
1306:
1307: #ifdef USE_META
1308: meta_finish();
1309: #endif
1310: Suff_End();
1311: Targ_End();
1312: Arch_End();
1313: Var_End();
1314: Parse_End();
1315: Dir_End();
1316: Job_End();
1317: Trace_End();
1318: }
1319:
1.1 cgd 1320: /*-
1321: * main --
1322: * The main function, for obvious reasons. Initializes variables
1323: * and a few modules, then parses the arguments give it in the
1324: * environment and on the command line. Reads the system makefile
1325: * followed by either Makefile, makefile or the file given by the
1326: * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
1327: * flags it has received by then uses either the Make or the Compat
1328: * module to create the initial list of targets.
1329: *
1330: * Results:
1331: * If -q was given, exits -1 if anything was out-of-date. Else it exits
1332: * 0.
1333: *
1334: * Side Effects:
1335: * The program exits when done. Targets are created. etc. etc. etc.
1336: */
1.13 cgd 1337: int
1.85 wiz 1338: main(int argc, char **argv)
1.1 cgd 1339: {
1.351 rillig 1340: Boolean outOfDate; /* FALSE if all targets up to date */
1.381 rillig 1341: struct stat sa;
1.369 rillig 1342: const char *machine;
1343: const char *machine_arch;
1.55 sjg 1344: char *syspath = getenv("MAKESYSPATH");
1.119 tsutsui 1345: struct utsname utsname;
1.107 sjg 1346:
1.154 apb 1347: /* default to writing debug to stderr */
1.391 rillig 1348: opts.debug_file = stderr;
1.133 dsl 1349:
1.167 christos 1350: #ifdef SIGINFO
1.188 sjg 1351: (void)bmake_signal(SIGINFO, siginfo);
1.167 christos 1352: #endif
1.404 rillig 1353:
1354: InitRandom();
1.277 rillig 1355:
1.53 christos 1356: if ((progname = strrchr(argv[0], '/')) != NULL)
1357: progname++;
1358: else
1359: progname = argv[0];
1.393 rillig 1360:
1361: UnlimitFiles();
1.13 cgd 1362:
1.206 christos 1363: if (uname(&utsname) == -1) {
1364: (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
1365: strerror(errno));
1366: exit(2);
1367: }
1368:
1.17 gwr 1369: /*
1370: * Get the name of this type of MACHINE from utsname
1371: * so we can share an executable for similar machines.
1372: * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
1373: *
1.33 christos 1374: * Note that both MACHINE and MACHINE_ARCH are decided at
1375: * run-time.
1.17 gwr 1376: */
1.369 rillig 1377: machine = init_machine(&utsname);
1378: machine_arch = init_machine_arch();
1.33 christos 1379:
1.183 sjg 1380: myPid = getpid(); /* remember this for vFork() */
1381:
1.1 cgd 1382: /*
1.51 sjg 1383: * Just in case MAKEOBJDIR wants us to do something tricky.
1384: */
1385: Var_Init(); /* Initialize the lists of variables for
1386: * parsing arguments */
1.277 rillig 1387: Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL);
1388: Var_Set("MACHINE", machine, VAR_GLOBAL);
1389: Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
1.170 perry 1390: #ifdef MAKE_VERSION
1.277 rillig 1391: Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
1.170 perry 1392: #endif
1.277 rillig 1393: Var_Set(".newline", "\n", VAR_GLOBAL); /* handy for :@ loops */
1.176 sjg 1394: /*
1395: * This is the traditional preference for makefiles.
1396: */
1397: #ifndef MAKEFILE_PREFERENCE_LIST
1398: # define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
1399: #endif
1400: Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
1.277 rillig 1401: VAR_GLOBAL);
1402: Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL);
1.51 sjg 1403:
1.395 rillig 1404: CmdOpts_Init();
1.1 cgd 1405: allPrecious = FALSE; /* Remove targets when interrupted */
1.251 dholland 1406: deleteOnError = FALSE; /* Historical default behavior */
1.1 cgd 1407: jobsRunning = FALSE;
1408:
1.391 rillig 1409: maxJobTokens = opts.maxJobs;
1.174 sjg 1410: ignorePWD = FALSE;
1.13 cgd 1411:
1.1 cgd 1412: /*
1413: * Initialize the parsing, directory and variable modules to prepare
1414: * for the reading of inclusion paths and variable settings on the
1415: * command line
1416: */
1.36 gwr 1417:
1418: /*
1.1 cgd 1419: * Initialize various variables.
1420: * MAKE also gets this name, for compatibility
1421: * .MAKEFLAGS gets set to the empty string just in case.
1422: * MFLAGS also gets initialized empty, for compatibility.
1423: */
1.79 tv 1424: Parse_Init();
1.406 rillig 1425: InitVarMake(argv[0]);
1.277 rillig 1426: Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
1427: Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL);
1428: Var_Set("MFLAGS", "", VAR_GLOBAL);
1429: Var_Set(".ALLTARGETS", "", VAR_GLOBAL);
1.217 sjg 1430: /* some makefiles need to know this */
1.410 rillig 1431: Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMDLINE);
1.1 cgd 1432:
1433: /*
1.142 sjg 1434: * Set some other useful macros
1435: */
1436: {
1.213 christos 1437: char tmp[64], *ep;
1.142 sjg 1438:
1.220 christos 1439: makelevel = ((ep = getenv(MAKE_LEVEL_ENV)) && *ep) ? atoi(ep) : 0;
1440: if (makelevel < 0)
1441: makelevel = 0;
1442: snprintf(tmp, sizeof(tmp), "%d", makelevel);
1.277 rillig 1443: Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL);
1.183 sjg 1444: snprintf(tmp, sizeof(tmp), "%u", myPid);
1.277 rillig 1445: Var_Set(".MAKE.PID", tmp, VAR_GLOBAL);
1.149 christos 1446: snprintf(tmp, sizeof(tmp), "%u", getppid());
1.277 rillig 1447: Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL);
1.142 sjg 1448: }
1.220 christos 1449: if (makelevel > 0) {
1450: char pn[1024];
1451: snprintf(pn, sizeof(pn), "%s[%d]", progname, makelevel);
1.221 christos 1452: progname = bmake_strdup(pn);
1.220 christos 1453: }
1.142 sjg 1454:
1.210 sjg 1455: #ifdef USE_META
1456: meta_init();
1457: #endif
1.306 rillig 1458: Dir_Init();
1.255 sjg 1459:
1.142 sjg 1460: /*
1.1 cgd 1461: * First snag any flags out of the MAKE environment variable.
1462: * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
1463: * in a different format).
1464: */
1465: #ifdef POSIX
1.412 rillig 1466: {
1467: char *p1 = explode(getenv("MAKEFLAGS"));
1468: Main_ParseArgLine(p1);
1469: free(p1);
1470: }
1.1 cgd 1471: #else
1472: Main_ParseArgLine(getenv("MAKE"));
1473: #endif
1.31 christos 1474:
1.1 cgd 1475: /*
1.175 sjg 1476: * Find where we are (now).
1477: * We take care of PWD for the automounter below...
1.174 sjg 1478: */
1479: if (getcwd(curdir, MAXPATHLEN) == NULL) {
1.194 dholland 1480: (void)fprintf(stderr, "%s: getcwd: %s.\n",
1481: progname, strerror(errno));
1.174 sjg 1482: exit(2);
1483: }
1484:
1.175 sjg 1485: MainParseArgs(argc, argv);
1486:
1.391 rillig 1487: if (opts.enterFlag)
1.220 christos 1488: printf("%s: Entering directory `%s'\n", progname, curdir);
1489:
1.175 sjg 1490: /*
1491: * Verify that cwd is sane.
1492: */
1.174 sjg 1493: if (stat(curdir, &sa) == -1) {
1494: (void)fprintf(stderr, "%s: %s: %s.\n",
1495: progname, curdir, strerror(errno));
1496: exit(2);
1497: }
1498:
1.222 sjg 1499: #ifndef NO_PWD_OVERRIDE
1.381 rillig 1500: HandlePWD(&sa);
1.222 sjg 1501: #endif
1.277 rillig 1502: Var_Set(".CURDIR", curdir, VAR_GLOBAL);
1.174 sjg 1503:
1.407 rillig 1504: InitObjdir(machine, machine_arch);
1.174 sjg 1505:
1506: /*
1.1 cgd 1507: * Initialize archive, target and suffix modules in preparation for
1508: * parsing the makefile(s)
1509: */
1510: Arch_Init();
1511: Targ_Init();
1512: Suff_Init();
1.58 sommerfe 1513: Trace_Init(tracefile);
1.1 cgd 1514:
1.157 dsl 1515: DEFAULT = NULL;
1.1 cgd 1516: (void)time(&now);
1517:
1.58 sommerfe 1518: Trace_Log(MAKESTART, NULL);
1.279 rillig 1519:
1.343 rillig 1520: InitVarTargets();
1.25 christos 1521:
1.409 rillig 1522: InitDefSysIncPath(syspath);
1.25 christos 1523:
1524: /*
1525: * Read in the built-in rules first, followed by the specified
1.325 rillig 1526: * makefiles, or the default makefile and Makefile, in that order,
1527: * if no makefiles were given on the command line.
1.25 christos 1528: */
1.398 rillig 1529: if (!opts.noBuiltins)
1530: ReadBuiltinRules();
1.403 rillig 1531: ReadMakefiles();
1532:
1.138 dsl 1533: /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
1.391 rillig 1534: if (!opts.noBuiltins || !opts.printVars) {
1.389 sjg 1535: /* ignore /dev/null and anything starting with "no" */
1536: (void)Var_Subst("${.MAKE.DEPENDFILE:N/dev/null:Nno*:T}",
1.410 rillig 1537: VAR_CMDLINE, VARE_WANTRES, &makeDependfile);
1.389 sjg 1538: if (makeDependfile[0] != '\0') {
1539: /* TODO: handle errors */
1540: doing_depend = TRUE;
1541: (void)ReadMakefile(makeDependfile);
1542: doing_depend = FALSE;
1543: }
1.145 dsl 1544: }
1.1 cgd 1545:
1.233 sjg 1546: if (enterFlagObj)
1547: printf("%s: Entering directory `%s'\n", progname, objdir);
1.279 rillig 1548:
1.176 sjg 1549: MakeMode(NULL);
1550:
1.412 rillig 1551: {
1552: void *freeIt;
1553: Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &freeIt),
1554: VAR_GLOBAL);
1555: bmake_free(freeIt);
1556:
1557: }
1.1 cgd 1558:
1.408 rillig 1559: InitMaxJobs();
1.243 matthias 1560:
1561: /*
1562: * Be compatible if user did not specify -j and did not explicitly
1563: * turned compatibility on
1564: */
1.391 rillig 1565: if (!opts.compatMake && !forceJobs) {
1566: opts.compatMake = TRUE;
1.243 matthias 1567: }
1568:
1.391 rillig 1569: if (!opts.compatMake)
1.132 dsl 1570: Job_ServerStart(maxJobTokens, jp_0, jp_1);
1.352 rillig 1571: DEBUG5(JOB, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
1.391 rillig 1572: jp_0, jp_1, opts.maxJobs, maxJobTokens, opts.compatMake ? 1 : 0);
1.58 sommerfe 1573:
1.391 rillig 1574: if (!opts.printVars)
1.255 sjg 1575: Main_ExportMAKEFLAGS(TRUE); /* initial export */
1.279 rillig 1576:
1.400 rillig 1577: InitVpath();
1.1 cgd 1578:
1579: /*
1580: * Now that all search paths have been read for suffixes et al, it's
1581: * time to add the default search path to their lists...
1582: */
1583: Suff_DoPaths();
1.50 mycroft 1584:
1585: /*
1586: * Propagate attributes through :: dependency lists.
1587: */
1588: Targ_Propagate();
1.1 cgd 1589:
1590: /* print the initial graph, if the user requested it */
1591: if (DEBUG(GRAPH1))
1592: Targ_PrintGraph(1);
1593:
1.31 christos 1594: /* print the values of any variables requested by the user */
1.391 rillig 1595: if (opts.printVars) {
1.266 christos 1596: doPrintVars();
1597: outOfDate = FALSE;
1.138 dsl 1598: } else {
1.266 christos 1599: outOfDate = runTargets();
1.31 christos 1600: }
1601:
1.402 rillig 1602: CleanUp();
1.14 jtc 1603:
1.421 ! rillig 1604: if (DEBUG(LINT) && (errors > 0 || Parse_GetFatals() > 0))
! 1605: return 2; /* Not 1 so -q can distinguish error */
1.137 dsl 1606: return outOfDate ? 1 : 0;
1.1 cgd 1607: }
1608:
1.321 rillig 1609: /* Open and parse the given makefile, with all its side effects.
1.1 cgd 1610: *
1611: * Results:
1.124 sjg 1612: * 0 if ok. -1 if couldn't open file.
1.1 cgd 1613: */
1.124 sjg 1614: static int
1.325 rillig 1615: ReadMakefile(const char *fname)
1.1 cgd 1616: {
1.140 dsl 1617: int fd;
1.304 rillig 1618: char *name, *path = NULL;
1.1 cgd 1619:
1620: if (!strcmp(fname, "-")) {
1.193 dholland 1621: Parse_File(NULL /*stdin*/, -1);
1.277 rillig 1622: Var_Set("MAKEFILE", "", VAR_INTERNAL);
1.1 cgd 1623: } else {
1624: /* if we've chdir'd, rebuild the path name */
1.74 tv 1625: if (strcmp(curdir, objdir) && *fname != '/') {
1.304 rillig 1626: path = str_concat3(curdir, "/", fname);
1.140 dsl 1627: fd = open(path, O_RDONLY);
1628: if (fd != -1) {
1.1 cgd 1629: fname = path;
1630: goto found;
1631: }
1.309 rillig 1632: free(path);
1.279 rillig 1633:
1.95 jmc 1634: /* If curdir failed, try objdir (ala .depend) */
1.304 rillig 1635: path = str_concat3(objdir, "/", fname);
1.140 dsl 1636: fd = open(path, O_RDONLY);
1637: if (fd != -1) {
1.95 jmc 1638: fname = path;
1639: goto found;
1640: }
1.140 dsl 1641: } else {
1642: fd = open(fname, O_RDONLY);
1643: if (fd != -1)
1644: goto found;
1645: }
1.1 cgd 1646: /* look in -I and system include directories. */
1647: name = Dir_FindFile(fname, parseIncPath);
1.409 rillig 1648: if (!name) {
1649: SearchPath *sysInc = Lst_IsEmpty(sysIncPath)
1650: ? defSysIncPath : sysIncPath;
1651: name = Dir_FindFile(fname, sysInc);
1652: }
1.140 dsl 1653: if (!name || (fd = open(name, O_RDONLY)) == -1) {
1.238 christos 1654: free(name);
1.48 christos 1655: free(path);
1.278 rillig 1656: return -1;
1.48 christos 1657: }
1.1 cgd 1658: fname = name;
1659: /*
1660: * set the MAKEFILE variable desired by System V fans -- the
1661: * placement of the setting here means it gets set to the last
1662: * makefile specified, as it is set by SysV make.
1663: */
1.67 sjg 1664: found:
1.176 sjg 1665: if (!doing_depend)
1.277 rillig 1666: Var_Set("MAKEFILE", fname, VAR_INTERNAL);
1.140 dsl 1667: Parse_File(fname, fd);
1.1 cgd 1668: }
1.48 christos 1669: free(path);
1.278 rillig 1670: return 0;
1.54 sjg 1671: }
1672:
1673:
1.29 christos 1674:
1675: /*-
1676: * Cmd_Exec --
1677: * Execute the command in cmd, and return the output of that command
1.302 rillig 1678: * in a string. In the output, newlines are replaced with spaces.
1.29 christos 1679: *
1680: * Results:
1.293 rillig 1681: * A string containing the output of the command, or the empty string.
1682: * *errfmt returns a format string describing the command failure,
1683: * if any, using a single %s conversion specification.
1.29 christos 1684: *
1685: * Side Effects:
1686: * The string must be freed by the caller.
1687: */
1688: char *
1.293 rillig 1689: Cmd_Exec(const char *cmd, const char **errfmt)
1.29 christos 1690: {
1.351 rillig 1691: const char *args[4]; /* Args for invoking the shell */
1692: int fds[2]; /* Pipe streams */
1693: int cpid; /* Child PID */
1694: int pid; /* PID from wait() */
1.29 christos 1695: int status; /* command exit status */
1696: Buffer buf; /* buffer to store the result */
1.298 rillig 1697: ssize_t bytes_read;
1698: char *res; /* result */
1699: size_t res_len;
1.29 christos 1700: char *cp;
1.231 dholland 1701: int savederr; /* saved errno */
1.29 christos 1702:
1.293 rillig 1703: *errfmt = NULL;
1.29 christos 1704:
1.90 sjg 1705: if (!shellName)
1706: Shell_Init();
1.29 christos 1707: /*
1708: * Set up arguments for shell
1709: */
1.90 sjg 1710: args[0] = shellName;
1.29 christos 1711: args[1] = "-c";
1712: args[2] = cmd;
1713: args[3] = NULL;
1714:
1715: /*
1716: * Open a pipe for fetching its output
1717: */
1718: if (pipe(fds) == -1) {
1.293 rillig 1719: *errfmt = "Couldn't create pipe for \"%s\"";
1.29 christos 1720: goto bad;
1721: }
1722:
1723: /*
1724: * Fork
1725: */
1.183 sjg 1726: switch (cpid = vFork()) {
1.29 christos 1727: case 0:
1728: /*
1729: * Close input side of pipe
1730: */
1.112 christos 1731: (void)close(fds[0]);
1.29 christos 1732:
1733: /*
1734: * Duplicate the output stream to the shell's output, then
1735: * shut the extra thing down. Note we don't fetch the error
1736: * stream...why not? Why?
1737: */
1.112 christos 1738: (void)dup2(fds[1], 1);
1739: (void)close(fds[1]);
1.31 christos 1740:
1.143 sjg 1741: Var_ExportVars();
1742:
1.112 christos 1743: (void)execv(shellPath, UNCONST(args));
1.29 christos 1744: _exit(1);
1745: /*NOTREACHED*/
1746:
1747: case -1:
1.293 rillig 1748: *errfmt = "Couldn't exec \"%s\"";
1.29 christos 1749: goto bad;
1750:
1751: default:
1752: /*
1753: * No need for the writing half
1754: */
1.112 christos 1755: (void)close(fds[1]);
1.31 christos 1756:
1.232 sjg 1757: savederr = 0;
1.297 rillig 1758: Buf_Init(&buf, 0);
1.29 christos 1759:
1760: do {
1761: char result[BUFSIZ];
1.298 rillig 1762: bytes_read = read(fds[0], result, sizeof(result));
1763: if (bytes_read > 0)
1764: Buf_AddBytes(&buf, result, (size_t)bytes_read);
1.29 christos 1765: }
1.298 rillig 1766: while (bytes_read > 0 || (bytes_read == -1 && errno == EINTR));
1767: if (bytes_read == -1)
1.231 dholland 1768: savederr = errno;
1.29 christos 1769:
1770: /*
1771: * Close the input side of the pipe.
1772: */
1.112 christos 1773: (void)close(fds[0]);
1.29 christos 1774:
1775: /*
1776: * Wait for the process to exit.
1777: */
1.189 sjg 1778: while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) {
1779: JobReapChild(pid, status, FALSE);
1.29 christos 1780: continue;
1.189 sjg 1781: }
1.350 rillig 1782: res_len = Buf_Len(&buf);
1.163 dsl 1783: res = Buf_Destroy(&buf, FALSE);
1.29 christos 1784:
1.231 dholland 1785: if (savederr != 0)
1.293 rillig 1786: *errfmt = "Couldn't read shell's output for \"%s\"";
1.29 christos 1787:
1.172 dholland 1788: if (WIFSIGNALED(status))
1.293 rillig 1789: *errfmt = "\"%s\" exited on a signal";
1.172 dholland 1790: else if (WEXITSTATUS(status) != 0)
1.293 rillig 1791: *errfmt = "\"%s\" returned non-zero status";
1.29 christos 1792:
1.299 rillig 1793: /* Convert newlines to spaces. A final newline is just stripped */
1.300 rillig 1794: if (res_len > 0 && res[res_len - 1] == '\n')
1795: res[res_len - 1] = '\0';
1796: for (cp = res; *cp != '\0'; cp++)
1.299 rillig 1797: if (*cp == '\n')
1.29 christos 1798: *cp = ' ';
1799: break;
1800: }
1801: return res;
1802: bad:
1.293 rillig 1803: return bmake_strdup("");
1.1 cgd 1804: }
1805:
1.369 rillig 1806: /* Print a printf-style error message.
1.1 cgd 1807: *
1.369 rillig 1808: * This error message has no consequences, in particular it does not affect
1809: * the exit status. */
1.1 cgd 1810: void
1.89 christos 1811: Error(const char *fmt, ...)
1.1 cgd 1812: {
1813: va_list ap;
1.162 dsl 1814: FILE *err_file;
1.85 wiz 1815:
1.391 rillig 1816: err_file = opts.debug_file;
1.162 dsl 1817: if (err_file == stdout)
1818: err_file = stderr;
1.184 sjg 1819: (void)fflush(stdout);
1.162 dsl 1820: for (;;) {
1821: va_start(ap, fmt);
1822: fprintf(err_file, "%s: ", progname);
1823: (void)vfprintf(err_file, fmt, ap);
1824: va_end(ap);
1825: (void)fprintf(err_file, "\n");
1826: (void)fflush(err_file);
1827: if (err_file == stderr)
1828: break;
1829: err_file = stderr;
1830: }
1.421 ! rillig 1831: errors++;
1.1 cgd 1832: }
1833:
1.334 rillig 1834: /* Produce a Fatal error message, then exit immediately.
1.1 cgd 1835: *
1.418 rillig 1836: * If jobs are running, wait for them to finish. */
1.1 cgd 1837: void
1.89 christos 1838: Fatal(const char *fmt, ...)
1.1 cgd 1839: {
1840: va_list ap;
1.85 wiz 1841:
1.13 cgd 1842: va_start(ap, fmt);
1.1 cgd 1843: if (jobsRunning)
1844: Job_Wait();
1845:
1.184 sjg 1846: (void)fflush(stdout);
1.1 cgd 1847: (void)vfprintf(stderr, fmt, ap);
1848: va_end(ap);
1849: (void)fprintf(stderr, "\n");
1850: (void)fflush(stderr);
1851:
1.176 sjg 1852: PrintOnError(NULL, NULL);
1.67 sjg 1853:
1.94 dsl 1854: if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
1.1 cgd 1855: Targ_PrintGraph(2);
1.58 sommerfe 1856: Trace_Log(MAKEERROR, 0);
1.1 cgd 1857: exit(2); /* Not 1 so -q can distinguish error */
1858: }
1859:
1.392 rillig 1860: /* Major exception once jobs are being created.
1861: * Kills all jobs, prints a message and exits. */
1.1 cgd 1862: void
1.89 christos 1863: Punt(const char *fmt, ...)
1.1 cgd 1864: {
1865: va_list ap;
1.85 wiz 1866:
1.13 cgd 1867: va_start(ap, fmt);
1.184 sjg 1868: (void)fflush(stdout);
1.63 christos 1869: (void)fprintf(stderr, "%s: ", progname);
1.1 cgd 1870: (void)vfprintf(stderr, fmt, ap);
1871: va_end(ap);
1872: (void)fprintf(stderr, "\n");
1873: (void)fflush(stderr);
1874:
1.176 sjg 1875: PrintOnError(NULL, NULL);
1.67 sjg 1876:
1.1 cgd 1877: DieHorribly();
1878: }
1879:
1.392 rillig 1880: /* Exit without giving a message. */
1.1 cgd 1881: void
1.85 wiz 1882: DieHorribly(void)
1.1 cgd 1883: {
1884: if (jobsRunning)
1885: Job_AbortAll();
1886: if (DEBUG(GRAPH2))
1887: Targ_PrintGraph(2);
1.58 sommerfe 1888: Trace_Log(MAKEERROR, 0);
1.1 cgd 1889: exit(2); /* Not 1, so -q can distinguish error */
1890: }
1891:
1.392 rillig 1892: /* Called when aborting due to errors in child shell to signal abnormal exit.
1893: * The program exits.
1894: * Errors is the number of errors encountered in Make_Make. */
1.1 cgd 1895: void
1.421 ! rillig 1896: Finish(int errs)
1.1 cgd 1897: {
1.275 sjg 1898: if (dieQuietly(NULL, -1))
1899: exit(2);
1.421 ! rillig 1900: Fatal("%d error%s", errs, errs == 1 ? "" : "s");
1.1 cgd 1901: }
1902:
1.21 christos 1903: /*
1.208 dholland 1904: * eunlink --
1.21 christos 1905: * Remove a file carefully, avoiding directories.
1906: */
1907: int
1.85 wiz 1908: eunlink(const char *file)
1.21 christos 1909: {
1910: struct stat st;
1911:
1912: if (lstat(file, &st) == -1)
1913: return -1;
1914:
1915: if (S_ISDIR(st.st_mode)) {
1916: errno = EISDIR;
1917: return -1;
1918: }
1919: return unlink(file);
1.1 cgd 1920: }
1921:
1.373 rillig 1922: static void
1923: write_all(int fd, const void *data, size_t n)
1924: {
1925: const char *mem = data;
1926:
1927: while (n > 0) {
1928: ssize_t written = write(fd, mem, n);
1929: if (written == -1 && errno == EAGAIN)
1930: continue;
1931: if (written == -1)
1932: break;
1933: mem += written;
1.375 rillig 1934: n -= (size_t)written;
1.373 rillig 1935: }
1936: }
1937:
1.1 cgd 1938: /*
1.372 rillig 1939: * execDie --
1.66 christos 1940: * Print why exec failed, avoiding stdio.
1941: */
1.372 rillig 1942: void MAKE_ATTR_DEAD
1943: execDie(const char *af, const char *av)
1.66 christos 1944: {
1.373 rillig 1945: Buffer buf;
1946:
1947: Buf_Init(&buf, 0);
1948: Buf_AddStr(&buf, progname);
1949: Buf_AddStr(&buf, ": ");
1950: Buf_AddStr(&buf, af);
1951: Buf_AddStr(&buf, "(");
1952: Buf_AddStr(&buf, av);
1953: Buf_AddStr(&buf, ") failed (");
1954: Buf_AddStr(&buf, strerror(errno));
1955: Buf_AddStr(&buf, ")\n");
1.66 christos 1956:
1.373 rillig 1957: write_all(STDERR_FILENO, Buf_GetAll(&buf, NULL), Buf_Len(&buf));
1.66 christos 1958:
1.373 rillig 1959: Buf_Destroy(&buf, TRUE);
1.372 rillig 1960: _exit(1);
1.66 christos 1961: }
1962:
1963: /*
1.1 cgd 1964: * usage --
1965: * exit with usage message
1966: */
1.13 cgd 1967: static void
1.85 wiz 1968: usage(void)
1.1 cgd 1969: {
1.220 christos 1970: char *p;
1971: if ((p = strchr(progname, '[')) != NULL)
1.292 rillig 1972: *p = '\0';
1.220 christos 1973:
1.1 cgd 1974: (void)fprintf(stderr,
1.292 rillig 1975: "usage: %s [-BeikNnqrstWwX] \n"
1976: " [-C directory] [-D variable] [-d flags] [-f makefile]\n"
1977: " [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n"
1978: " [-V variable] [-v variable] [variable=value] [target ...]\n",
1.272 christos 1979: progname);
1.1 cgd 1980: exit(2);
1.14 jtc 1981: }
1982:
1.245 sjg 1983: /*
1984: * realpath(3) can get expensive, cache results...
1985: */
1.262 riastrad 1986: static GNode *cached_realpaths = NULL;
1987:
1988: static GNode *
1989: get_cached_realpaths(void)
1990: {
1991:
1992: if (!cached_realpaths) {
1993: cached_realpaths = Targ_NewGN("Realpath");
1994: #ifndef DEBUG_REALPATH_CACHE
1995: cached_realpaths->flags = INTERNAL;
1996: #endif
1997: }
1998:
1999: return cached_realpaths;
2000: }
2001:
2002: /* purge any relative paths */
2003: static void
2004: purge_cached_realpaths(void)
2005: {
2006: GNode *cache = get_cached_realpaths();
1.376 rillig 2007: HashEntry *he, *nhe;
1.374 rillig 2008: HashIter hi;
1.262 riastrad 2009:
1.374 rillig 2010: HashIter_Init(&hi, &cache->context);
2011: he = HashIter_Next(&hi);
2012: while (he != NULL) {
2013: nhe = HashIter_Next(&hi);
1.377 rillig 2014: if (he->key[0] != '/') {
1.262 riastrad 2015: if (DEBUG(DIR))
1.377 rillig 2016: fprintf(stderr, "cached_realpath: purging %s\n", he->key);
1.390 rillig 2017: HashTable_DeleteEntry(&cache->context, he);
1.262 riastrad 2018: }
2019: he = nhe;
2020: }
2021: }
2022:
1.245 sjg 2023: char *
2024: cached_realpath(const char *pathname, char *resolved)
2025: {
1.262 riastrad 2026: GNode *cache;
1.289 rillig 2027: const char *rp;
1.412 rillig 2028: void *freeIt;
1.245 sjg 2029:
2030: if (!pathname || !pathname[0])
2031: return NULL;
2032:
1.262 riastrad 2033: cache = get_cached_realpaths();
2034:
1.412 rillig 2035: if ((rp = Var_Value(pathname, cache, &freeIt)) != NULL) {
1.245 sjg 2036: /* a hit */
1.248 christos 2037: strncpy(resolved, rp, MAXPATHLEN);
2038: resolved[MAXPATHLEN - 1] = '\0';
2039: } else if ((rp = realpath(pathname, resolved)) != NULL) {
1.277 rillig 2040: Var_Set(pathname, rp, cache);
1.248 christos 2041: } /* else should we negative-cache? */
2042:
1.412 rillig 2043: bmake_free(freeIt);
1.245 sjg 2044: return rp ? resolved : NULL;
2045: }
2046:
1.275 sjg 2047: /*
2048: * Return true if we should die without noise.
2049: * For example our failing child was a sub-make
2050: * or failure happend elsewhere.
2051: */
2052: int
2053: dieQuietly(GNode *gn, int bf)
2054: {
2055: static int quietly = -1;
2056:
2057: if (quietly < 0) {
1.417 rillig 2058: if (DEBUG(JOB) || !getBoolean(".MAKE.DIE_QUIETLY", TRUE))
1.275 sjg 2059: quietly = 0;
2060: else if (bf >= 0)
2061: quietly = bf;
2062: else
1.380 rillig 2063: quietly = gn != NULL ? ((gn->type & (OP_MAKE)) != 0) : 0;
1.275 sjg 2064: }
2065: return quietly;
2066: }
2067:
1.385 rillig 2068: static void
2069: SetErrorVars(GNode *gn)
2070: {
2071: StringListNode *ln;
2072:
2073: /*
2074: * We can print this even if there is no .ERROR target.
2075: */
2076: Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL);
2077: Var_Delete(".ERROR_CMD", VAR_GLOBAL);
2078:
2079: for (ln = gn->commands->first; ln != NULL; ln = ln->next) {
2080: const char *cmd = ln->datum;
2081:
2082: if (cmd == NULL)
2083: break;
2084: Var_Append(".ERROR_CMD", cmd, VAR_GLOBAL);
2085: }
2086: }
2087:
1.67 sjg 2088: void
1.176 sjg 2089: PrintOnError(GNode *gn, const char *s)
1.67 sjg 2090: {
1.177 sjg 2091: static GNode *en = NULL;
1.296 rillig 2092: const char *expr;
2093: char *cp;
1.128 sjg 2094:
1.283 sjg 2095: if (DEBUG(HASH)) {
2096: Targ_Stats();
2097: Var_Stats();
2098: }
2099:
1.275 sjg 2100: /* we generally want to keep quiet if a sub-make died */
2101: if (dieQuietly(gn, -1))
2102: return;
2103:
1.67 sjg 2104: if (s)
1.176 sjg 2105: printf("%s", s);
1.279 rillig 2106:
1.67 sjg 2107: printf("\n%s: stopped in %s\n", progname, curdir);
1.176 sjg 2108:
1.177 sjg 2109: if (en)
2110: return; /* we've been here! */
1.385 rillig 2111: if (gn)
1.411 rillig 2112: SetErrorVars(gn);
1.296 rillig 2113: expr = "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}";
1.341 rillig 2114: (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &cp);
2115: /* TODO: handle errors */
1.329 rillig 2116: printf("%s", cp);
2117: free(cp);
1.235 sjg 2118: fflush(stdout);
2119:
1.176 sjg 2120: /*
1.186 sjg 2121: * Finally, see if there is a .ERROR target, and run it if so.
1.176 sjg 2122: */
1.346 rillig 2123: en = Targ_FindNode(".ERROR");
1.176 sjg 2124: if (en) {
2125: en->type |= OP_SPECIAL;
2126: Compat_Make(en, en);
2127: }
1.68 sjg 2128: }
2129:
2130: void
1.85 wiz 2131: Main_ExportMAKEFLAGS(Boolean first)
1.68 sjg 2132: {
1.322 rillig 2133: static Boolean once = TRUE;
1.296 rillig 2134: const char *expr;
2135: char *s;
1.68 sjg 2136:
2137: if (once != first)
2138: return;
1.322 rillig 2139: once = FALSE;
1.279 rillig 2140:
1.296 rillig 2141: expr = "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}";
1.410 rillig 2142: (void)Var_Subst(expr, VAR_CMDLINE, VARE_WANTRES, &s);
1.341 rillig 2143: /* TODO: handle errors */
1.322 rillig 2144: if (s[0] != '\0') {
1.68 sjg 2145: #ifdef POSIX
2146: setenv("MAKEFLAGS", s, 1);
2147: #else
2148: setenv("MAKE", s, 1);
2149: #endif
2150: }
1.1 cgd 2151: }
1.180 sjg 2152:
1.191 sjg 2153: char *
2154: getTmpdir(void)
1.180 sjg 2155: {
2156: static char *tmpdir = NULL;
2157:
2158: if (!tmpdir) {
2159: struct stat st;
2160:
2161: /*
2162: * Honor $TMPDIR but only if it is valid.
2163: * Ensure it ends with /.
2164: */
1.341 rillig 2165: (void)Var_Subst("${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
2166: VARE_WANTRES, &tmpdir);
2167: /* TODO: handle errors */
1.180 sjg 2168: if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
2169: free(tmpdir);
2170: tmpdir = bmake_strdup(_PATH_TMP);
2171: }
2172: }
1.191 sjg 2173: return tmpdir;
2174: }
2175:
2176: /*
2177: * Create and open a temp file using "pattern".
1.414 rillig 2178: * If out_fname is provided, set it to a copy of the filename created.
1.191 sjg 2179: * Otherwise unlink the file once open.
2180: */
2181: int
1.414 rillig 2182: mkTempFile(const char *pattern, char **out_fname)
1.191 sjg 2183: {
2184: static char *tmpdir = NULL;
2185: char tfile[MAXPATHLEN];
2186: int fd;
1.279 rillig 2187:
1.414 rillig 2188: if (pattern != NULL)
1.191 sjg 2189: pattern = TMPPAT;
1.414 rillig 2190: if (tmpdir == NULL)
1.191 sjg 2191: tmpdir = getTmpdir();
1.180 sjg 2192: if (pattern[0] == '/') {
1.181 dholland 2193: snprintf(tfile, sizeof(tfile), "%s", pattern);
1.180 sjg 2194: } else {
2195: snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern);
2196: }
2197: if ((fd = mkstemp(tfile)) < 0)
2198: Punt("Could not create temporary file %s: %s", tfile, strerror(errno));
1.414 rillig 2199: if (out_fname) {
2200: *out_fname = bmake_strdup(tfile);
1.180 sjg 2201: } else {
2202: unlink(tfile); /* we just want the descriptor */
2203: }
2204: return fd;
2205: }
1.201 sjg 2206:
1.240 sjg 2207: /*
2208: * Convert a string representation of a boolean.
2209: * Anything that looks like "No", "False", "Off", "0" etc,
2210: * is FALSE, otherwise TRUE.
2211: */
2212: Boolean
2213: s2Boolean(const char *s, Boolean bf)
2214: {
1.416 rillig 2215: switch(s[0]) {
2216: case '\0': /* not set - the default wins */
2217: break;
2218: case '0':
2219: case 'F':
2220: case 'f':
2221: case 'N':
2222: case 'n':
2223: return FALSE;
2224: case 'O':
2225: case 'o':
2226: return s[1] != 'F' && s[1] != 'f';
2227: default:
2228: return TRUE;
1.240 sjg 2229: }
1.278 rillig 2230: return bf;
1.240 sjg 2231: }
1.201 sjg 2232:
2233: /*
1.417 rillig 2234: * Return a Boolean based on a variable.
1.201 sjg 2235: *
1.417 rillig 2236: * If the knob is not set, return the fallback.
2237: * If set, anything that looks or smells like "No", "False", "Off", "0", etc.
1.201 sjg 2238: * is FALSE, otherwise TRUE.
2239: */
2240: Boolean
1.417 rillig 2241: getBoolean(const char *varname, Boolean fallback)
1.201 sjg 2242: {
1.417 rillig 2243: char *expr = str_concat3("${", varname, ":U}");
1.341 rillig 2244: char *value;
2245: Boolean res;
2246:
2247: (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &value);
2248: /* TODO: handle errors */
2249: res = s2Boolean(value, fallback);
1.328 rillig 2250: free(value);
2251: free(expr);
2252: return res;
1.201 sjg 2253: }
CVSweb <webmaster@jp.NetBSD.org>