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