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