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