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