main.c revision 1.66 1 /* $NetBSD: main.c,v 1.66 2001/05/29 17:37:52 christos 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.66 2001/05/29 17:37:52 christos 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.66 2001/05/29 17:37:52 christos 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 occured, 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 char * chdir_verify_path __P((char *, char *));
151 static int ReadMakefile __P((ClientData, ClientData));
152 static void usage __P((void));
153
154 static char *curdir; /* startup directory */
155 static char *objdir; /* where we chdir'ed to */
156 char *progname; /* the program name */
157
158 Boolean forceJobs = FALSE;
159
160 extern Lst parseIncPath;
161
162 /*-
163 * MainParseArgs --
164 * Parse a given argument vector. Called from main() and from
165 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
166 *
167 * XXX: Deal with command line overriding .MAKEFLAGS in makefile
168 *
169 * Results:
170 * None
171 *
172 * Side Effects:
173 * Various global and local flags will be set depending on the flags
174 * given
175 */
176 static void
177 MainParseArgs(argc, argv)
178 int argc;
179 char **argv;
180 {
181 char *p;
182 int c;
183
184 optind = 1; /* since we're called more than once */
185 #ifdef REMOTE
186 # define OPTFLAGS "BD:I:J:L:NPST:V:Wd:ef:ij:km:nqrst"
187 #else
188 # define OPTFLAGS "BD:I:J:NPST:V:Wd:ef:ij:km:nqrst"
189 #endif
190 rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
191 switch(c) {
192 case 'D':
193 Var_Set(optarg, "1", VAR_GLOBAL);
194 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
195 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
196 break;
197 case 'I':
198 Parse_AddIncludeDir(optarg);
199 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
200 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
201 break;
202 case 'J':
203 if (sscanf(optarg, "%d,%d", &job_pipe[0], &job_pipe[1]) != 2) {
204 /* backslash to avoid trigraph ??) */
205 (void)fprintf(stderr,
206 "%s: internal error -- J option malformed (%s?\?)\n",
207 progname, optarg);
208 usage();
209 }
210 if ((fcntl(job_pipe[0], F_GETFD, 0) < 0) ||
211 (fcntl(job_pipe[1], F_GETFD, 0) < 0)) {
212 #if 0
213 (void)fprintf(stderr,
214 "%s: warning -- J descriptors were closed!\n",
215 progname);
216 #endif
217 job_pipe[0] = -1;
218 job_pipe[1] = -1;
219 compatMake = TRUE;
220 } else {
221 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
222 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
223 jobServer = TRUE;
224 }
225 break;
226 case 'V':
227 printVars = TRUE;
228 (void)Lst_AtEnd(variables, (ClientData)optarg);
229 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
230 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
231 break;
232 case 'B':
233 compatMake = TRUE;
234 break;
235 #ifdef REMOTE
236 case 'L':
237 maxLocal = strtol(optarg, &p, 0);
238 if (*p != '\0' || maxLocal < 1) {
239 (void) fprintf(stderr, "%s: illegal argument to -L -- must be positive integer!\n",
240 progname);
241 exit(1);
242 }
243 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
244 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
245 break;
246 #endif
247 case 'N':
248 noExecute = TRUE;
249 noRecursiveExecute = TRUE;
250 Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
251 break;
252 case 'P':
253 usePipes = FALSE;
254 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
255 break;
256 case 'S':
257 keepgoing = FALSE;
258 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
259 break;
260 case 'T':
261 tracefile = estrdup(optarg);
262 Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
263 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
264 break;
265 case 'W':
266 parseWarnFatal = TRUE;
267 break;
268 case 'd': {
269 char *modules = optarg;
270
271 for (; *modules; ++modules)
272 switch (*modules) {
273 case 'A':
274 debug = ~0;
275 break;
276 case 'a':
277 debug |= DEBUG_ARCH;
278 break;
279 case 'c':
280 debug |= DEBUG_COND;
281 break;
282 case 'd':
283 debug |= DEBUG_DIR;
284 break;
285 case 'f':
286 debug |= DEBUG_FOR;
287 break;
288 case 'g':
289 if (modules[1] == '1') {
290 debug |= DEBUG_GRAPH1;
291 ++modules;
292 }
293 else if (modules[1] == '2') {
294 debug |= DEBUG_GRAPH2;
295 ++modules;
296 }
297 break;
298 case 'j':
299 debug |= DEBUG_JOB;
300 break;
301 case 'm':
302 debug |= DEBUG_MAKE;
303 break;
304 case 's':
305 debug |= DEBUG_SUFF;
306 break;
307 case 't':
308 debug |= DEBUG_TARG;
309 break;
310 case 'v':
311 debug |= DEBUG_VAR;
312 break;
313 default:
314 (void)fprintf(stderr,
315 "%s: illegal argument to d option -- %c\n",
316 progname, *modules);
317 usage();
318 }
319 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
320 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
321 break;
322 }
323 case 'e':
324 checkEnvFirst = TRUE;
325 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
326 break;
327 case 'f':
328 (void)Lst_AtEnd(makefiles, (ClientData)optarg);
329 break;
330 case 'i':
331 ignoreErrors = TRUE;
332 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
333 break;
334 case 'j':
335 forceJobs = TRUE;
336 maxJobs = strtol(optarg, &p, 0);
337 if (*p != '\0' || maxJobs < 1) {
338 (void) fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
339 progname);
340 exit(1);
341 }
342 #ifndef REMOTE
343 maxLocal = maxJobs;
344 #endif
345 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
346 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
347 break;
348 case 'k':
349 keepgoing = TRUE;
350 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
351 break;
352 case 'm':
353 (void) Dir_AddDir(sysIncPath, optarg);
354 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
355 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
356 break;
357 case 'n':
358 noExecute = TRUE;
359 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
360 break;
361 case 'q':
362 queryFlag = TRUE;
363 /* Kind of nonsensical, wot? */
364 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
365 break;
366 case 'r':
367 noBuiltins = TRUE;
368 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
369 break;
370 case 's':
371 beSilent = TRUE;
372 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
373 break;
374 case 't':
375 touchFlag = TRUE;
376 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
377 break;
378 default:
379 case '?':
380 usage();
381 }
382 }
383
384 oldVars = TRUE;
385
386 /*
387 * See if the rest of the arguments are variable assignments and
388 * perform them if so. Else take them to be targets and stuff them
389 * on the end of the "create" list.
390 */
391 for (argv += optind, argc -= optind; *argv; ++argv, --argc)
392 if (Parse_IsVar(*argv))
393 Parse_DoVar(*argv, VAR_CMD);
394 else {
395 if (!**argv)
396 Punt("illegal (null) argument.");
397 if (**argv == '-') {
398 if ((*argv)[1])
399 optind = 0; /* -flag... */
400 else
401 optind = 1; /* - */
402 goto rearg;
403 }
404 (void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
405 }
406 }
407
408 /*-
409 * Main_ParseArgLine --
410 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
411 * is encountered and by main() when reading the .MAKEFLAGS envariable.
412 * Takes a line of arguments and breaks it into its
413 * component words and passes those words and the number of them to the
414 * MainParseArgs function.
415 * The line should have all its leading whitespace removed.
416 *
417 * Results:
418 * None
419 *
420 * Side Effects:
421 * Only those that come from the various arguments.
422 */
423 void
424 Main_ParseArgLine(line)
425 char *line; /* Line to fracture */
426 {
427 char **argv; /* Manufactured argument vector */
428 int argc; /* Number of arguments in argv */
429 char *args; /* Space used by the args */
430 char *buf, *p1;
431 char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
432 size_t len;
433
434 if (line == NULL)
435 return;
436 for (; *line == ' '; ++line)
437 continue;
438 if (!*line)
439 return;
440
441 buf = emalloc(len = strlen(line) + strlen(argv0) + 2);
442 (void)snprintf(buf, len, "%s %s", argv0, line);
443 if (p1)
444 free(p1);
445
446 argv = brk_string(buf, &argc, TRUE, &args);
447 free(buf);
448 MainParseArgs(argc, argv);
449
450 free(args);
451 free(argv);
452 }
453
454 char *
455 chdir_verify_path(path, obpath)
456 char *path;
457 char *obpath;
458 {
459 struct stat sb;
460
461 if (strchr(path, '$') != 0) {
462 path = Var_Subst(NULL, path, VAR_GLOBAL, 0);
463 }
464 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
465 if (chdir(path)) {
466 (void)fprintf(stderr, "make warning: %s: %s.\n",
467 path, strerror(errno));
468 return 0;
469 }
470 else {
471 if (path[0] != '/') {
472 (void) snprintf(obpath, MAXPATHLEN, "%s/%s",
473 curdir, path);
474 return obpath;
475 }
476 else
477 return path;
478 }
479 }
480
481 return 0;
482 }
483
484
485 /*-
486 * main --
487 * The main function, for obvious reasons. Initializes variables
488 * and a few modules, then parses the arguments give it in the
489 * environment and on the command line. Reads the system makefile
490 * followed by either Makefile, makefile or the file given by the
491 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
492 * flags it has received by then uses either the Make or the Compat
493 * module to create the initial list of targets.
494 *
495 * Results:
496 * If -q was given, exits -1 if anything was out-of-date. Else it exits
497 * 0.
498 *
499 * Side Effects:
500 * The program exits when done. Targets are created. etc. etc. etc.
501 */
502 int
503 main(argc, argv)
504 int argc;
505 char **argv;
506 {
507 Lst targs; /* target nodes to create -- passed to Make_Init */
508 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
509 struct stat sb, sa;
510 char *p, *p1, *path, *pathp, *pwd;
511 char mdpath[MAXPATHLEN + 1];
512 char obpath[MAXPATHLEN + 1];
513 char cdpath[MAXPATHLEN + 1];
514 char *machine = getenv("MACHINE");
515 char *machine_arch = getenv("MACHINE_ARCH");
516 char *syspath = getenv("MAKESYSPATH");
517 Lst sysMkPath; /* Path of sys.mk */
518 char *cp = NULL, *start;
519 /* avoid faults on read-only strings */
520 static char defsyspath[] = _PATH_DEFSYSPATH;
521
522 if ((progname = strrchr(argv[0], '/')) != NULL)
523 progname++;
524 else
525 progname = argv[0];
526 #ifdef RLIMIT_NOFILE
527 /*
528 * get rid of resource limit on file descriptors
529 */
530 {
531 struct rlimit rl;
532 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
533 rl.rlim_cur != rl.rlim_max) {
534 rl.rlim_cur = rl.rlim_max;
535 (void) setrlimit(RLIMIT_NOFILE, &rl);
536 }
537 }
538 #endif
539 /*
540 * Find where we are and take care of PWD for the automounter...
541 * All this code is so that we know where we are when we start up
542 * on a different machine with pmake.
543 */
544 curdir = cdpath;
545 if (getcwd(curdir, MAXPATHLEN) == NULL) {
546 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
547 exit(2);
548 }
549
550 if (stat(curdir, &sa) == -1) {
551 (void)fprintf(stderr, "%s: %s: %s.\n",
552 progname, curdir, strerror(errno));
553 exit(2);
554 }
555
556 /*
557 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
558 * since the value of curdir can very depending on how we got
559 * here. Ie sitting at a shell prompt (shell that provides $PWD)
560 * or via subdir.mk in which case its likely a shell which does
561 * not provide it.
562 * So, to stop it breaking this case only, we ignore PWD if
563 * MAKEOBJDIRPREFIX is set.
564 */
565 if ((pwd = getenv("PWD")) != NULL &&
566 getenv("MAKEOBJDIRPREFIX") == NULL) {
567 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
568 sa.st_dev == sb.st_dev)
569 (void) strcpy(curdir, pwd);
570 }
571
572 /*
573 * Get the name of this type of MACHINE from utsname
574 * so we can share an executable for similar machines.
575 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
576 *
577 * Note that both MACHINE and MACHINE_ARCH are decided at
578 * run-time.
579 */
580 if (!machine) {
581 #ifndef MAKE_BOOTSTRAP
582 struct utsname utsname;
583
584 if (uname(&utsname) == -1) {
585 (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
586 strerror(errno));
587 exit(2);
588 }
589 machine = utsname.machine;
590 #else
591 machine = MACHINE;
592 #endif
593 }
594
595 if (!machine_arch) {
596 #ifndef MACHINE_ARCH
597 #ifdef __ARCHITECTURE__
598 machine_arch = __ARCHITECTURE__;
599 #else
600 machine_arch = "unknown"; /* XXX: no uname -p yet */
601 #endif
602 #else
603 machine_arch = MACHINE_ARCH;
604 #endif
605 }
606
607 /*
608 * Just in case MAKEOBJDIR wants us to do something tricky.
609 */
610 Var_Init(); /* Initialize the lists of variables for
611 * parsing arguments */
612 Var_Set(".CURDIR", curdir, VAR_GLOBAL);
613 Var_Set("MACHINE", machine, VAR_GLOBAL);
614 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
615
616 /*
617 * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
618 * exists, change into it and build there. (If a .${MACHINE} suffix
619 * exists, use that directory instead).
620 * Otherwise check MAKEOBJDIRPREFIX`cwd` (or by default,
621 * _PATH_OBJDIRPREFIX`cwd`) and build there if it exists.
622 * If all fails, use the current directory to build.
623 *
624 * Once things are initted,
625 * have to add the original directory to the search path,
626 * and modify the paths for the Makefiles apropriately. The
627 * current directory is also placed as a variable for make scripts.
628 */
629 if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
630 if (!(path = getenv("MAKEOBJDIR"))) {
631 path = _PATH_OBJDIR;
632 pathp = _PATH_OBJDIRPREFIX;
633 (void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
634 path, machine);
635 if (!(objdir = chdir_verify_path(mdpath, obpath)))
636 if (!(objdir=chdir_verify_path(path, obpath))) {
637 (void) snprintf(mdpath, MAXPATHLEN,
638 "%s%s", pathp, curdir);
639 if (!(objdir=chdir_verify_path(mdpath,
640 obpath)))
641 objdir = curdir;
642 }
643 }
644 else if (!(objdir = chdir_verify_path(path, obpath)))
645 objdir = curdir;
646 }
647 else {
648 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
649 if (!(objdir = chdir_verify_path(mdpath, obpath)))
650 objdir = curdir;
651 }
652
653 setenv("PWD", objdir, 1);
654
655 create = Lst_Init(FALSE);
656 makefiles = Lst_Init(FALSE);
657 printVars = FALSE;
658 variables = Lst_Init(FALSE);
659 beSilent = FALSE; /* Print commands as executed */
660 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
661 noExecute = FALSE; /* Execute all commands */
662 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
663 keepgoing = FALSE; /* Stop on error */
664 allPrecious = FALSE; /* Remove targets when interrupted */
665 queryFlag = FALSE; /* This is not just a check-run */
666 noBuiltins = FALSE; /* Read the built-in rules */
667 touchFlag = FALSE; /* Actually update targets */
668 usePipes = TRUE; /* Catch child output in pipes */
669 debug = 0; /* No debug verbosity, please. */
670 jobsRunning = FALSE;
671
672 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
673 #ifdef REMOTE
674 maxJobs = DEFMAXJOBS; /* Set default max concurrency */
675 #else
676 maxJobs = maxLocal;
677 #endif
678 compatMake = FALSE; /* No compat mode */
679
680
681 /*
682 * Initialize the parsing, directory and variable modules to prepare
683 * for the reading of inclusion paths and variable settings on the
684 * command line
685 */
686
687 /*
688 * Initialize directory structures so -I flags can be processed
689 * correctly, if we have a different objdir, then let the directory
690 * know our curdir.
691 */
692 Dir_Init(curdir != objdir ? curdir : NULL);
693 Parse_Init(); /* Need to initialize the paths of #include
694 * directories */
695 Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
696
697 /*
698 * Initialize various variables.
699 * MAKE also gets this name, for compatibility
700 * .MAKEFLAGS gets set to the empty string just in case.
701 * MFLAGS also gets initialized empty, for compatibility.
702 */
703 Var_Set("MAKE", argv[0], VAR_GLOBAL);
704 Var_Set(".MAKE", argv[0], VAR_GLOBAL);
705 Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
706 Var_Set("MFLAGS", "", VAR_GLOBAL);
707
708 /*
709 * First snag any flags out of the MAKE environment variable.
710 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
711 * in a different format).
712 */
713 #ifdef POSIX
714 Main_ParseArgLine(getenv("MAKEFLAGS"));
715 #else
716 Main_ParseArgLine(getenv("MAKE"));
717 #endif
718
719 MainParseArgs(argc, argv);
720
721 /*
722 * Be compatible if user did not specify -j and did not explicitly
723 * turned compatibility on
724 */
725 if (!compatMake && !forceJobs) {
726 compatMake = TRUE;
727 }
728
729 /*
730 * Initialize archive, target and suffix modules in preparation for
731 * parsing the makefile(s)
732 */
733 Arch_Init();
734 Targ_Init();
735 Suff_Init();
736 Trace_Init(tracefile);
737
738 DEFAULT = NILGNODE;
739 (void)time(&now);
740
741 Trace_Log(MAKESTART, NULL);
742
743 /*
744 * Set up the .TARGETS variable to contain the list of targets to be
745 * created. If none specified, make the variable empty -- the parser
746 * will fill the thing in with the default or .MAIN target.
747 */
748 if (!Lst_IsEmpty(create)) {
749 LstNode ln;
750
751 for (ln = Lst_First(create); ln != NILLNODE;
752 ln = Lst_Succ(ln)) {
753 char *name = (char *)Lst_Datum(ln);
754
755 Var_Append(".TARGETS", name, VAR_GLOBAL);
756 }
757 } else
758 Var_Set(".TARGETS", "", VAR_GLOBAL);
759
760
761 /*
762 * If no user-supplied system path was given (through the -m option)
763 * add the directories from the DEFSYSPATH (more than one may be given
764 * as dir1:...:dirn) to the system include path.
765 */
766 if (Lst_IsEmpty(sysIncPath)) {
767 if (syspath == NULL || *syspath == '\0')
768 syspath = defsyspath;
769 else
770 syspath = strdup(syspath);
771
772 for (start = syspath; *start != '\0'; start = cp) {
773 for (cp = start; *cp != '\0' && *cp != ':'; cp++)
774 continue;
775 if (*cp == '\0') {
776 (void) Dir_AddDir(sysIncPath, start);
777 } else {
778 *cp++ = '\0';
779 (void) Dir_AddDir(sysIncPath, start);
780 }
781 }
782 if (syspath != defsyspath)
783 free(syspath);
784 }
785
786 /*
787 * Read in the built-in rules first, followed by the specified
788 * makefile, if it was (makefile != (char *) NULL), or the default
789 * Makefile and makefile, in that order, if it wasn't.
790 */
791 if (!noBuiltins) {
792 LstNode ln;
793
794 sysMkPath = Lst_Init (FALSE);
795 Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
796 if (Lst_IsEmpty(sysMkPath))
797 Fatal("%s: no system rules (%s).", progname,
798 _PATH_DEFSYSMK);
799 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
800 if (ln != NILLNODE)
801 Fatal("%s: cannot open %s.", progname,
802 (char *)Lst_Datum(ln));
803 }
804
805 if (!Lst_IsEmpty(makefiles)) {
806 LstNode ln;
807
808 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
809 if (ln != NILLNODE)
810 Fatal("%s: cannot open %s.", progname,
811 (char *)Lst_Datum(ln));
812 } else if (!ReadMakefile("makefile", NULL))
813 (void)ReadMakefile("Makefile", NULL);
814
815 (void)ReadMakefile(".depend", NULL);
816
817 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
818 if (p1)
819 free(p1);
820
821 if (!jobServer && !compatMake)
822 Job_ServerStart(maxJobs);
823 if (DEBUG(JOB))
824 printf("job_pipe %d %d, maxjobs %d maxlocal %d compat %d\n", job_pipe[0], job_pipe[1], maxJobs,
825 maxLocal, compatMake);
826
827 /* Install all the flags into the MAKE envariable. */
828 if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
829 #ifdef POSIX
830 setenv("MAKEFLAGS", p, 1);
831 #else
832 setenv("MAKE", p, 1);
833 #endif
834 if (p1)
835 free(p1);
836
837 Check_Cwd_av(0, NULL, 0); /* initialize it */
838
839
840 /*
841 * For compatibility, look at the directories in the VPATH variable
842 * and add them to the search path, if the variable is defined. The
843 * variable's value is in the same format as the PATH envariable, i.e.
844 * <directory>:<directory>:<directory>...
845 */
846 if (Var_Exists("VPATH", VAR_CMD)) {
847 char *vpath, *path, *cp, savec;
848 /*
849 * GCC stores string constants in read-only memory, but
850 * Var_Subst will want to write this thing, so store it
851 * in an array
852 */
853 static char VPATH[] = "${VPATH}";
854
855 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
856 path = vpath;
857 do {
858 /* skip to end of directory */
859 for (cp = path; *cp != ':' && *cp != '\0'; cp++)
860 continue;
861 /* Save terminator character so know when to stop */
862 savec = *cp;
863 *cp = '\0';
864 /* Add directory to search path */
865 (void) Dir_AddDir(dirSearchPath, path);
866 *cp = savec;
867 path = cp + 1;
868 } while (savec == ':');
869 (void)free((Address)vpath);
870 }
871
872 /*
873 * Now that all search paths have been read for suffixes et al, it's
874 * time to add the default search path to their lists...
875 */
876 Suff_DoPaths();
877
878 /*
879 * Propagate attributes through :: dependency lists.
880 */
881 Targ_Propagate();
882
883 /* print the initial graph, if the user requested it */
884 if (DEBUG(GRAPH1))
885 Targ_PrintGraph(1);
886
887 /* print the values of any variables requested by the user */
888 if (printVars) {
889 LstNode ln;
890
891 for (ln = Lst_First(variables); ln != NILLNODE;
892 ln = Lst_Succ(ln)) {
893 char *value = Var_Value((char *)Lst_Datum(ln),
894 VAR_GLOBAL, &p1);
895
896 printf("%s\n", value ? value : "");
897 if (p1)
898 free(p1);
899 }
900 }
901
902 /*
903 * Have now read the entire graph and need to make a list of targets
904 * to create. If none was given on the command line, we consult the
905 * parsing module to find the main target(s) to create.
906 */
907 if (Lst_IsEmpty(create))
908 targs = Parse_MainName();
909 else
910 targs = Targ_FindList(create, TARG_CREATE);
911
912 if (!compatMake && !printVars) {
913 /*
914 * Initialize job module before traversing the graph, now that
915 * any .BEGIN and .END targets have been read. This is done
916 * only if the -q flag wasn't given (to prevent the .BEGIN from
917 * being executed should it exist).
918 */
919 if (!queryFlag) {
920 if (maxLocal == -1)
921 maxLocal = maxJobs;
922 Job_Init(maxJobs, maxLocal);
923 jobsRunning = TRUE;
924 }
925
926 /* Traverse the graph, checking on all the targets */
927 outOfDate = Make_Run(targs);
928 } else if (!printVars) {
929 /*
930 * Compat_Init will take care of creating all the targets as
931 * well as initializing the module.
932 */
933 Compat_Run(targs);
934 }
935
936 #ifdef CLEANUP
937 Lst_Destroy(targs, NOFREE);
938 Lst_Destroy(variables, NOFREE);
939 Lst_Destroy(makefiles, NOFREE);
940 Lst_Destroy(create, (void (*) __P((ClientData))) free);
941 #endif
942
943 /* print the graph now it's been processed if the user requested it */
944 if (DEBUG(GRAPH2))
945 Targ_PrintGraph(2);
946
947 Trace_Log(MAKEEND, 0);
948
949 Suff_End();
950 Targ_End();
951 Arch_End();
952 Var_End();
953 Parse_End();
954 Dir_End();
955 Job_End();
956 Trace_End();
957
958 if (queryFlag && outOfDate)
959 return(1);
960 else
961 return(0);
962 }
963
964 /*-
965 * ReadMakefile --
966 * Open and parse the given makefile.
967 *
968 * Results:
969 * TRUE if ok. FALSE if couldn't open file.
970 *
971 * Side Effects:
972 * lots
973 */
974 static Boolean
975 ReadMakefile(p, q)
976 ClientData p, q;
977 {
978 char *fname = p; /* makefile to read */
979 FILE *stream;
980 size_t len = MAXPATHLEN;
981 char *name, *path = emalloc(len);
982
983 if (!strcmp(fname, "-")) {
984 Parse_File("(stdin)", stdin);
985 Var_Set("MAKEFILE", "", VAR_GLOBAL);
986 } else {
987 /* if we've chdir'd, rebuild the path name */
988 if (curdir != objdir && *fname != '/') {
989 size_t plen = strlen(curdir) + strlen(fname) + 2;
990 if (len < plen)
991 path = erealloc(path, len = 2 * plen);
992
993 (void)snprintf(path, len, "%s/%s", curdir, fname);
994 if ((stream = fopen(path, "r")) != NULL) {
995 fname = path;
996 goto found;
997 }
998 } else if ((stream = fopen(fname, "r")) != NULL)
999 goto found;
1000 /* look in -I and system include directories. */
1001 name = Dir_FindFile(fname, parseIncPath);
1002 if (!name)
1003 name = Dir_FindFile(fname, sysIncPath);
1004 if (!name || !(stream = fopen(name, "r"))) {
1005 free(path);
1006 return(FALSE);
1007 }
1008 fname = name;
1009 /*
1010 * set the MAKEFILE variable desired by System V fans -- the
1011 * placement of the setting here means it gets set to the last
1012 * makefile specified, as it is set by SysV make.
1013 */
1014 found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
1015 Parse_File(fname, stream);
1016 (void)fclose(stream);
1017 }
1018 free(path);
1019 return(TRUE);
1020 }
1021
1022
1023 /*
1024 * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR
1025 * in situations that would not arrise with ./obj (links or not).
1026 * This tends to break things like:
1027 *
1028 * build:
1029 * ${MAKE} includes
1030 *
1031 * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as
1032 * opposed to an argument) in a command line and if so returns
1033 * ${.CURDIR} so caller can chdir() so that the assumptions made by
1034 * the Makefile hold true.
1035 *
1036 * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped.
1037 *
1038 * The chdir() only happens in the child process, and does nothing if
1039 * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it
1040 * should not break anything. Also if NOCHECKMAKECHDIR is set we
1041 * do nothing - to ensure historic semantics can be retained.
1042 */
1043 static int Check_Cwd_Off = 0;
1044
1045 static char *
1046 Check_Cwd_av(ac, av, copy)
1047 int ac;
1048 char **av;
1049 int copy;
1050 {
1051 static char *make[4];
1052 static char *curdir = NULL;
1053 char *cp, **mp;
1054 int is_cmd, next_cmd;
1055 int i;
1056 int n;
1057
1058 if (Check_Cwd_Off)
1059 return NULL;
1060
1061 if (make[0] == NULL) {
1062 if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
1063 Check_Cwd_Off = 1;
1064 return NULL;
1065 }
1066
1067 make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
1068 if ((make[0] = strrchr(make[1], '/')) == NULL) {
1069 make[0] = make[1];
1070 make[1] = NULL;
1071 } else
1072 ++make[0];
1073 make[2] = NULL;
1074 curdir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
1075 }
1076 if (ac == 0 || av == NULL)
1077 return NULL; /* initialization only */
1078
1079 if (getenv("MAKEOBJDIR") == NULL &&
1080 getenv("MAKEOBJDIRPREFIX") == NULL)
1081 return NULL;
1082
1083
1084 next_cmd = 1;
1085 for (i = 0; i < ac; ++i) {
1086 is_cmd = next_cmd;
1087
1088 n = strlen(av[i]);
1089 cp = &(av[i])[n - 1];
1090 if (strspn(av[i], "|&;") == n) {
1091 next_cmd = 1;
1092 continue;
1093 } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
1094 next_cmd = 1;
1095 if (copy) {
1096 do {
1097 *cp-- = '\0';
1098 } while (*cp == ';' || *cp == '&' || *cp == '|' ||
1099 *cp == ')' || *cp == '}') ;
1100 } else {
1101 /*
1102 * XXX this should not happen.
1103 */
1104 fprintf(stderr, "WARNING: raw arg ends in shell meta '%s'\n",
1105 av[i]);
1106 }
1107 } else
1108 next_cmd = 0;
1109
1110 cp = av[i];
1111 if (*cp == ';' || *cp == '&' || *cp == '|')
1112 is_cmd = 1;
1113
1114 #ifdef check_cwd_debug
1115 fprintf(stderr, "av[%d] == %s '%s'",
1116 i, (is_cmd) ? "cmd" : "arg", av[i]);
1117 #endif
1118 if (is_cmd != 0) {
1119 if (*cp == '(' || *cp == '{' ||
1120 *cp == ';' || *cp == '&' || *cp == '|') {
1121 do {
1122 ++cp;
1123 } while (*cp == '(' || *cp == '{' ||
1124 *cp == ';' || *cp == '&' || *cp == '|');
1125 if (*cp == '\0') {
1126 next_cmd = 1;
1127 continue;
1128 }
1129 }
1130 if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
1131 #ifdef check_cwd_debug
1132 fprintf(stderr, " == cd, done.\n");
1133 #endif
1134 return NULL;
1135 }
1136 for (mp = make; *mp != NULL; ++mp) {
1137 n = strlen(*mp);
1138 if (strcmp(cp, *mp) == 0) {
1139 #ifdef check_cwd_debug
1140 fprintf(stderr, " %s == '%s', chdir(%s)\n",
1141 cp, *mp, curdir);
1142 #endif
1143 return curdir;
1144 }
1145 }
1146 }
1147 #ifdef check_cwd_debug
1148 fprintf(stderr, "\n");
1149 #endif
1150 }
1151 return NULL;
1152 }
1153
1154 char *
1155 Check_Cwd_Cmd(cmd)
1156 char *cmd;
1157 {
1158 char *cp, *bp, **av;
1159 int ac;
1160
1161 if (Check_Cwd_Off)
1162 return NULL;
1163
1164 if (cmd) {
1165 av = brk_string(cmd, &ac, TRUE, &bp);
1166 #ifdef check_cwd_debug
1167 fprintf(stderr, "splitting: '%s' -> %d words\n",
1168 cmd, ac);
1169 #endif
1170 } else {
1171 ac = 0;
1172 av = NULL;
1173 bp = NULL;
1174 }
1175 cp = Check_Cwd_av(ac, av, 1);
1176 if (bp) {
1177 free(av);
1178 free(bp);
1179 }
1180 return cp;
1181 }
1182
1183 void
1184 Check_Cwd(argv)
1185 char **argv;
1186 {
1187 char *cp;
1188 int ac;
1189
1190 if (Check_Cwd_Off)
1191 return;
1192
1193 for (ac = 0; argv[ac] != NULL; ++ac)
1194 /* NOTHING */;
1195 if (ac == 3 && *argv[1] == '-') {
1196 cp = Check_Cwd_Cmd(argv[2]);
1197 } else {
1198 cp = Check_Cwd_av(ac, argv, 0);
1199 }
1200 if (cp) {
1201 chdir(cp);
1202 }
1203 }
1204
1205 /*-
1206 * Cmd_Exec --
1207 * Execute the command in cmd, and return the output of that command
1208 * in a string.
1209 *
1210 * Results:
1211 * A string containing the output of the command, or the empty string
1212 * If err is not NULL, it contains the reason for the command failure
1213 *
1214 * Side Effects:
1215 * The string must be freed by the caller.
1216 */
1217 char *
1218 Cmd_Exec(cmd, err)
1219 char *cmd;
1220 char **err;
1221 {
1222 char *args[4]; /* Args for invoking the shell */
1223 int fds[2]; /* Pipe streams */
1224 int cpid; /* Child PID */
1225 int pid; /* PID from wait() */
1226 char *res; /* result */
1227 int status; /* command exit status */
1228 Buffer buf; /* buffer to store the result */
1229 char *cp;
1230 int cc;
1231
1232
1233 *err = NULL;
1234
1235 /*
1236 * Set up arguments for shell
1237 */
1238 args[0] = "sh";
1239 args[1] = "-c";
1240 args[2] = cmd;
1241 args[3] = NULL;
1242
1243 /*
1244 * Open a pipe for fetching its output
1245 */
1246 if (pipe(fds) == -1) {
1247 *err = "Couldn't create pipe for \"%s\"";
1248 goto bad;
1249 }
1250
1251 /*
1252 * Fork
1253 */
1254 switch (cpid = vfork()) {
1255 case 0:
1256 /*
1257 * Close input side of pipe
1258 */
1259 (void) close(fds[0]);
1260
1261 /*
1262 * Duplicate the output stream to the shell's output, then
1263 * shut the extra thing down. Note we don't fetch the error
1264 * stream...why not? Why?
1265 */
1266 (void) dup2(fds[1], 1);
1267 (void) close(fds[1]);
1268
1269 (void) execv("/bin/sh", args);
1270 _exit(1);
1271 /*NOTREACHED*/
1272
1273 case -1:
1274 *err = "Couldn't exec \"%s\"";
1275 goto bad;
1276
1277 default:
1278 /*
1279 * No need for the writing half
1280 */
1281 (void) close(fds[1]);
1282
1283 buf = Buf_Init (MAKE_BSIZE);
1284
1285 do {
1286 char result[BUFSIZ];
1287 cc = read(fds[0], result, sizeof(result));
1288 if (cc > 0)
1289 Buf_AddBytes(buf, cc, (Byte *) result);
1290 }
1291 while (cc > 0 || (cc == -1 && errno == EINTR));
1292
1293 /*
1294 * Close the input side of the pipe.
1295 */
1296 (void) close(fds[0]);
1297
1298 /*
1299 * Wait for the process to exit.
1300 */
1301 while(((pid = wait(&status)) != cpid) && (pid >= 0))
1302 continue;
1303
1304 res = (char *)Buf_GetAll (buf, &cc);
1305 Buf_Destroy (buf, FALSE);
1306
1307 if (cc == 0)
1308 *err = "Couldn't read shell's output for \"%s\"";
1309
1310 if (status)
1311 *err = "\"%s\" returned non-zero status";
1312
1313 /*
1314 * Null-terminate the result, convert newlines to spaces and
1315 * install it in the variable.
1316 */
1317 res[cc] = '\0';
1318 cp = &res[cc];
1319
1320 if (cc > 0 && *--cp == '\n') {
1321 /*
1322 * A final newline is just stripped
1323 */
1324 *cp-- = '\0';
1325 }
1326 while (cp >= res) {
1327 if (*cp == '\n') {
1328 *cp = ' ';
1329 }
1330 cp--;
1331 }
1332 break;
1333 }
1334 return res;
1335 bad:
1336 res = emalloc(1);
1337 *res = '\0';
1338 return res;
1339 }
1340
1341 /*-
1342 * Error --
1343 * Print an error message given its format.
1344 *
1345 * Results:
1346 * None.
1347 *
1348 * Side Effects:
1349 * The message is printed.
1350 */
1351 /* VARARGS */
1352 void
1353 #ifdef __STDC__
1354 Error(char *fmt, ...)
1355 #else
1356 Error(va_alist)
1357 va_dcl
1358 #endif
1359 {
1360 va_list ap;
1361 #ifdef __STDC__
1362 va_start(ap, fmt);
1363 #else
1364 char *fmt;
1365
1366 va_start(ap);
1367 fmt = va_arg(ap, char *);
1368 #endif
1369 fprintf(stderr, "%s: ", progname);
1370 (void)vfprintf(stderr, fmt, ap);
1371 va_end(ap);
1372 (void)fprintf(stderr, "\n");
1373 (void)fflush(stderr);
1374 }
1375
1376 /*-
1377 * Fatal --
1378 * Produce a Fatal error message. If jobs are running, waits for them
1379 * to finish.
1380 *
1381 * Results:
1382 * None
1383 *
1384 * Side Effects:
1385 * The program exits
1386 */
1387 /* VARARGS */
1388 void
1389 #ifdef __STDC__
1390 Fatal(char *fmt, ...)
1391 #else
1392 Fatal(va_alist)
1393 va_dcl
1394 #endif
1395 {
1396 va_list ap;
1397 #ifdef __STDC__
1398 va_start(ap, fmt);
1399 #else
1400 char *fmt;
1401
1402 va_start(ap);
1403 fmt = va_arg(ap, char *);
1404 #endif
1405 if (jobsRunning)
1406 Job_Wait();
1407 Job_TokenFlush();
1408
1409 (void)vfprintf(stderr, fmt, ap);
1410 va_end(ap);
1411 (void)fprintf(stderr, "\n");
1412 (void)fflush(stderr);
1413
1414 if (DEBUG(GRAPH2))
1415 Targ_PrintGraph(2);
1416 Trace_Log(MAKEERROR, 0);
1417 exit(2); /* Not 1 so -q can distinguish error */
1418 }
1419
1420 /*
1421 * Punt --
1422 * Major exception once jobs are being created. Kills all jobs, prints
1423 * a message and exits.
1424 *
1425 * Results:
1426 * None
1427 *
1428 * Side Effects:
1429 * All children are killed indiscriminately and the program Lib_Exits
1430 */
1431 /* VARARGS */
1432 void
1433 #ifdef __STDC__
1434 Punt(char *fmt, ...)
1435 #else
1436 Punt(va_alist)
1437 va_dcl
1438 #endif
1439 {
1440 va_list ap;
1441 #ifdef __STDC__
1442 va_start(ap, fmt);
1443 #else
1444 char *fmt;
1445
1446 va_start(ap);
1447 fmt = va_arg(ap, char *);
1448 #endif
1449
1450 (void)fprintf(stderr, "%s: ", progname);
1451 (void)vfprintf(stderr, fmt, ap);
1452 va_end(ap);
1453 (void)fprintf(stderr, "\n");
1454 (void)fflush(stderr);
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