main.c revision 1.82 1 /* $NetBSD: main.c,v 1.82 2002/01/27 01:50:54 reinoud Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 * Copyright (c) 1989 by Berkeley Softworks
7 * All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * Adam de Boor.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 */
40
41 #ifdef MAKE_BOOTSTRAP
42 static char rcsid[] = "$NetBSD: main.c,v 1.82 2002/01/27 01:50:54 reinoud Exp $";
43 #else
44 #include <sys/cdefs.h>
45 #ifndef lint
46 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
47 The Regents of the University of California. All rights reserved.\n");
48 #endif /* not lint */
49
50 #ifndef lint
51 #if 0
52 static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
53 #else
54 __RCSID("$NetBSD: main.c,v 1.82 2002/01/27 01:50:54 reinoud Exp $");
55 #endif
56 #endif /* not lint */
57 #endif
58
59 /*-
60 * main.c --
61 * The main file for this entire program. Exit routines etc
62 * reside here.
63 *
64 * Utility functions defined in this file:
65 * Main_ParseArgLine Takes a line of arguments, breaks them and
66 * treats them as if they were given when first
67 * invoked. Used by the parse module to implement
68 * the .MFLAGS target.
69 *
70 * Error Print a tagged error message. The global
71 * MAKE variable must have been defined. This
72 * takes a format string and two optional
73 * arguments for it.
74 *
75 * Fatal Print an error message and exit. Also takes
76 * a format string and two arguments.
77 *
78 * Punt Aborts all jobs and exits with a message. Also
79 * takes a format string and two arguments.
80 *
81 * Finish Finish things up by printing the number of
82 * errors which occurred, as passed to it, and
83 * exiting.
84 */
85
86 #include <sys/types.h>
87 #include <sys/time.h>
88 #include <sys/param.h>
89 #include <sys/resource.h>
90 #include <sys/signal.h>
91 #include <sys/stat.h>
92 #ifndef MAKE_BOOTSTRAP
93 #include <sys/utsname.h>
94 #endif
95 #include <sys/wait.h>
96 #include <errno.h>
97 #include <fcntl.h>
98 #include <stdio.h>
99 #include <stdlib.h>
100 #include <time.h>
101 #ifdef __STDC__
102 #include <stdarg.h>
103 #else
104 #include <varargs.h>
105 #endif
106 #include "make.h"
107 #include "hash.h"
108 #include "dir.h"
109 #include "job.h"
110 #include "pathnames.h"
111 #include "trace.h"
112
113 #ifdef USE_IOVEC
114 #include <sys/uio.h>
115 #endif
116
117 #ifndef DEFMAXLOCAL
118 #define DEFMAXLOCAL DEFMAXJOBS
119 #endif /* DEFMAXLOCAL */
120
121 Lst create; /* Targets to be made */
122 time_t now; /* Time at start of make */
123 GNode *DEFAULT; /* .DEFAULT node */
124 Boolean allPrecious; /* .PRECIOUS given on line by itself */
125
126 static Boolean noBuiltins; /* -r flag */
127 static Lst makefiles; /* ordered list of makefiles to read */
128 static Boolean printVars; /* print value of one or more vars */
129 static Lst variables; /* list of variables to print */
130 int maxJobs; /* -j argument */
131 static int maxLocal; /* -L argument */
132 Boolean compatMake; /* -B argument */
133 Boolean debug; /* -d flag */
134 Boolean noExecute; /* -n flag */
135 Boolean noRecursiveExecute; /* -N flag */
136 Boolean keepgoing; /* -k flag */
137 Boolean queryFlag; /* -q flag */
138 Boolean touchFlag; /* -t flag */
139 Boolean usePipes; /* !-P flag */
140 Boolean ignoreErrors; /* -i flag */
141 Boolean beSilent; /* -s flag */
142 Boolean oldVars; /* variable substitution style */
143 Boolean checkEnvFirst; /* -e flag */
144 Boolean parseWarnFatal; /* -W flag */
145 Boolean jobServer; /* -J flag */
146 static Boolean jobsRunning; /* TRUE if the jobs might be running */
147 static const char * tracefile;
148 static char * Check_Cwd_av __P((int, char **, int));
149 static void MainParseArgs __P((int, char **));
150 static int ReadMakefile __P((ClientData, ClientData));
151 static void usage __P((void));
152
153 static char curdir[MAXPATHLEN + 1]; /* startup directory */
154 static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
155 char *progname; /* the program name */
156
157 Boolean forceJobs = FALSE;
158
159 extern Lst parseIncPath;
160
161 /*-
162 * MainParseArgs --
163 * Parse a given argument vector. Called from main() and from
164 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
165 *
166 * XXX: Deal with command line overriding .MAKEFLAGS in makefile
167 *
168 * Results:
169 * None
170 *
171 * Side Effects:
172 * Various global and local flags will be set depending on the flags
173 * given
174 */
175 static void
176 MainParseArgs(argc, argv)
177 int argc;
178 char **argv;
179 {
180 char *p;
181 int c;
182
183 optind = 1; /* since we're called more than once */
184 #ifdef REMOTE
185 # define OPTFLAGS "BD:I:J:L:NPST:V:Wd:ef:ij:km:nqrst"
186 #else
187 # define OPTFLAGS "BD:I:J:NPST:V:Wd:ef:ij:km:nqrst"
188 #endif
189 rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
190 switch(c) {
191 case 'D':
192 Var_Set(optarg, "1", VAR_GLOBAL, 0);
193 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
194 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
195 break;
196 case 'I':
197 Parse_AddIncludeDir(optarg);
198 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
199 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
200 break;
201 case 'J':
202 if (sscanf(optarg, "%d,%d", &job_pipe[0], &job_pipe[1]) != 2) {
203 /* backslash to avoid trigraph ??) */
204 (void)fprintf(stderr,
205 "%s: internal error -- J option malformed (%s?\?)\n",
206 progname, optarg);
207 usage();
208 }
209 if ((fcntl(job_pipe[0], F_GETFD, 0) < 0) ||
210 (fcntl(job_pipe[1], F_GETFD, 0) < 0)) {
211 #if 0
212 (void)fprintf(stderr,
213 "%s: warning -- J descriptors were closed!\n",
214 progname);
215 #endif
216 job_pipe[0] = -1;
217 job_pipe[1] = -1;
218 compatMake = TRUE;
219 } else {
220 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
221 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
222 jobServer = TRUE;
223 }
224 break;
225 case 'V':
226 printVars = TRUE;
227 (void)Lst_AtEnd(variables, (ClientData)optarg);
228 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
229 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
230 break;
231 case 'B':
232 compatMake = TRUE;
233 break;
234 #ifdef REMOTE
235 case 'L':
236 maxLocal = strtol(optarg, &p, 0);
237 if (*p != '\0' || maxLocal < 1) {
238 (void) fprintf(stderr, "%s: illegal argument to -L -- must be positive integer!\n",
239 progname);
240 exit(1);
241 }
242 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
243 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
244 break;
245 #endif
246 case 'N':
247 noExecute = TRUE;
248 noRecursiveExecute = TRUE;
249 Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
250 break;
251 case 'P':
252 usePipes = FALSE;
253 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
254 break;
255 case 'S':
256 keepgoing = FALSE;
257 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
258 break;
259 case 'T':
260 tracefile = estrdup(optarg);
261 Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
262 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
263 break;
264 case 'W':
265 parseWarnFatal = TRUE;
266 break;
267 case 'd': {
268 char *modules = optarg;
269
270 for (; *modules; ++modules)
271 switch (*modules) {
272 case 'A':
273 debug = ~0;
274 break;
275 case 'a':
276 debug |= DEBUG_ARCH;
277 break;
278 case 'c':
279 debug |= DEBUG_COND;
280 break;
281 case 'd':
282 debug |= DEBUG_DIR;
283 break;
284 case 'f':
285 debug |= DEBUG_FOR;
286 break;
287 case 'g':
288 if (modules[1] == '1') {
289 debug |= DEBUG_GRAPH1;
290 ++modules;
291 }
292 else if (modules[1] == '2') {
293 debug |= DEBUG_GRAPH2;
294 ++modules;
295 }
296 break;
297 case 'j':
298 debug |= DEBUG_JOB;
299 break;
300 case 'm':
301 debug |= DEBUG_MAKE;
302 break;
303 case 's':
304 debug |= DEBUG_SUFF;
305 break;
306 case 't':
307 debug |= DEBUG_TARG;
308 break;
309 case 'v':
310 debug |= DEBUG_VAR;
311 break;
312 case 'x':
313 debug |= DEBUG_SHELL;
314 break;
315 default:
316 (void)fprintf(stderr,
317 "%s: illegal argument to d option -- %c\n",
318 progname, *modules);
319 usage();
320 }
321 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
322 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
323 break;
324 }
325 case 'e':
326 checkEnvFirst = TRUE;
327 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
328 break;
329 case 'f':
330 (void)Lst_AtEnd(makefiles, (ClientData)optarg);
331 break;
332 case 'i':
333 ignoreErrors = TRUE;
334 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
335 break;
336 case 'j':
337 forceJobs = TRUE;
338 maxJobs = strtol(optarg, &p, 0);
339 if (*p != '\0' || maxJobs < 1) {
340 (void) fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
341 progname);
342 exit(1);
343 }
344 #ifndef REMOTE
345 maxLocal = maxJobs;
346 #endif
347 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
348 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
349 break;
350 case 'k':
351 keepgoing = TRUE;
352 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
353 break;
354 case 'm':
355 (void) Dir_AddDir(sysIncPath, optarg);
356 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
357 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
358 break;
359 case 'n':
360 noExecute = TRUE;
361 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
362 break;
363 case 'q':
364 queryFlag = TRUE;
365 /* Kind of nonsensical, wot? */
366 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
367 break;
368 case 'r':
369 noBuiltins = TRUE;
370 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
371 break;
372 case 's':
373 beSilent = TRUE;
374 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
375 break;
376 case 't':
377 touchFlag = TRUE;
378 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
379 break;
380 default:
381 case '?':
382 usage();
383 }
384 }
385
386 oldVars = TRUE;
387
388 /*
389 * See if the rest of the arguments are variable assignments and
390 * perform them if so. Else take them to be targets and stuff them
391 * on the end of the "create" list.
392 */
393 for (argv += optind, argc -= optind; *argv; ++argv, --argc)
394 if (Parse_IsVar(*argv)) {
395 Parse_DoVar(*argv, VAR_CMD);
396 } else {
397 if (!**argv)
398 Punt("illegal (null) argument.");
399 if (**argv == '-') {
400 if ((*argv)[1])
401 optind = 0; /* -flag... */
402 else
403 optind = 1; /* - */
404 goto rearg;
405 }
406 (void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
407 }
408 }
409
410 /*-
411 * Main_ParseArgLine --
412 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
413 * is encountered and by main() when reading the .MAKEFLAGS envariable.
414 * Takes a line of arguments and breaks it into its
415 * component words and passes those words and the number of them to the
416 * MainParseArgs function.
417 * The line should have all its leading whitespace removed.
418 *
419 * Results:
420 * None
421 *
422 * Side Effects:
423 * Only those that come from the various arguments.
424 */
425 void
426 Main_ParseArgLine(line)
427 char *line; /* Line to fracture */
428 {
429 char **argv; /* Manufactured argument vector */
430 int argc; /* Number of arguments in argv */
431 char *args; /* Space used by the args */
432 char *buf, *p1;
433 char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
434 size_t len;
435
436 if (line == NULL)
437 return;
438 for (; *line == ' '; ++line)
439 continue;
440 if (!*line)
441 return;
442
443 buf = emalloc(len = strlen(line) + strlen(argv0) + 2);
444 (void)snprintf(buf, len, "%s %s", argv0, line);
445 if (p1)
446 free(p1);
447
448 argv = brk_string(buf, &argc, TRUE, &args);
449 free(buf);
450 MainParseArgs(argc, argv);
451
452 free(args);
453 free(argv);
454 }
455
456 Boolean
457 Main_SetObjdir(path)
458 const char *path;
459 {
460 struct stat sb;
461 char *p = NULL;
462 char buf[MAXPATHLEN + 1];
463 Boolean rc = FALSE;
464
465 /* expand variable substitutions */
466 if (strchr(path, '$') != 0) {
467 snprintf(buf, MAXPATHLEN, "%s", path);
468 path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0);
469 }
470
471 if (path[0] != '/') {
472 snprintf(buf, MAXPATHLEN, "%s/%s", curdir, path);
473 path = buf;
474 }
475
476 /* look for the directory and try to chdir there */
477 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
478 if (chdir(path)) {
479 (void)fprintf(stderr, "make warning: %s: %s.\n",
480 path, strerror(errno));
481 } else {
482 strncpy(objdir, path, MAXPATHLEN);
483 Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0);
484 setenv("PWD", objdir, 1);
485 Dir_InitDot();
486 rc = TRUE;
487 }
488 }
489
490 if (p)
491 free(p);
492 return rc;
493 }
494
495
496 /*-
497 * main --
498 * The main function, for obvious reasons. Initializes variables
499 * and a few modules, then parses the arguments give it in the
500 * environment and on the command line. Reads the system makefile
501 * followed by either Makefile, makefile or the file given by the
502 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
503 * flags it has received by then uses either the Make or the Compat
504 * module to create the initial list of targets.
505 *
506 * Results:
507 * If -q was given, exits -1 if anything was out-of-date. Else it exits
508 * 0.
509 *
510 * Side Effects:
511 * The program exits when done. Targets are created. etc. etc. etc.
512 */
513 int
514 main(argc, argv)
515 int argc;
516 char **argv;
517 {
518 Lst targs; /* target nodes to create -- passed to Make_Init */
519 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
520 struct stat sb, sa;
521 char *p1, *path, *pwd;
522 char mdpath[MAXPATHLEN];
523 char *machine = getenv("MACHINE");
524 char *machine_arch = getenv("MACHINE_ARCH");
525 char *syspath = getenv("MAKESYSPATH");
526 Lst sysMkPath; /* Path of sys.mk */
527 char *cp = NULL, *start;
528 /* avoid faults on read-only strings */
529 static char defsyspath[] = _PATH_DEFSYSPATH;
530
531 if ((progname = strrchr(argv[0], '/')) != NULL)
532 progname++;
533 else
534 progname = argv[0];
535 #ifdef RLIMIT_NOFILE
536 /*
537 * get rid of resource limit on file descriptors
538 */
539 {
540 struct rlimit rl;
541 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
542 rl.rlim_cur != rl.rlim_max) {
543 rl.rlim_cur = rl.rlim_max;
544 (void) setrlimit(RLIMIT_NOFILE, &rl);
545 }
546 }
547 #endif
548 /*
549 * Find where we are and take care of PWD for the automounter...
550 * All this code is so that we know where we are when we start up
551 * on a different machine with pmake.
552 */
553 if (getcwd(curdir, MAXPATHLEN) == NULL) {
554 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
555 exit(2);
556 }
557
558 if (stat(curdir, &sa) == -1) {
559 (void)fprintf(stderr, "%s: %s: %s.\n",
560 progname, curdir, strerror(errno));
561 exit(2);
562 }
563
564 /*
565 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
566 * since the value of curdir can very depending on how we got
567 * here. Ie sitting at a shell prompt (shell that provides $PWD)
568 * or via subdir.mk in which case its likely a shell which does
569 * not provide it.
570 * So, to stop it breaking this case only, we ignore PWD if
571 * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
572 */
573 if ((pwd = getenv("PWD")) != NULL && getenv("MAKEOBJDIRPREFIX") == NULL) {
574 const char *makeobjdir = getenv("MAKEOBJDIR");
575
576 if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
577 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
578 sa.st_dev == sb.st_dev)
579 (void) strncpy(curdir, pwd, MAXPATHLEN);
580 }
581 }
582
583 /*
584 * Get the name of this type of MACHINE from utsname
585 * so we can share an executable for similar machines.
586 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
587 *
588 * Note that both MACHINE and MACHINE_ARCH are decided at
589 * run-time.
590 */
591 if (!machine) {
592 #ifndef MAKE_BOOTSTRAP
593 struct utsname utsname;
594
595 if (uname(&utsname) == -1) {
596 (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
597 strerror(errno));
598 exit(2);
599 }
600 machine = utsname.machine;
601 #else
602 #ifdef MAKE_MACHINE
603 machine = MAKE_MACHINE;
604 #else
605 machine = "unknown";
606 #endif
607 #endif
608 }
609
610 if (!machine_arch) {
611 #ifndef MACHINE_ARCH
612 #ifdef MAKE_MACHINE_ARCH
613 machine_arch = MAKE_MACHINE_ARCH;
614 #else
615 machine_arch = "unknown";
616 #endif
617 #else
618 machine_arch = MACHINE_ARCH;
619 #endif
620 }
621
622 /*
623 * Just in case MAKEOBJDIR wants us to do something tricky.
624 */
625 Var_Init(); /* Initialize the lists of variables for
626 * parsing arguments */
627 Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
628 Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
629 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
630 #ifdef MAKE_VERSION
631 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
632 #endif
633 Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
634
635 /*
636 * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that,
637 * MAKEOBJDIR is set in the environment, try only that value
638 * and fall back to .CURDIR if it does not exist.
639 *
640 * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and
641 * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
642 * of these paths exist, just use .CURDIR.
643 */
644 Dir_Init(curdir);
645 (void) Main_SetObjdir(curdir);
646
647 if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) {
648 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir);
649 (void) Main_SetObjdir(mdpath);
650 } else if ((path = getenv("MAKEOBJDIR")) != NULL) {
651 (void) Main_SetObjdir(path);
652 } else {
653 (void) snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine);
654 if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) {
655 (void) snprintf(mdpath, MAXPATHLEN, "%s%s",
656 _PATH_OBJDIRPREFIX, curdir);
657 (void) Main_SetObjdir(mdpath);
658 }
659 }
660
661 create = Lst_Init(FALSE);
662 makefiles = Lst_Init(FALSE);
663 printVars = FALSE;
664 variables = Lst_Init(FALSE);
665 beSilent = FALSE; /* Print commands as executed */
666 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
667 noExecute = FALSE; /* Execute all commands */
668 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
669 keepgoing = FALSE; /* Stop on error */
670 allPrecious = FALSE; /* Remove targets when interrupted */
671 queryFlag = FALSE; /* This is not just a check-run */
672 noBuiltins = FALSE; /* Read the built-in rules */
673 touchFlag = FALSE; /* Actually update targets */
674 usePipes = TRUE; /* Catch child output in pipes */
675 debug = 0; /* No debug verbosity, please. */
676 jobsRunning = FALSE;
677
678 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
679 #ifdef REMOTE
680 maxJobs = DEFMAXJOBS; /* Set default max concurrency */
681 #else
682 maxJobs = maxLocal;
683 #endif
684 compatMake = FALSE; /* No compat mode */
685
686
687 /*
688 * Initialize the parsing, directory and variable modules to prepare
689 * for the reading of inclusion paths and variable settings on the
690 * command line
691 */
692
693 /*
694 * Initialize various variables.
695 * MAKE also gets this name, for compatibility
696 * .MAKEFLAGS gets set to the empty string just in case.
697 * MFLAGS also gets initialized empty, for compatibility.
698 */
699 Parse_Init();
700 Var_Set("MAKE", argv[0], VAR_GLOBAL, 0);
701 Var_Set(".MAKE", argv[0], VAR_GLOBAL, 0);
702 Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0);
703 Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
704 Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
705 Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);
706
707 /*
708 * First snag any flags out of the MAKE environment variable.
709 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
710 * in a different format).
711 */
712 #ifdef POSIX
713 Main_ParseArgLine(getenv("MAKEFLAGS"));
714 #else
715 Main_ParseArgLine(getenv("MAKE"));
716 #endif
717
718 MainParseArgs(argc, argv);
719
720 /*
721 * Be compatible if user did not specify -j and did not explicitly
722 * turned compatibility on
723 */
724 if (!compatMake && !forceJobs) {
725 compatMake = TRUE;
726 }
727
728 /*
729 * Initialize archive, target and suffix modules in preparation for
730 * parsing the makefile(s)
731 */
732 Arch_Init();
733 Targ_Init();
734 Suff_Init();
735 Trace_Init(tracefile);
736
737 DEFAULT = NILGNODE;
738 (void)time(&now);
739
740 Trace_Log(MAKESTART, NULL);
741
742 /*
743 * Set up the .TARGETS variable to contain the list of targets to be
744 * created. If none specified, make the variable empty -- the parser
745 * will fill the thing in with the default or .MAIN target.
746 */
747 if (!Lst_IsEmpty(create)) {
748 LstNode ln;
749
750 for (ln = Lst_First(create); ln != NILLNODE;
751 ln = Lst_Succ(ln)) {
752 char *name = (char *)Lst_Datum(ln);
753
754 Var_Append(".TARGETS", name, VAR_GLOBAL);
755 }
756 } else
757 Var_Set(".TARGETS", "", VAR_GLOBAL, 0);
758
759
760 /*
761 * If no user-supplied system path was given (through the -m option)
762 * add the directories from the DEFSYSPATH (more than one may be given
763 * as dir1:...:dirn) to the system include path.
764 */
765 if (syspath == NULL || *syspath == '\0')
766 syspath = defsyspath;
767 else
768 syspath = strdup(syspath);
769
770 for (start = syspath; *start != '\0'; start = cp) {
771 for (cp = start; *cp != '\0' && *cp != ':'; cp++)
772 continue;
773 if (*cp == '\0') {
774 (void) Dir_AddDir(defIncPath, start);
775 } else {
776 *cp++ = '\0';
777 (void) Dir_AddDir(defIncPath, start);
778 }
779 }
780 if (syspath != defsyspath)
781 free(syspath);
782
783 /*
784 * Read in the built-in rules first, followed by the specified
785 * makefile, if it was (makefile != (char *) NULL), or the default
786 * Makefile and makefile, in that order, if it wasn't.
787 */
788 if (!noBuiltins) {
789 LstNode ln;
790
791 sysMkPath = Lst_Init (FALSE);
792 Dir_Expand(_PATH_DEFSYSMK,
793 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
794 sysMkPath);
795 if (Lst_IsEmpty(sysMkPath))
796 Fatal("%s: no system rules (%s).", progname,
797 _PATH_DEFSYSMK);
798 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
799 if (ln != NILLNODE)
800 Fatal("%s: cannot open %s.", progname,
801 (char *)Lst_Datum(ln));
802 }
803
804 if (!Lst_IsEmpty(makefiles)) {
805 LstNode ln;
806
807 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
808 if (ln != NILLNODE)
809 Fatal("%s: cannot open %s.", progname,
810 (char *)Lst_Datum(ln));
811 } else if (!ReadMakefile("makefile", NULL))
812 (void)ReadMakefile("Makefile", NULL);
813
814 (void)ReadMakefile(".depend", NULL);
815
816 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
817 if (p1)
818 free(p1);
819
820 if (!jobServer && !compatMake)
821 Job_ServerStart(maxJobs);
822 if (DEBUG(JOB))
823 printf("job_pipe %d %d, maxjobs %d maxlocal %d compat %d\n", job_pipe[0], job_pipe[1], maxJobs,
824 maxLocal, compatMake);
825
826 Main_ExportMAKEFLAGS(TRUE); /* initial export */
827
828 Check_Cwd_av(0, NULL, 0); /* initialize it */
829
830
831 /*
832 * For compatibility, look at the directories in the VPATH variable
833 * and add them to the search path, if the variable is defined. The
834 * variable's value is in the same format as the PATH envariable, i.e.
835 * <directory>:<directory>:<directory>...
836 */
837 if (Var_Exists("VPATH", VAR_CMD)) {
838 char *vpath, savec;
839 /*
840 * GCC stores string constants in read-only memory, but
841 * Var_Subst will want to write this thing, so store it
842 * in an array
843 */
844 static char VPATH[] = "${VPATH}";
845
846 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
847 path = vpath;
848 do {
849 /* skip to end of directory */
850 for (cp = path; *cp != ':' && *cp != '\0'; cp++)
851 continue;
852 /* Save terminator character so know when to stop */
853 savec = *cp;
854 *cp = '\0';
855 /* Add directory to search path */
856 (void) Dir_AddDir(dirSearchPath, path);
857 *cp = savec;
858 path = cp + 1;
859 } while (savec == ':');
860 (void)free((Address)vpath);
861 }
862
863 /*
864 * Now that all search paths have been read for suffixes et al, it's
865 * time to add the default search path to their lists...
866 */
867 Suff_DoPaths();
868
869 /*
870 * Propagate attributes through :: dependency lists.
871 */
872 Targ_Propagate();
873
874 /* print the initial graph, if the user requested it */
875 if (DEBUG(GRAPH1))
876 Targ_PrintGraph(1);
877
878 /* print the values of any variables requested by the user */
879 if (printVars) {
880 LstNode ln;
881
882 for (ln = Lst_First(variables); ln != NILLNODE;
883 ln = Lst_Succ(ln)) {
884 char *value = Var_Value((char *)Lst_Datum(ln),
885 VAR_GLOBAL, &p1);
886
887 printf("%s\n", value ? value : "");
888 if (p1)
889 free(p1);
890 }
891 }
892
893 /*
894 * Have now read the entire graph and need to make a list of targets
895 * to create. If none was given on the command line, we consult the
896 * parsing module to find the main target(s) to create.
897 */
898 if (Lst_IsEmpty(create))
899 targs = Parse_MainName();
900 else
901 targs = Targ_FindList(create, TARG_CREATE);
902
903 if (!compatMake && !printVars) {
904 /*
905 * Initialize job module before traversing the graph, now that
906 * any .BEGIN and .END targets have been read. This is done
907 * only if the -q flag wasn't given (to prevent the .BEGIN from
908 * being executed should it exist).
909 */
910 if (!queryFlag) {
911 if (maxLocal == -1)
912 maxLocal = maxJobs;
913 Job_Init(maxJobs, maxLocal);
914 jobsRunning = TRUE;
915 }
916
917 /* Traverse the graph, checking on all the targets */
918 outOfDate = Make_Run(targs);
919 } else if (!printVars) {
920 /*
921 * Compat_Init will take care of creating all the targets as
922 * well as initializing the module.
923 */
924 Compat_Run(targs);
925 }
926
927 #ifdef CLEANUP
928 Lst_Destroy(targs, NOFREE);
929 Lst_Destroy(variables, NOFREE);
930 Lst_Destroy(makefiles, NOFREE);
931 Lst_Destroy(create, (void (*) __P((ClientData))) free);
932 #endif
933
934 /* print the graph now it's been processed if the user requested it */
935 if (DEBUG(GRAPH2))
936 Targ_PrintGraph(2);
937
938 Trace_Log(MAKEEND, 0);
939
940 Suff_End();
941 Targ_End();
942 Arch_End();
943 Var_End();
944 Parse_End();
945 Dir_End();
946 Job_End();
947 Trace_End();
948
949 if (queryFlag && outOfDate)
950 return(1);
951 else
952 return(0);
953 }
954
955 /*-
956 * ReadMakefile --
957 * Open and parse the given makefile.
958 *
959 * Results:
960 * TRUE if ok. FALSE if couldn't open file.
961 *
962 * Side Effects:
963 * lots
964 */
965 static Boolean
966 ReadMakefile(p, q)
967 ClientData p, q;
968 {
969 char *fname = p; /* makefile to read */
970 FILE *stream;
971 size_t len = MAXPATHLEN;
972 char *name, *path = emalloc(len);
973 int setMAKEFILE;
974
975 if (!strcmp(fname, "-")) {
976 Parse_File("(stdin)", stdin);
977 Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
978 } else {
979 setMAKEFILE = strcmp(fname, ".depend");
980
981 /* if we've chdir'd, rebuild the path name */
982 if (strcmp(curdir, objdir) && *fname != '/') {
983 size_t plen = strlen(curdir) + strlen(fname) + 2;
984 if (len < plen)
985 path = erealloc(path, len = 2 * plen);
986
987 (void)snprintf(path, len, "%s/%s", curdir, fname);
988 if ((stream = fopen(path, "r")) != NULL) {
989 fname = path;
990 goto found;
991 }
992 } else if ((stream = fopen(fname, "r")) != NULL)
993 goto found;
994 /* look in -I and system include directories. */
995 name = Dir_FindFile(fname, parseIncPath);
996 if (!name)
997 name = Dir_FindFile(fname,
998 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
999 if (!name || !(stream = fopen(name, "r"))) {
1000 free(path);
1001 return(FALSE);
1002 }
1003 fname = name;
1004 /*
1005 * set the MAKEFILE variable desired by System V fans -- the
1006 * placement of the setting here means it gets set to the last
1007 * makefile specified, as it is set by SysV make.
1008 */
1009 found:
1010 if (setMAKEFILE)
1011 Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
1012 Parse_File(fname, stream);
1013 (void)fclose(stream);
1014 }
1015 free(path);
1016 return(TRUE);
1017 }
1018
1019
1020 /*
1021 * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR
1022 * in situations that would not arrise with ./obj (links or not).
1023 * This tends to break things like:
1024 *
1025 * build:
1026 * ${MAKE} includes
1027 *
1028 * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as
1029 * opposed to an argument) in a command line and if so returns
1030 * ${.CURDIR} so caller can chdir() so that the assumptions made by
1031 * the Makefile hold true.
1032 *
1033 * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped.
1034 *
1035 * The chdir() only happens in the child process, and does nothing if
1036 * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it
1037 * should not break anything. Also if NOCHECKMAKECHDIR is set we
1038 * do nothing - to ensure historic semantics can be retained.
1039 */
1040 static int Check_Cwd_Off = 0;
1041
1042 static char *
1043 Check_Cwd_av(ac, av, copy)
1044 int ac;
1045 char **av;
1046 int copy;
1047 {
1048 static char *make[4];
1049 static char *cur_dir = NULL;
1050 char *cp, **mp;
1051 int is_cmd, next_cmd;
1052 int i;
1053 int n;
1054
1055 if (Check_Cwd_Off)
1056 return NULL;
1057
1058 if (make[0] == NULL) {
1059 if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
1060 Check_Cwd_Off = 1;
1061 return NULL;
1062 }
1063
1064 make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
1065 if ((make[0] = strrchr(make[1], '/')) == NULL) {
1066 make[0] = make[1];
1067 make[1] = NULL;
1068 } else
1069 ++make[0];
1070 make[2] = NULL;
1071 cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
1072 }
1073 if (ac == 0 || av == NULL)
1074 return NULL; /* initialization only */
1075
1076 if (getenv("MAKEOBJDIR") == NULL &&
1077 getenv("MAKEOBJDIRPREFIX") == NULL)
1078 return NULL;
1079
1080
1081 next_cmd = 1;
1082 for (i = 0; i < ac; ++i) {
1083 is_cmd = next_cmd;
1084
1085 n = strlen(av[i]);
1086 cp = &(av[i])[n - 1];
1087 if (strspn(av[i], "|&;") == n) {
1088 next_cmd = 1;
1089 continue;
1090 } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
1091 next_cmd = 1;
1092 if (copy) {
1093 do {
1094 *cp-- = '\0';
1095 } while (*cp == ';' || *cp == '&' || *cp == '|' ||
1096 *cp == ')' || *cp == '}') ;
1097 } else {
1098 /*
1099 * XXX this should not happen.
1100 */
1101 fprintf(stderr, "WARNING: raw arg ends in shell meta '%s'\n",
1102 av[i]);
1103 }
1104 } else
1105 next_cmd = 0;
1106
1107 cp = av[i];
1108 if (*cp == ';' || *cp == '&' || *cp == '|')
1109 is_cmd = 1;
1110
1111 #ifdef check_cwd_debug
1112 fprintf(stderr, "av[%d] == %s '%s'",
1113 i, (is_cmd) ? "cmd" : "arg", av[i]);
1114 #endif
1115 if (is_cmd != 0) {
1116 if (*cp == '(' || *cp == '{' ||
1117 *cp == ';' || *cp == '&' || *cp == '|') {
1118 do {
1119 ++cp;
1120 } while (*cp == '(' || *cp == '{' ||
1121 *cp == ';' || *cp == '&' || *cp == '|');
1122 if (*cp == '\0') {
1123 next_cmd = 1;
1124 continue;
1125 }
1126 }
1127 if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
1128 #ifdef check_cwd_debug
1129 fprintf(stderr, " == cd, done.\n");
1130 #endif
1131 return NULL;
1132 }
1133 for (mp = make; *mp != NULL; ++mp) {
1134 n = strlen(*mp);
1135 if (strcmp(cp, *mp) == 0) {
1136 #ifdef check_cwd_debug
1137 fprintf(stderr, " %s == '%s', chdir(%s)\n",
1138 cp, *mp, cur_dir);
1139 #endif
1140 return cur_dir;
1141 }
1142 }
1143 }
1144 #ifdef check_cwd_debug
1145 fprintf(stderr, "\n");
1146 #endif
1147 }
1148 return NULL;
1149 }
1150
1151 char *
1152 Check_Cwd_Cmd(cmd)
1153 char *cmd;
1154 {
1155 char *cp, *bp, **av;
1156 int ac;
1157
1158 if (Check_Cwd_Off)
1159 return NULL;
1160
1161 if (cmd) {
1162 av = brk_string(cmd, &ac, TRUE, &bp);
1163 #ifdef check_cwd_debug
1164 fprintf(stderr, "splitting: '%s' -> %d words\n",
1165 cmd, ac);
1166 #endif
1167 } else {
1168 ac = 0;
1169 av = NULL;
1170 bp = NULL;
1171 }
1172 cp = Check_Cwd_av(ac, av, 1);
1173 if (bp) {
1174 free(av);
1175 free(bp);
1176 }
1177 return cp;
1178 }
1179
1180 void
1181 Check_Cwd(argv)
1182 char **argv;
1183 {
1184 char *cp;
1185 int ac;
1186
1187 if (Check_Cwd_Off)
1188 return;
1189
1190 for (ac = 0; argv[ac] != NULL; ++ac)
1191 /* NOTHING */;
1192 if (ac == 3 && *argv[1] == '-') {
1193 cp = Check_Cwd_Cmd(argv[2]);
1194 } else {
1195 cp = Check_Cwd_av(ac, argv, 0);
1196 }
1197 if (cp) {
1198 chdir(cp);
1199 }
1200 }
1201
1202 /*-
1203 * Cmd_Exec --
1204 * Execute the command in cmd, and return the output of that command
1205 * in a string.
1206 *
1207 * Results:
1208 * A string containing the output of the command, or the empty string
1209 * If err is not NULL, it contains the reason for the command failure
1210 *
1211 * Side Effects:
1212 * The string must be freed by the caller.
1213 */
1214 char *
1215 Cmd_Exec(cmd, err)
1216 char *cmd;
1217 char **err;
1218 {
1219 char *args[4]; /* Args for invoking the shell */
1220 int fds[2]; /* Pipe streams */
1221 int cpid; /* Child PID */
1222 int pid; /* PID from wait() */
1223 char *res; /* result */
1224 int status; /* command exit status */
1225 Buffer buf; /* buffer to store the result */
1226 char *cp;
1227 int cc;
1228
1229
1230 *err = NULL;
1231
1232 /*
1233 * Set up arguments for shell
1234 */
1235 args[0] = "sh";
1236 args[1] = "-c";
1237 args[2] = cmd;
1238 args[3] = NULL;
1239
1240 /*
1241 * Open a pipe for fetching its output
1242 */
1243 if (pipe(fds) == -1) {
1244 *err = "Couldn't create pipe for \"%s\"";
1245 goto bad;
1246 }
1247
1248 /*
1249 * Fork
1250 */
1251 switch (cpid = vfork()) {
1252 case 0:
1253 /*
1254 * Close input side of pipe
1255 */
1256 (void) close(fds[0]);
1257
1258 /*
1259 * Duplicate the output stream to the shell's output, then
1260 * shut the extra thing down. Note we don't fetch the error
1261 * stream...why not? Why?
1262 */
1263 (void) dup2(fds[1], 1);
1264 (void) close(fds[1]);
1265
1266 (void) execv("/bin/sh", args);
1267 _exit(1);
1268 /*NOTREACHED*/
1269
1270 case -1:
1271 *err = "Couldn't exec \"%s\"";
1272 goto bad;
1273
1274 default:
1275 /*
1276 * No need for the writing half
1277 */
1278 (void) close(fds[1]);
1279
1280 buf = Buf_Init (MAKE_BSIZE);
1281
1282 do {
1283 char result[BUFSIZ];
1284 cc = read(fds[0], result, sizeof(result));
1285 if (cc > 0)
1286 Buf_AddBytes(buf, cc, (Byte *) result);
1287 }
1288 while (cc > 0 || (cc == -1 && errno == EINTR));
1289
1290 /*
1291 * Close the input side of the pipe.
1292 */
1293 (void) close(fds[0]);
1294
1295 /*
1296 * Wait for the process to exit.
1297 */
1298 while(((pid = wait(&status)) != cpid) && (pid >= 0))
1299 continue;
1300
1301 res = (char *)Buf_GetAll (buf, &cc);
1302 Buf_Destroy (buf, FALSE);
1303
1304 if (cc == 0)
1305 *err = "Couldn't read shell's output for \"%s\"";
1306
1307 if (status)
1308 *err = "\"%s\" returned non-zero status";
1309
1310 /*
1311 * Null-terminate the result, convert newlines to spaces and
1312 * install it in the variable.
1313 */
1314 res[cc] = '\0';
1315 cp = &res[cc];
1316
1317 if (cc > 0 && *--cp == '\n') {
1318 /*
1319 * A final newline is just stripped
1320 */
1321 *cp-- = '\0';
1322 }
1323 while (cp >= res) {
1324 if (*cp == '\n') {
1325 *cp = ' ';
1326 }
1327 cp--;
1328 }
1329 break;
1330 }
1331 return res;
1332 bad:
1333 res = emalloc(1);
1334 *res = '\0';
1335 return res;
1336 }
1337
1338 /*-
1339 * Error --
1340 * Print an error message given its format.
1341 *
1342 * Results:
1343 * None.
1344 *
1345 * Side Effects:
1346 * The message is printed.
1347 */
1348 /* VARARGS */
1349 void
1350 #ifdef __STDC__
1351 Error(char *fmt, ...)
1352 #else
1353 Error(va_alist)
1354 va_dcl
1355 #endif
1356 {
1357 va_list ap;
1358 #ifdef __STDC__
1359 va_start(ap, fmt);
1360 #else
1361 char *fmt;
1362
1363 va_start(ap);
1364 fmt = va_arg(ap, char *);
1365 #endif
1366 fprintf(stderr, "%s: ", progname);
1367 (void)vfprintf(stderr, fmt, ap);
1368 va_end(ap);
1369 (void)fprintf(stderr, "\n");
1370 (void)fflush(stderr);
1371 }
1372
1373 /*-
1374 * Fatal --
1375 * Produce a Fatal error message. If jobs are running, waits for them
1376 * to finish.
1377 *
1378 * Results:
1379 * None
1380 *
1381 * Side Effects:
1382 * The program exits
1383 */
1384 /* VARARGS */
1385 void
1386 #ifdef __STDC__
1387 Fatal(char *fmt, ...)
1388 #else
1389 Fatal(va_alist)
1390 va_dcl
1391 #endif
1392 {
1393 va_list ap;
1394 #ifdef __STDC__
1395 va_start(ap, fmt);
1396 #else
1397 char *fmt;
1398
1399 va_start(ap);
1400 fmt = va_arg(ap, char *);
1401 #endif
1402 if (jobsRunning)
1403 Job_Wait();
1404 Job_TokenFlush();
1405
1406 (void)vfprintf(stderr, fmt, ap);
1407 va_end(ap);
1408 (void)fprintf(stderr, "\n");
1409 (void)fflush(stderr);
1410
1411 PrintOnError(NULL);
1412
1413 if (DEBUG(GRAPH2))
1414 Targ_PrintGraph(2);
1415 Trace_Log(MAKEERROR, 0);
1416 exit(2); /* Not 1 so -q can distinguish error */
1417 }
1418
1419 /*
1420 * Punt --
1421 * Major exception once jobs are being created. Kills all jobs, prints
1422 * a message and exits.
1423 *
1424 * Results:
1425 * None
1426 *
1427 * Side Effects:
1428 * All children are killed indiscriminately and the program Lib_Exits
1429 */
1430 /* VARARGS */
1431 void
1432 #ifdef __STDC__
1433 Punt(char *fmt, ...)
1434 #else
1435 Punt(va_alist)
1436 va_dcl
1437 #endif
1438 {
1439 va_list ap;
1440 #ifdef __STDC__
1441 va_start(ap, fmt);
1442 #else
1443 char *fmt;
1444
1445 va_start(ap);
1446 fmt = va_arg(ap, char *);
1447 #endif
1448
1449 (void)fprintf(stderr, "%s: ", progname);
1450 (void)vfprintf(stderr, fmt, ap);
1451 va_end(ap);
1452 (void)fprintf(stderr, "\n");
1453 (void)fflush(stderr);
1454
1455 PrintOnError(NULL);
1456
1457 DieHorribly();
1458 }
1459
1460 /*-
1461 * DieHorribly --
1462 * Exit without giving a message.
1463 *
1464 * Results:
1465 * None
1466 *
1467 * Side Effects:
1468 * A big one...
1469 */
1470 void
1471 DieHorribly()
1472 {
1473 if (jobsRunning)
1474 Job_AbortAll();
1475 if (DEBUG(GRAPH2))
1476 Targ_PrintGraph(2);
1477 Trace_Log(MAKEERROR, 0);
1478 exit(2); /* Not 1, so -q can distinguish error */
1479 }
1480
1481 /*
1482 * Finish --
1483 * Called when aborting due to errors in child shell to signal
1484 * abnormal exit.
1485 *
1486 * Results:
1487 * None
1488 *
1489 * Side Effects:
1490 * The program exits
1491 */
1492 void
1493 Finish(errors)
1494 int errors; /* number of errors encountered in Make_Make */
1495 {
1496 Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1497 }
1498
1499 /*
1500 * emalloc --
1501 * malloc, but die on error.
1502 */
1503 void *
1504 emalloc(len)
1505 size_t len;
1506 {
1507 void *p;
1508
1509 if ((p = malloc(len)) == NULL)
1510 enomem();
1511 return(p);
1512 }
1513
1514 /*
1515 * estrdup --
1516 * strdup, but die on error.
1517 */
1518 char *
1519 estrdup(str)
1520 const char *str;
1521 {
1522 char *p;
1523
1524 if ((p = strdup(str)) == NULL)
1525 enomem();
1526 return(p);
1527 }
1528
1529 /*
1530 * erealloc --
1531 * realloc, but die on error.
1532 */
1533 void *
1534 erealloc(ptr, size)
1535 void *ptr;
1536 size_t size;
1537 {
1538 if ((ptr = realloc(ptr, size)) == NULL)
1539 enomem();
1540 return(ptr);
1541 }
1542
1543 /*
1544 * enomem --
1545 * die when out of memory.
1546 */
1547 void
1548 enomem()
1549 {
1550 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
1551 exit(2);
1552 }
1553
1554 /*
1555 * enunlink --
1556 * Remove a file carefully, avoiding directories.
1557 */
1558 int
1559 eunlink(file)
1560 const char *file;
1561 {
1562 struct stat st;
1563
1564 if (lstat(file, &st) == -1)
1565 return -1;
1566
1567 if (S_ISDIR(st.st_mode)) {
1568 errno = EISDIR;
1569 return -1;
1570 }
1571 return unlink(file);
1572 }
1573
1574 /*
1575 * execError --
1576 * Print why exec failed, avoiding stdio.
1577 */
1578 void
1579 execError(av)
1580 const char *av;
1581 {
1582 #ifdef USE_IOVEC
1583 int i = 0;
1584 struct iovec iov[6];
1585 #define IOADD(s) \
1586 (void)(iov[i].iov_base = (s), \
1587 iov[i].iov_len = strlen(iov[i].iov_base), \
1588 i++)
1589 #else
1590 #define IOADD (void)write(2, s, strlen(s))
1591 #endif
1592
1593 IOADD(progname);
1594 IOADD(": Exec of `");
1595 IOADD((char *)av);
1596 IOADD("' failed (");
1597 IOADD(strerror(errno));
1598 IOADD(")\n");
1599
1600 #ifdef USE_IOVEC
1601 (void)writev(2, iov, 6);
1602 #endif
1603 }
1604
1605 /*
1606 * usage --
1607 * exit with usage message
1608 */
1609 static void
1610 usage()
1611 {
1612 (void)fprintf(stderr,
1613 "Usage: %s [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
1614 [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
1615 [variable=value] [target ...]\n", progname);
1616 exit(2);
1617 }
1618
1619
1620 int
1621 PrintAddr(a, b)
1622 ClientData a;
1623 ClientData b;
1624 {
1625 printf("%lx ", (unsigned long) a);
1626 return b ? 0 : 0;
1627 }
1628
1629
1630
1631 void
1632 PrintOnError(s)
1633 char *s;
1634 {
1635 char tmp[64];
1636
1637 if (s)
1638 printf("%s", s);
1639
1640 printf("\n%s: stopped in %s\n", progname, curdir);
1641 strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
1642 sizeof(tmp) - 1);
1643 s = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
1644 if (s && *s)
1645 printf("%s", s);
1646 }
1647
1648 void
1649 Main_ExportMAKEFLAGS(first)
1650 Boolean first;
1651 {
1652 static int once = 1;
1653 char tmp[64];
1654 char *s;
1655
1656 if (once != first)
1657 return;
1658 once = 0;
1659
1660 strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
1661 sizeof(tmp));
1662 s = Var_Subst(NULL, tmp, VAR_CMD, 0);
1663 if (s && *s) {
1664 #ifdef POSIX
1665 setenv("MAKEFLAGS", s, 1);
1666 #else
1667 setenv("MAKE", s, 1);
1668 #endif
1669 }
1670 }
1671