main.c revision 1.77 1 /* $NetBSD: main.c,v 1.77 2001/11/11 21:40:05 tv 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.77 2001/11/11 21:40:05 tv 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.77 2001/11/11 21:40:05 tv 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 rc = TRUE;
486 }
487 }
488
489 if (p)
490 free(p);
491 return rc;
492 }
493
494
495 /*-
496 * main --
497 * The main function, for obvious reasons. Initializes variables
498 * and a few modules, then parses the arguments give it in the
499 * environment and on the command line. Reads the system makefile
500 * followed by either Makefile, makefile or the file given by the
501 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
502 * flags it has received by then uses either the Make or the Compat
503 * module to create the initial list of targets.
504 *
505 * Results:
506 * If -q was given, exits -1 if anything was out-of-date. Else it exits
507 * 0.
508 *
509 * Side Effects:
510 * The program exits when done. Targets are created. etc. etc. etc.
511 */
512 int
513 main(argc, argv)
514 int argc;
515 char **argv;
516 {
517 Lst targs; /* target nodes to create -- passed to Make_Init */
518 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
519 struct stat sb, sa;
520 char *p1, *path, *pwd;
521 char mdpath[MAXPATHLEN];
522 char *machine = getenv("MACHINE");
523 char *machine_arch = getenv("MACHINE_ARCH");
524 char *syspath = getenv("MAKESYSPATH");
525 Lst sysMkPath; /* Path of sys.mk */
526 char *cp = NULL, *start;
527 /* avoid faults on read-only strings */
528 static char defsyspath[] = _PATH_DEFSYSPATH;
529
530 if ((progname = strrchr(argv[0], '/')) != NULL)
531 progname++;
532 else
533 progname = argv[0];
534 #ifdef RLIMIT_NOFILE
535 /*
536 * get rid of resource limit on file descriptors
537 */
538 {
539 struct rlimit rl;
540 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
541 rl.rlim_cur != rl.rlim_max) {
542 rl.rlim_cur = rl.rlim_max;
543 (void) setrlimit(RLIMIT_NOFILE, &rl);
544 }
545 }
546 #endif
547 /*
548 * Find where we are and take care of PWD for the automounter...
549 * All this code is so that we know where we are when we start up
550 * on a different machine with pmake.
551 */
552 if (getcwd(curdir, MAXPATHLEN) == NULL) {
553 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
554 exit(2);
555 }
556
557 if (stat(curdir, &sa) == -1) {
558 (void)fprintf(stderr, "%s: %s: %s.\n",
559 progname, curdir, strerror(errno));
560 exit(2);
561 }
562
563 /*
564 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
565 * since the value of curdir can very depending on how we got
566 * here. Ie sitting at a shell prompt (shell that provides $PWD)
567 * or via subdir.mk in which case its likely a shell which does
568 * not provide it.
569 * So, to stop it breaking this case only, we ignore PWD if
570 * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
571 */
572 if ((pwd = getenv("PWD")) != NULL && getenv("MAKEOBJDIRPREFIX") == NULL) {
573 const char *makeobjdir = getenv("MAKEOBJDIR");
574
575 if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
576 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
577 sa.st_dev == sb.st_dev)
578 (void) strncpy(curdir, pwd, MAXPATHLEN);
579 }
580 }
581
582 /*
583 * Get the name of this type of MACHINE from utsname
584 * so we can share an executable for similar machines.
585 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
586 *
587 * Note that both MACHINE and MACHINE_ARCH are decided at
588 * run-time.
589 */
590 if (!machine) {
591 #ifndef MAKE_BOOTSTRAP
592 struct utsname utsname;
593
594 if (uname(&utsname) == -1) {
595 (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
596 strerror(errno));
597 exit(2);
598 }
599 machine = utsname.machine;
600 #else
601 machine = MACHINE;
602 #endif
603 }
604
605 if (!machine_arch) {
606 #ifndef MACHINE_ARCH
607 #ifdef __ARCHITECTURE__
608 machine_arch = __ARCHITECTURE__;
609 #else
610 machine_arch = "unknown"; /* XXX: no uname -p yet */
611 #endif
612 #else
613 machine_arch = MACHINE_ARCH;
614 #endif
615 }
616
617 /*
618 * Just in case MAKEOBJDIR wants us to do something tricky.
619 */
620 Var_Init(); /* Initialize the lists of variables for
621 * parsing arguments */
622 Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
623 Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
624 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
625 #ifdef MAKE_VERSION
626 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
627 #endif
628 Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
629
630 /*
631 * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that,
632 * MAKEOBJDIR is set in the environment, try only that value
633 * and fall back to .CURDIR if it does not exist.
634 *
635 * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and
636 * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
637 * of these paths exist, just use .CURDIR.
638 */
639 (void) Main_SetObjdir(curdir);
640 if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) {
641 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir);
642 (void) Main_SetObjdir(mdpath);
643 } else if ((path = getenv("MAKEOBJDIR")) != NULL) {
644 (void) Main_SetObjdir(path);
645 } else {
646 (void) snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine);
647 if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) {
648 (void) snprintf(mdpath, MAXPATHLEN, "%s%s",
649 _PATH_OBJDIRPREFIX, curdir);
650 (void) Main_SetObjdir(mdpath);
651 }
652 }
653
654 create = Lst_Init(FALSE);
655 makefiles = Lst_Init(FALSE);
656 printVars = FALSE;
657 variables = Lst_Init(FALSE);
658 beSilent = FALSE; /* Print commands as executed */
659 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
660 noExecute = FALSE; /* Execute all commands */
661 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
662 keepgoing = FALSE; /* Stop on error */
663 allPrecious = FALSE; /* Remove targets when interrupted */
664 queryFlag = FALSE; /* This is not just a check-run */
665 noBuiltins = FALSE; /* Read the built-in rules */
666 touchFlag = FALSE; /* Actually update targets */
667 usePipes = TRUE; /* Catch child output in pipes */
668 debug = 0; /* No debug verbosity, please. */
669 jobsRunning = FALSE;
670
671 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
672 #ifdef REMOTE
673 maxJobs = DEFMAXJOBS; /* Set default max concurrency */
674 #else
675 maxJobs = maxLocal;
676 #endif
677 compatMake = FALSE; /* No compat mode */
678
679
680 /*
681 * Initialize the parsing, directory and variable modules to prepare
682 * for the reading of inclusion paths and variable settings on the
683 * command line
684 */
685
686 /*
687 * Initialize directory structures so -I flags can be processed
688 * correctly.
689 */
690 Dir_Init(curdir);
691 Parse_Init(); /* Need to initialize the paths of #include
692 * directories */
693
694 /*
695 * Initialize various variables.
696 * MAKE also gets this name, for compatibility
697 * .MAKEFLAGS gets set to the empty string just in case.
698 * MFLAGS also gets initialized empty, for compatibility.
699 */
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
706 /*
707 * First snag any flags out of the MAKE environment variable.
708 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
709 * in a different format).
710 */
711 #ifdef POSIX
712 Main_ParseArgLine(getenv("MAKEFLAGS"));
713 #else
714 Main_ParseArgLine(getenv("MAKE"));
715 #endif
716
717 MainParseArgs(argc, argv);
718
719 /*
720 * Be compatible if user did not specify -j and did not explicitly
721 * turned compatibility on
722 */
723 if (!compatMake && !forceJobs) {
724 compatMake = TRUE;
725 }
726
727 /*
728 * Initialize archive, target and suffix modules in preparation for
729 * parsing the makefile(s)
730 */
731 Arch_Init();
732 Targ_Init();
733 Suff_Init();
734 Trace_Init(tracefile);
735
736 DEFAULT = NILGNODE;
737 (void)time(&now);
738
739 Trace_Log(MAKESTART, NULL);
740
741 /*
742 * Set up the .TARGETS variable to contain the list of targets to be
743 * created. If none specified, make the variable empty -- the parser
744 * will fill the thing in with the default or .MAIN target.
745 */
746 if (!Lst_IsEmpty(create)) {
747 LstNode ln;
748
749 for (ln = Lst_First(create); ln != NILLNODE;
750 ln = Lst_Succ(ln)) {
751 char *name = (char *)Lst_Datum(ln);
752
753 Var_Append(".TARGETS", name, VAR_GLOBAL);
754 }
755 } else
756 Var_Set(".TARGETS", "", VAR_GLOBAL, 0);
757
758
759 /*
760 * If no user-supplied system path was given (through the -m option)
761 * add the directories from the DEFSYSPATH (more than one may be given
762 * as dir1:...:dirn) to the system include path.
763 */
764 if (syspath == NULL || *syspath == '\0')
765 syspath = defsyspath;
766 else
767 syspath = strdup(syspath);
768
769 for (start = syspath; *start != '\0'; start = cp) {
770 for (cp = start; *cp != '\0' && *cp != ':'; cp++)
771 continue;
772 if (*cp == '\0') {
773 (void) Dir_AddDir(defIncPath, start);
774 } else {
775 *cp++ = '\0';
776 (void) Dir_AddDir(defIncPath, start);
777 }
778 }
779 if (syspath != defsyspath)
780 free(syspath);
781
782 /*
783 * Read in the built-in rules first, followed by the specified
784 * makefile, if it was (makefile != (char *) NULL), or the default
785 * Makefile and makefile, in that order, if it wasn't.
786 */
787 if (!noBuiltins) {
788 LstNode ln;
789
790 sysMkPath = Lst_Init (FALSE);
791 Dir_Expand(_PATH_DEFSYSMK,
792 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
793 sysMkPath);
794 if (Lst_IsEmpty(sysMkPath))
795 Fatal("%s: no system rules (%s).", progname,
796 _PATH_DEFSYSMK);
797 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
798 if (ln != NILLNODE)
799 Fatal("%s: cannot open %s.", progname,
800 (char *)Lst_Datum(ln));
801 }
802
803 if (!Lst_IsEmpty(makefiles)) {
804 LstNode ln;
805
806 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
807 if (ln != NILLNODE)
808 Fatal("%s: cannot open %s.", progname,
809 (char *)Lst_Datum(ln));
810 } else if (!ReadMakefile("makefile", NULL))
811 (void)ReadMakefile("Makefile", NULL);
812
813 (void)ReadMakefile(".depend", NULL);
814
815 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
816 if (p1)
817 free(p1);
818
819 if (!jobServer && !compatMake)
820 Job_ServerStart(maxJobs);
821 if (DEBUG(JOB))
822 printf("job_pipe %d %d, maxjobs %d maxlocal %d compat %d\n", job_pipe[0], job_pipe[1], maxJobs,
823 maxLocal, compatMake);
824
825 Main_ExportMAKEFLAGS(TRUE); /* initial export */
826
827 Check_Cwd_av(0, NULL, 0); /* initialize it */
828
829
830 /*
831 * For compatibility, look at the directories in the VPATH variable
832 * and add them to the search path, if the variable is defined. The
833 * variable's value is in the same format as the PATH envariable, i.e.
834 * <directory>:<directory>:<directory>...
835 */
836 if (Var_Exists("VPATH", VAR_CMD)) {
837 char *vpath, *path, *cp, savec;
838 /*
839 * GCC stores string constants in read-only memory, but
840 * Var_Subst will want to write this thing, so store it
841 * in an array
842 */
843 static char VPATH[] = "${VPATH}";
844
845 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
846 path = vpath;
847 do {
848 /* skip to end of directory */
849 for (cp = path; *cp != ':' && *cp != '\0'; cp++)
850 continue;
851 /* Save terminator character so know when to stop */
852 savec = *cp;
853 *cp = '\0';
854 /* Add directory to search path */
855 (void) Dir_AddDir(dirSearchPath, path);
856 *cp = savec;
857 path = cp + 1;
858 } while (savec == ':');
859 (void)free((Address)vpath);
860 }
861
862 /*
863 * Now that all search paths have been read for suffixes et al, it's
864 * time to add the default search path to their lists...
865 */
866 Suff_DoPaths();
867
868 /*
869 * Propagate attributes through :: dependency lists.
870 */
871 Targ_Propagate();
872
873 /* print the initial graph, if the user requested it */
874 if (DEBUG(GRAPH1))
875 Targ_PrintGraph(1);
876
877 /* print the values of any variables requested by the user */
878 if (printVars) {
879 LstNode ln;
880
881 for (ln = Lst_First(variables); ln != NILLNODE;
882 ln = Lst_Succ(ln)) {
883 char *value = Var_Value((char *)Lst_Datum(ln),
884 VAR_GLOBAL, &p1);
885
886 printf("%s\n", value ? value : "");
887 if (p1)
888 free(p1);
889 }
890 }
891
892 /*
893 * Have now read the entire graph and need to make a list of targets
894 * to create. If none was given on the command line, we consult the
895 * parsing module to find the main target(s) to create.
896 */
897 if (Lst_IsEmpty(create))
898 targs = Parse_MainName();
899 else
900 targs = Targ_FindList(create, TARG_CREATE);
901
902 if (!compatMake && !printVars) {
903 /*
904 * Initialize job module before traversing the graph, now that
905 * any .BEGIN and .END targets have been read. This is done
906 * only if the -q flag wasn't given (to prevent the .BEGIN from
907 * being executed should it exist).
908 */
909 if (!queryFlag) {
910 if (maxLocal == -1)
911 maxLocal = maxJobs;
912 Job_Init(maxJobs, maxLocal);
913 jobsRunning = TRUE;
914 }
915
916 /* Traverse the graph, checking on all the targets */
917 outOfDate = Make_Run(targs);
918 } else if (!printVars) {
919 /*
920 * Compat_Init will take care of creating all the targets as
921 * well as initializing the module.
922 */
923 Compat_Run(targs);
924 }
925
926 #ifdef CLEANUP
927 Lst_Destroy(targs, NOFREE);
928 Lst_Destroy(variables, NOFREE);
929 Lst_Destroy(makefiles, NOFREE);
930 Lst_Destroy(create, (void (*) __P((ClientData))) free);
931 #endif
932
933 /* print the graph now it's been processed if the user requested it */
934 if (DEBUG(GRAPH2))
935 Targ_PrintGraph(2);
936
937 Trace_Log(MAKEEND, 0);
938
939 Suff_End();
940 Targ_End();
941 Arch_End();
942 Var_End();
943 Parse_End();
944 Dir_End();
945 Job_End();
946 Trace_End();
947
948 if (queryFlag && outOfDate)
949 return(1);
950 else
951 return(0);
952 }
953
954 /*-
955 * ReadMakefile --
956 * Open and parse the given makefile.
957 *
958 * Results:
959 * TRUE if ok. FALSE if couldn't open file.
960 *
961 * Side Effects:
962 * lots
963 */
964 static Boolean
965 ReadMakefile(p, q)
966 ClientData p, q;
967 {
968 char *fname = p; /* makefile to read */
969 FILE *stream;
970 size_t len = MAXPATHLEN;
971 char *name, *path = emalloc(len);
972 int setMAKEFILE;
973
974 if (!strcmp(fname, "-")) {
975 Parse_File("(stdin)", stdin);
976 Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
977 } else {
978 setMAKEFILE = strcmp(fname, ".depend");
979
980 /* if we've chdir'd, rebuild the path name */
981 if (strcmp(curdir, objdir) && *fname != '/') {
982 size_t plen = strlen(curdir) + strlen(fname) + 2;
983 if (len < plen)
984 path = erealloc(path, len = 2 * plen);
985
986 (void)snprintf(path, len, "%s/%s", curdir, fname);
987 if ((stream = fopen(path, "r")) != NULL) {
988 fname = path;
989 goto found;
990 }
991 } else if ((stream = fopen(fname, "r")) != NULL)
992 goto found;
993 /* look in -I and system include directories. */
994 name = Dir_FindFile(fname, parseIncPath);
995 if (!name)
996 name = Dir_FindFile(fname,
997 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
998 if (!name || !(stream = fopen(name, "r"))) {
999 free(path);
1000 return(FALSE);
1001 }
1002 fname = name;
1003 /*
1004 * set the MAKEFILE variable desired by System V fans -- the
1005 * placement of the setting here means it gets set to the last
1006 * makefile specified, as it is set by SysV make.
1007 */
1008 found:
1009 if (setMAKEFILE)
1010 Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
1011 Parse_File(fname, stream);
1012 (void)fclose(stream);
1013 }
1014 free(path);
1015 return(TRUE);
1016 }
1017
1018
1019 /*
1020 * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR
1021 * in situations that would not arrise with ./obj (links or not).
1022 * This tends to break things like:
1023 *
1024 * build:
1025 * ${MAKE} includes
1026 *
1027 * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as
1028 * opposed to an argument) in a command line and if so returns
1029 * ${.CURDIR} so caller can chdir() so that the assumptions made by
1030 * the Makefile hold true.
1031 *
1032 * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped.
1033 *
1034 * The chdir() only happens in the child process, and does nothing if
1035 * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it
1036 * should not break anything. Also if NOCHECKMAKECHDIR is set we
1037 * do nothing - to ensure historic semantics can be retained.
1038 */
1039 static int Check_Cwd_Off = 0;
1040
1041 static char *
1042 Check_Cwd_av(ac, av, copy)
1043 int ac;
1044 char **av;
1045 int copy;
1046 {
1047 static char *make[4];
1048 static char *curdir = NULL;
1049 char *cp, **mp;
1050 int is_cmd, next_cmd;
1051 int i;
1052 int n;
1053
1054 if (Check_Cwd_Off)
1055 return NULL;
1056
1057 if (make[0] == NULL) {
1058 if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
1059 Check_Cwd_Off = 1;
1060 return NULL;
1061 }
1062
1063 make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
1064 if ((make[0] = strrchr(make[1], '/')) == NULL) {
1065 make[0] = make[1];
1066 make[1] = NULL;
1067 } else
1068 ++make[0];
1069 make[2] = NULL;
1070 curdir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
1071 }
1072 if (ac == 0 || av == NULL)
1073 return NULL; /* initialization only */
1074
1075 if (getenv("MAKEOBJDIR") == NULL &&
1076 getenv("MAKEOBJDIRPREFIX") == NULL)
1077 return NULL;
1078
1079
1080 next_cmd = 1;
1081 for (i = 0; i < ac; ++i) {
1082 is_cmd = next_cmd;
1083
1084 n = strlen(av[i]);
1085 cp = &(av[i])[n - 1];
1086 if (strspn(av[i], "|&;") == n) {
1087 next_cmd = 1;
1088 continue;
1089 } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
1090 next_cmd = 1;
1091 if (copy) {
1092 do {
1093 *cp-- = '\0';
1094 } while (*cp == ';' || *cp == '&' || *cp == '|' ||
1095 *cp == ')' || *cp == '}') ;
1096 } else {
1097 /*
1098 * XXX this should not happen.
1099 */
1100 fprintf(stderr, "WARNING: raw arg ends in shell meta '%s'\n",
1101 av[i]);
1102 }
1103 } else
1104 next_cmd = 0;
1105
1106 cp = av[i];
1107 if (*cp == ';' || *cp == '&' || *cp == '|')
1108 is_cmd = 1;
1109
1110 #ifdef check_cwd_debug
1111 fprintf(stderr, "av[%d] == %s '%s'",
1112 i, (is_cmd) ? "cmd" : "arg", av[i]);
1113 #endif
1114 if (is_cmd != 0) {
1115 if (*cp == '(' || *cp == '{' ||
1116 *cp == ';' || *cp == '&' || *cp == '|') {
1117 do {
1118 ++cp;
1119 } while (*cp == '(' || *cp == '{' ||
1120 *cp == ';' || *cp == '&' || *cp == '|');
1121 if (*cp == '\0') {
1122 next_cmd = 1;
1123 continue;
1124 }
1125 }
1126 if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
1127 #ifdef check_cwd_debug
1128 fprintf(stderr, " == cd, done.\n");
1129 #endif
1130 return NULL;
1131 }
1132 for (mp = make; *mp != NULL; ++mp) {
1133 n = strlen(*mp);
1134 if (strcmp(cp, *mp) == 0) {
1135 #ifdef check_cwd_debug
1136 fprintf(stderr, " %s == '%s', chdir(%s)\n",
1137 cp, *mp, curdir);
1138 #endif
1139 return curdir;
1140 }
1141 }
1142 }
1143 #ifdef check_cwd_debug
1144 fprintf(stderr, "\n");
1145 #endif
1146 }
1147 return NULL;
1148 }
1149
1150 char *
1151 Check_Cwd_Cmd(cmd)
1152 char *cmd;
1153 {
1154 char *cp, *bp, **av;
1155 int ac;
1156
1157 if (Check_Cwd_Off)
1158 return NULL;
1159
1160 if (cmd) {
1161 av = brk_string(cmd, &ac, TRUE, &bp);
1162 #ifdef check_cwd_debug
1163 fprintf(stderr, "splitting: '%s' -> %d words\n",
1164 cmd, ac);
1165 #endif
1166 } else {
1167 ac = 0;
1168 av = NULL;
1169 bp = NULL;
1170 }
1171 cp = Check_Cwd_av(ac, av, 1);
1172 if (bp) {
1173 free(av);
1174 free(bp);
1175 }
1176 return cp;
1177 }
1178
1179 void
1180 Check_Cwd(argv)
1181 char **argv;
1182 {
1183 char *cp;
1184 int ac;
1185
1186 if (Check_Cwd_Off)
1187 return;
1188
1189 for (ac = 0; argv[ac] != NULL; ++ac)
1190 /* NOTHING */;
1191 if (ac == 3 && *argv[1] == '-') {
1192 cp = Check_Cwd_Cmd(argv[2]);
1193 } else {
1194 cp = Check_Cwd_av(ac, argv, 0);
1195 }
1196 if (cp) {
1197 chdir(cp);
1198 }
1199 }
1200
1201 /*-
1202 * Cmd_Exec --
1203 * Execute the command in cmd, and return the output of that command
1204 * in a string.
1205 *
1206 * Results:
1207 * A string containing the output of the command, or the empty string
1208 * If err is not NULL, it contains the reason for the command failure
1209 *
1210 * Side Effects:
1211 * The string must be freed by the caller.
1212 */
1213 char *
1214 Cmd_Exec(cmd, err)
1215 char *cmd;
1216 char **err;
1217 {
1218 char *args[4]; /* Args for invoking the shell */
1219 int fds[2]; /* Pipe streams */
1220 int cpid; /* Child PID */
1221 int pid; /* PID from wait() */
1222 char *res; /* result */
1223 int status; /* command exit status */
1224 Buffer buf; /* buffer to store the result */
1225 char *cp;
1226 int cc;
1227
1228
1229 *err = NULL;
1230
1231 /*
1232 * Set up arguments for shell
1233 */
1234 args[0] = "sh";
1235 args[1] = "-c";
1236 args[2] = cmd;
1237 args[3] = NULL;
1238
1239 /*
1240 * Open a pipe for fetching its output
1241 */
1242 if (pipe(fds) == -1) {
1243 *err = "Couldn't create pipe for \"%s\"";
1244 goto bad;
1245 }
1246
1247 /*
1248 * Fork
1249 */
1250 switch (cpid = vfork()) {
1251 case 0:
1252 /*
1253 * Close input side of pipe
1254 */
1255 (void) close(fds[0]);
1256
1257 /*
1258 * Duplicate the output stream to the shell's output, then
1259 * shut the extra thing down. Note we don't fetch the error
1260 * stream...why not? Why?
1261 */
1262 (void) dup2(fds[1], 1);
1263 (void) close(fds[1]);
1264
1265 (void) execv("/bin/sh", args);
1266 _exit(1);
1267 /*NOTREACHED*/
1268
1269 case -1:
1270 *err = "Couldn't exec \"%s\"";
1271 goto bad;
1272
1273 default:
1274 /*
1275 * No need for the writing half
1276 */
1277 (void) close(fds[1]);
1278
1279 buf = Buf_Init (MAKE_BSIZE);
1280
1281 do {
1282 char result[BUFSIZ];
1283 cc = read(fds[0], result, sizeof(result));
1284 if (cc > 0)
1285 Buf_AddBytes(buf, cc, (Byte *) result);
1286 }
1287 while (cc > 0 || (cc == -1 && errno == EINTR));
1288
1289 /*
1290 * Close the input side of the pipe.
1291 */
1292 (void) close(fds[0]);
1293
1294 /*
1295 * Wait for the process to exit.
1296 */
1297 while(((pid = wait(&status)) != cpid) && (pid >= 0))
1298 continue;
1299
1300 res = (char *)Buf_GetAll (buf, &cc);
1301 Buf_Destroy (buf, FALSE);
1302
1303 if (cc == 0)
1304 *err = "Couldn't read shell's output for \"%s\"";
1305
1306 if (status)
1307 *err = "\"%s\" returned non-zero status";
1308
1309 /*
1310 * Null-terminate the result, convert newlines to spaces and
1311 * install it in the variable.
1312 */
1313 res[cc] = '\0';
1314 cp = &res[cc];
1315
1316 if (cc > 0 && *--cp == '\n') {
1317 /*
1318 * A final newline is just stripped
1319 */
1320 *cp-- = '\0';
1321 }
1322 while (cp >= res) {
1323 if (*cp == '\n') {
1324 *cp = ' ';
1325 }
1326 cp--;
1327 }
1328 break;
1329 }
1330 return res;
1331 bad:
1332 res = emalloc(1);
1333 *res = '\0';
1334 return res;
1335 }
1336
1337 /*-
1338 * Error --
1339 * Print an error message given its format.
1340 *
1341 * Results:
1342 * None.
1343 *
1344 * Side Effects:
1345 * The message is printed.
1346 */
1347 /* VARARGS */
1348 void
1349 #ifdef __STDC__
1350 Error(char *fmt, ...)
1351 #else
1352 Error(va_alist)
1353 va_dcl
1354 #endif
1355 {
1356 va_list ap;
1357 #ifdef __STDC__
1358 va_start(ap, fmt);
1359 #else
1360 char *fmt;
1361
1362 va_start(ap);
1363 fmt = va_arg(ap, char *);
1364 #endif
1365 fprintf(stderr, "%s: ", progname);
1366 (void)vfprintf(stderr, fmt, ap);
1367 va_end(ap);
1368 (void)fprintf(stderr, "\n");
1369 (void)fflush(stderr);
1370 }
1371
1372 /*-
1373 * Fatal --
1374 * Produce a Fatal error message. If jobs are running, waits for them
1375 * to finish.
1376 *
1377 * Results:
1378 * None
1379 *
1380 * Side Effects:
1381 * The program exits
1382 */
1383 /* VARARGS */
1384 void
1385 #ifdef __STDC__
1386 Fatal(char *fmt, ...)
1387 #else
1388 Fatal(va_alist)
1389 va_dcl
1390 #endif
1391 {
1392 va_list ap;
1393 #ifdef __STDC__
1394 va_start(ap, fmt);
1395 #else
1396 char *fmt;
1397
1398 va_start(ap);
1399 fmt = va_arg(ap, char *);
1400 #endif
1401 if (jobsRunning)
1402 Job_Wait();
1403 Job_TokenFlush();
1404
1405 (void)vfprintf(stderr, fmt, ap);
1406 va_end(ap);
1407 (void)fprintf(stderr, "\n");
1408 (void)fflush(stderr);
1409
1410 PrintOnError(NULL);
1411
1412 if (DEBUG(GRAPH2))
1413 Targ_PrintGraph(2);
1414 Trace_Log(MAKEERROR, 0);
1415 exit(2); /* Not 1 so -q can distinguish error */
1416 }
1417
1418 /*
1419 * Punt --
1420 * Major exception once jobs are being created. Kills all jobs, prints
1421 * a message and exits.
1422 *
1423 * Results:
1424 * None
1425 *
1426 * Side Effects:
1427 * All children are killed indiscriminately and the program Lib_Exits
1428 */
1429 /* VARARGS */
1430 void
1431 #ifdef __STDC__
1432 Punt(char *fmt, ...)
1433 #else
1434 Punt(va_alist)
1435 va_dcl
1436 #endif
1437 {
1438 va_list ap;
1439 #ifdef __STDC__
1440 va_start(ap, fmt);
1441 #else
1442 char *fmt;
1443
1444 va_start(ap);
1445 fmt = va_arg(ap, char *);
1446 #endif
1447
1448 (void)fprintf(stderr, "%s: ", progname);
1449 (void)vfprintf(stderr, fmt, ap);
1450 va_end(ap);
1451 (void)fprintf(stderr, "\n");
1452 (void)fflush(stderr);
1453
1454 PrintOnError(NULL);
1455
1456 DieHorribly();
1457 }
1458
1459 /*-
1460 * DieHorribly --
1461 * Exit without giving a message.
1462 *
1463 * Results:
1464 * None
1465 *
1466 * Side Effects:
1467 * A big one...
1468 */
1469 void
1470 DieHorribly()
1471 {
1472 if (jobsRunning)
1473 Job_AbortAll();
1474 if (DEBUG(GRAPH2))
1475 Targ_PrintGraph(2);
1476 Trace_Log(MAKEERROR, 0);
1477 exit(2); /* Not 1, so -q can distinguish error */
1478 }
1479
1480 /*
1481 * Finish --
1482 * Called when aborting due to errors in child shell to signal
1483 * abnormal exit.
1484 *
1485 * Results:
1486 * None
1487 *
1488 * Side Effects:
1489 * The program exits
1490 */
1491 void
1492 Finish(errors)
1493 int errors; /* number of errors encountered in Make_Make */
1494 {
1495 Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1496 }
1497
1498 /*
1499 * emalloc --
1500 * malloc, but die on error.
1501 */
1502 void *
1503 emalloc(len)
1504 size_t len;
1505 {
1506 void *p;
1507
1508 if ((p = malloc(len)) == NULL)
1509 enomem();
1510 return(p);
1511 }
1512
1513 /*
1514 * estrdup --
1515 * strdup, but die on error.
1516 */
1517 char *
1518 estrdup(str)
1519 const char *str;
1520 {
1521 char *p;
1522
1523 if ((p = strdup(str)) == NULL)
1524 enomem();
1525 return(p);
1526 }
1527
1528 /*
1529 * erealloc --
1530 * realloc, but die on error.
1531 */
1532 void *
1533 erealloc(ptr, size)
1534 void *ptr;
1535 size_t size;
1536 {
1537 if ((ptr = realloc(ptr, size)) == NULL)
1538 enomem();
1539 return(ptr);
1540 }
1541
1542 /*
1543 * enomem --
1544 * die when out of memory.
1545 */
1546 void
1547 enomem()
1548 {
1549 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
1550 exit(2);
1551 }
1552
1553 /*
1554 * enunlink --
1555 * Remove a file carefully, avoiding directories.
1556 */
1557 int
1558 eunlink(file)
1559 const char *file;
1560 {
1561 struct stat st;
1562
1563 if (lstat(file, &st) == -1)
1564 return -1;
1565
1566 if (S_ISDIR(st.st_mode)) {
1567 errno = EISDIR;
1568 return -1;
1569 }
1570 return unlink(file);
1571 }
1572
1573 /*
1574 * execError --
1575 * Print why exec failed, avoiding stdio.
1576 */
1577 void
1578 execError(av)
1579 const char *av;
1580 {
1581 #ifdef USE_IOVEC
1582 int i = 0;
1583 struct iovec iov[6];
1584 #define IOADD(s) \
1585 (void)(iov[i].iov_base = (s), \
1586 iov[i].iov_len = strlen(iov[i].iov_base), \
1587 i++)
1588 #else
1589 #define IOADD (void)write(2, s, strlen(s))
1590 #endif
1591
1592 IOADD(progname);
1593 IOADD(": Exec of `");
1594 IOADD((char *)av);
1595 IOADD("' failed (");
1596 IOADD(strerror(errno));
1597 IOADD(")\n");
1598
1599 #ifdef USE_IOVEC
1600 (void)writev(2, iov, 6);
1601 #endif
1602 }
1603
1604 /*
1605 * usage --
1606 * exit with usage message
1607 */
1608 static void
1609 usage()
1610 {
1611 (void)fprintf(stderr,
1612 "Usage: %s [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
1613 [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
1614 [variable=value] [target ...]\n", progname);
1615 exit(2);
1616 }
1617
1618
1619 int
1620 PrintAddr(a, b)
1621 ClientData a;
1622 ClientData b;
1623 {
1624 printf("%lx ", (unsigned long) a);
1625 return b ? 0 : 0;
1626 }
1627
1628
1629
1630 void
1631 PrintOnError(s)
1632 char *s;
1633 {
1634 char tmp[64];
1635
1636 if (s)
1637 printf("%s", s);
1638
1639 printf("\n%s: stopped in %s\n", progname, curdir);
1640 strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
1641 sizeof(tmp) - 1);
1642 s = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
1643 if (s && *s)
1644 printf("%s", s);
1645 }
1646
1647 void
1648 Main_ExportMAKEFLAGS(first)
1649 Boolean first;
1650 {
1651 static int once = 1;
1652 char tmp[64];
1653 char *s;
1654
1655 if (once != first)
1656 return;
1657 once = 0;
1658
1659 strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
1660 sizeof(tmp));
1661 s = Var_Subst(NULL, tmp, VAR_CMD, 0);
1662 if (s && *s) {
1663 #ifdef POSIX
1664 setenv("MAKEFLAGS", s, 1);
1665 #else
1666 setenv("MAKE", s, 1);
1667 #endif
1668 }
1669 }
1670