main.c revision 1.90 1 /* $NetBSD: main.c,v 1.90 2003/08/01 00:39:53 sjg 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.90 2003/08/01 00:39:53 sjg 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.90 2003/08/01 00:39:53 sjg 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
97 #include <errno.h>
98 #include <fcntl.h>
99 #include <stdarg.h>
100 #include <stdio.h>
101 #include <stdlib.h>
102 #include <time.h>
103
104 #include "make.h"
105 #include "hash.h"
106 #include "dir.h"
107 #include "job.h"
108 #include "pathnames.h"
109 #include "trace.h"
110
111 #ifdef USE_IOVEC
112 #include <sys/uio.h>
113 #endif
114
115 #ifndef DEFMAXLOCAL
116 #define DEFMAXLOCAL DEFMAXJOBS
117 #endif /* DEFMAXLOCAL */
118
119 Lst create; /* Targets to be made */
120 time_t now; /* Time at start of make */
121 GNode *DEFAULT; /* .DEFAULT node */
122 Boolean allPrecious; /* .PRECIOUS given on line by itself */
123
124 static Boolean noBuiltins; /* -r flag */
125 static Lst makefiles; /* ordered list of makefiles to read */
126 static Boolean printVars; /* print value of one or more vars */
127 static Lst variables; /* list of variables to print */
128 int maxJobs; /* -j argument */
129 static int maxLocal; /* -L argument */
130 Boolean compatMake; /* -B argument */
131 Boolean debug; /* -d flag */
132 Boolean noExecute; /* -n flag */
133 Boolean noRecursiveExecute; /* -N flag */
134 Boolean keepgoing; /* -k flag */
135 Boolean queryFlag; /* -q flag */
136 Boolean touchFlag; /* -t flag */
137 Boolean usePipes; /* !-P flag */
138 Boolean ignoreErrors; /* -i flag */
139 Boolean beSilent; /* -s flag */
140 Boolean oldVars; /* variable substitution style */
141 Boolean checkEnvFirst; /* -e flag */
142 Boolean parseWarnFatal; /* -W flag */
143 Boolean jobServer; /* -J flag */
144 Boolean varNoExportEnv; /* -X flag */
145 static Boolean jobsRunning; /* TRUE if the jobs might be running */
146 static const char * tracefile;
147 static char * Check_Cwd_av(int, char **, int);
148 static void MainParseArgs(int, char **);
149 static int ReadMakefile(ClientData, ClientData);
150 static void usage(void);
151
152 static char curdir[MAXPATHLEN + 1]; /* startup directory */
153 static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
154 char *progname; /* the program name */
155
156 Boolean forceJobs = FALSE;
157
158 extern Lst parseIncPath;
159
160 /*-
161 * MainParseArgs --
162 * Parse a given argument vector. Called from main() and from
163 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
164 *
165 * XXX: Deal with command line overriding .MAKEFLAGS in makefile
166 *
167 * Results:
168 * None
169 *
170 * Side Effects:
171 * Various global and local flags will be set depending on the flags
172 * given
173 */
174 static void
175 MainParseArgs(int argc, char **argv)
176 {
177 char *p;
178 int c;
179
180 optind = 1; /* since we're called more than once */
181 #ifdef REMOTE
182 # define OPTFLAGS "BD:I:J:L:NPST:V:WXd:ef:ij:km:nqrst"
183 #else
184 # define OPTFLAGS "BD:I:J:NPST:V:WXd:ef:ij:km:nqrst"
185 #endif
186 rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
187 switch(c) {
188 case 'D':
189 Var_Set(optarg, "1", VAR_GLOBAL, 0);
190 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
191 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
192 break;
193 case 'I':
194 Parse_AddIncludeDir(optarg);
195 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
196 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
197 break;
198 case 'J':
199 if (sscanf(optarg, "%d,%d", &job_pipe[0], &job_pipe[1]) != 2) {
200 /* backslash to avoid trigraph ??) */
201 (void)fprintf(stderr,
202 "%s: internal error -- J option malformed (%s?\?)\n",
203 progname, optarg);
204 usage();
205 }
206 if ((fcntl(job_pipe[0], F_GETFD, 0) < 0) ||
207 (fcntl(job_pipe[1], F_GETFD, 0) < 0)) {
208 #if 0
209 (void)fprintf(stderr,
210 "%s: warning -- J descriptors were closed!\n",
211 progname);
212 #endif
213 job_pipe[0] = -1;
214 job_pipe[1] = -1;
215 compatMake = TRUE;
216 } else {
217 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
218 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
219 jobServer = TRUE;
220 }
221 break;
222 case 'V':
223 printVars = TRUE;
224 (void)Lst_AtEnd(variables, (ClientData)optarg);
225 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
226 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
227 break;
228 case 'B':
229 compatMake = TRUE;
230 Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
231 break;
232 #ifdef REMOTE
233 case 'L':
234 maxLocal = strtol(optarg, &p, 0);
235 if (*p != '\0' || maxLocal < 1) {
236 (void) fprintf(stderr, "%s: illegal argument to -L -- must be positive integer!\n",
237 progname);
238 exit(1);
239 }
240 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
241 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
242 break;
243 #endif
244 case 'N':
245 noExecute = TRUE;
246 noRecursiveExecute = TRUE;
247 Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
248 break;
249 case 'P':
250 usePipes = FALSE;
251 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
252 break;
253 case 'S':
254 keepgoing = FALSE;
255 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
256 break;
257 case 'T':
258 tracefile = estrdup(optarg);
259 Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
260 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
261 break;
262 case 'W':
263 parseWarnFatal = TRUE;
264 break;
265 case 'X':
266 varNoExportEnv = TRUE;
267 Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
268 break;
269 case 'd': {
270 char *modules = optarg;
271
272 for (; *modules; ++modules)
273 switch (*modules) {
274 case 'A':
275 debug = ~0;
276 break;
277 case 'a':
278 debug |= DEBUG_ARCH;
279 break;
280 case 'c':
281 debug |= DEBUG_COND;
282 break;
283 case 'd':
284 debug |= DEBUG_DIR;
285 break;
286 case 'f':
287 debug |= DEBUG_FOR;
288 break;
289 case 'g':
290 if (modules[1] == '1') {
291 debug |= DEBUG_GRAPH1;
292 ++modules;
293 }
294 else if (modules[1] == '2') {
295 debug |= DEBUG_GRAPH2;
296 ++modules;
297 }
298 break;
299 case 'j':
300 debug |= DEBUG_JOB;
301 break;
302 case 'm':
303 debug |= DEBUG_MAKE;
304 break;
305 case 's':
306 debug |= DEBUG_SUFF;
307 break;
308 case 't':
309 debug |= DEBUG_TARG;
310 break;
311 case 'v':
312 debug |= DEBUG_VAR;
313 break;
314 case 'x':
315 debug |= DEBUG_SHELL;
316 break;
317 default:
318 (void)fprintf(stderr,
319 "%s: illegal argument to d option -- %c\n",
320 progname, *modules);
321 usage();
322 }
323 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
324 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
325 break;
326 }
327 case 'e':
328 checkEnvFirst = TRUE;
329 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
330 break;
331 case 'f':
332 (void)Lst_AtEnd(makefiles, (ClientData)optarg);
333 break;
334 case 'i':
335 ignoreErrors = TRUE;
336 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
337 break;
338 case 'j':
339 forceJobs = TRUE;
340 maxJobs = strtol(optarg, &p, 0);
341 if (*p != '\0' || maxJobs < 1) {
342 (void) fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
343 progname);
344 exit(1);
345 }
346 #ifndef REMOTE
347 maxLocal = maxJobs;
348 #endif
349 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
350 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
351 break;
352 case 'k':
353 keepgoing = TRUE;
354 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
355 break;
356 case 'm':
357 (void) Dir_AddDir(sysIncPath, optarg);
358 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
359 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
360 break;
361 case 'n':
362 noExecute = TRUE;
363 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
364 break;
365 case 'q':
366 queryFlag = TRUE;
367 /* Kind of nonsensical, wot? */
368 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
369 break;
370 case 'r':
371 noBuiltins = TRUE;
372 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
373 break;
374 case 's':
375 beSilent = TRUE;
376 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
377 break;
378 case 't':
379 touchFlag = TRUE;
380 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
381 break;
382 default:
383 case '?':
384 usage();
385 }
386 }
387
388 oldVars = TRUE;
389
390 /*
391 * See if the rest of the arguments are variable assignments and
392 * perform them if so. Else take them to be targets and stuff them
393 * on the end of the "create" list.
394 */
395 for (argv += optind, argc -= optind; *argv; ++argv, --argc)
396 if (Parse_IsVar(*argv)) {
397 Parse_DoVar(*argv, VAR_CMD);
398 } else {
399 if (!**argv)
400 Punt("illegal (null) argument.");
401 if (**argv == '-') {
402 if ((*argv)[1])
403 optind = 0; /* -flag... */
404 else
405 optind = 1; /* - */
406 goto rearg;
407 }
408 (void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
409 }
410 }
411
412 /*-
413 * Main_ParseArgLine --
414 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
415 * is encountered and by main() when reading the .MAKEFLAGS envariable.
416 * Takes a line of arguments and breaks it into its
417 * component words and passes those words and the number of them to the
418 * MainParseArgs function.
419 * The line should have all its leading whitespace removed.
420 *
421 * Input:
422 * line Line to fracture
423 *
424 * Results:
425 * None
426 *
427 * Side Effects:
428 * Only those that come from the various arguments.
429 */
430 void
431 Main_ParseArgLine(char *line)
432 {
433 char **argv; /* Manufactured argument vector */
434 int argc; /* Number of arguments in argv */
435 char *args; /* Space used by the args */
436 char *buf, *p1;
437 char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
438 size_t len;
439
440 if (line == NULL)
441 return;
442 for (; *line == ' '; ++line)
443 continue;
444 if (!*line)
445 return;
446
447 buf = emalloc(len = strlen(line) + strlen(argv0) + 2);
448 (void)snprintf(buf, len, "%s %s", argv0, line);
449 if (p1)
450 free(p1);
451
452 argv = brk_string(buf, &argc, TRUE, &args);
453 free(buf);
454 MainParseArgs(argc, argv);
455
456 free(args);
457 free(argv);
458 }
459
460 Boolean
461 Main_SetObjdir(const char *path)
462 {
463 struct stat sb;
464 char *p = NULL;
465 char buf[MAXPATHLEN + 1];
466 Boolean rc = FALSE;
467
468 /* expand variable substitutions */
469 if (strchr(path, '$') != 0) {
470 snprintf(buf, MAXPATHLEN, "%s", path);
471 path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0);
472 }
473
474 if (path[0] != '/') {
475 snprintf(buf, MAXPATHLEN, "%s/%s", curdir, path);
476 path = buf;
477 }
478
479 /* look for the directory and try to chdir there */
480 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
481 if (chdir(path)) {
482 (void)fprintf(stderr, "make warning: %s: %s.\n",
483 path, strerror(errno));
484 } else {
485 strncpy(objdir, path, MAXPATHLEN);
486 Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0);
487 setenv("PWD", objdir, 1);
488 Dir_InitDot();
489 rc = TRUE;
490 }
491 }
492
493 if (p)
494 free(p);
495 return rc;
496 }
497
498
499 /*-
500 * main --
501 * The main function, for obvious reasons. Initializes variables
502 * and a few modules, then parses the arguments give it in the
503 * environment and on the command line. Reads the system makefile
504 * followed by either Makefile, makefile or the file given by the
505 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
506 * flags it has received by then uses either the Make or the Compat
507 * module to create the initial list of targets.
508 *
509 * Results:
510 * If -q was given, exits -1 if anything was out-of-date. Else it exits
511 * 0.
512 *
513 * Side Effects:
514 * The program exits when done. Targets are created. etc. etc. etc.
515 */
516 int
517 main(int argc, char **argv)
518 {
519 Lst targs; /* target nodes to create -- passed to Make_Init */
520 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
521 struct stat sb, sa;
522 char *p1, *path, *pwd;
523 char mdpath[MAXPATHLEN];
524 char *machine = getenv("MACHINE");
525 const char *machine_arch = getenv("MACHINE_ARCH");
526 char *syspath = getenv("MAKESYSPATH");
527 Lst sysMkPath; /* Path of sys.mk */
528 char *cp = NULL, *start;
529 /* avoid faults on read-only strings */
530 static char defsyspath[] = _PATH_DEFSYSPATH;
531
532 if ((progname = strrchr(argv[0], '/')) != NULL)
533 progname++;
534 else
535 progname = argv[0];
536 #ifdef RLIMIT_NOFILE
537 /*
538 * get rid of resource limit on file descriptors
539 */
540 {
541 struct rlimit rl;
542 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
543 rl.rlim_cur != rl.rlim_max) {
544 rl.rlim_cur = rl.rlim_max;
545 (void) setrlimit(RLIMIT_NOFILE, &rl);
546 }
547 }
548 #endif
549 /*
550 * Find where we are and take care of PWD for the automounter...
551 * All this code is so that we know where we are when we start up
552 * on a different machine with pmake.
553 */
554 if (getcwd(curdir, MAXPATHLEN) == NULL) {
555 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
556 exit(2);
557 }
558
559 if (stat(curdir, &sa) == -1) {
560 (void)fprintf(stderr, "%s: %s: %s.\n",
561 progname, curdir, strerror(errno));
562 exit(2);
563 }
564
565 /*
566 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
567 * since the value of curdir can very depending on how we got
568 * here. Ie sitting at a shell prompt (shell that provides $PWD)
569 * or via subdir.mk in which case its likely a shell which does
570 * not provide it.
571 * So, to stop it breaking this case only, we ignore PWD if
572 * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
573 */
574 if ((pwd = getenv("PWD")) != NULL && getenv("MAKEOBJDIRPREFIX") == NULL) {
575 const char *makeobjdir = getenv("MAKEOBJDIR");
576
577 if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
578 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
579 sa.st_dev == sb.st_dev)
580 (void) strncpy(curdir, pwd, MAXPATHLEN);
581 }
582 }
583
584 /*
585 * Get the name of this type of MACHINE from utsname
586 * so we can share an executable for similar machines.
587 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
588 *
589 * Note that both MACHINE and MACHINE_ARCH are decided at
590 * run-time.
591 */
592 if (!machine) {
593 #ifndef MAKE_BOOTSTRAP
594 struct utsname utsname;
595
596 if (uname(&utsname) == -1) {
597 (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
598 strerror(errno));
599 exit(2);
600 }
601 machine = utsname.machine;
602 #else
603 #ifdef MAKE_MACHINE
604 machine = MAKE_MACHINE;
605 #else
606 machine = "unknown";
607 #endif
608 #endif
609 }
610
611 if (!machine_arch) {
612 #ifndef MACHINE_ARCH
613 #ifdef MAKE_MACHINE_ARCH
614 machine_arch = MAKE_MACHINE_ARCH;
615 #else
616 machine_arch = "unknown";
617 #endif
618 #else
619 machine_arch = MACHINE_ARCH;
620 #endif
621 }
622
623 /*
624 * Just in case MAKEOBJDIR wants us to do something tricky.
625 */
626 Var_Init(); /* Initialize the lists of variables for
627 * parsing arguments */
628 Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
629 Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
630 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
631 #ifdef MAKE_VERSION
632 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
633 #endif
634 Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
635
636 /*
637 * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that,
638 * MAKEOBJDIR is set in the environment, try only that value
639 * and fall back to .CURDIR if it does not exist.
640 *
641 * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and
642 * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
643 * of these paths exist, just use .CURDIR.
644 */
645 Dir_Init(curdir);
646 (void) Main_SetObjdir(curdir);
647
648 if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) {
649 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir);
650 (void) Main_SetObjdir(mdpath);
651 } else if ((path = getenv("MAKEOBJDIR")) != NULL) {
652 (void) Main_SetObjdir(path);
653 } else {
654 (void) snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine);
655 if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) {
656 (void) snprintf(mdpath, MAXPATHLEN, "%s%s",
657 _PATH_OBJDIRPREFIX, curdir);
658 (void) Main_SetObjdir(mdpath);
659 }
660 }
661
662 create = Lst_Init(FALSE);
663 makefiles = Lst_Init(FALSE);
664 printVars = FALSE;
665 variables = Lst_Init(FALSE);
666 beSilent = FALSE; /* Print commands as executed */
667 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
668 noExecute = FALSE; /* Execute all commands */
669 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
670 keepgoing = FALSE; /* Stop on error */
671 allPrecious = FALSE; /* Remove targets when interrupted */
672 queryFlag = FALSE; /* This is not just a check-run */
673 noBuiltins = FALSE; /* Read the built-in rules */
674 touchFlag = FALSE; /* Actually update targets */
675 usePipes = TRUE; /* Catch child output in pipes */
676 debug = 0; /* No debug verbosity, please. */
677 jobsRunning = FALSE;
678
679 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
680 #ifdef REMOTE
681 maxJobs = DEFMAXJOBS; /* Set default max concurrency */
682 #else
683 maxJobs = maxLocal;
684 #endif
685 compatMake = FALSE; /* No compat mode */
686
687
688 /*
689 * Initialize the parsing, directory and variable modules to prepare
690 * for the reading of inclusion paths and variable settings on the
691 * command line
692 */
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 Parse_Init();
701 Var_Set("MAKE", argv[0], VAR_GLOBAL, 0);
702 Var_Set(".MAKE", argv[0], VAR_GLOBAL, 0);
703 Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0);
704 Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
705 Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
706 Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);
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, 0);
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 (syspath == NULL || *syspath == '\0')
767 syspath = defsyspath;
768 else
769 syspath = strdup(syspath);
770
771 for (start = syspath; *start != '\0'; start = cp) {
772 for (cp = start; *cp != '\0' && *cp != ':'; cp++)
773 continue;
774 if (*cp == '\0') {
775 (void) Dir_AddDir(defIncPath, start);
776 } else {
777 *cp++ = '\0';
778 (void) Dir_AddDir(defIncPath, start);
779 }
780 }
781 if (syspath != defsyspath)
782 free(syspath);
783
784 /*
785 * Read in the built-in rules first, followed by the specified
786 * makefile, if it was (makefile != (char *) NULL), or the default
787 * Makefile and makefile, in that order, if it wasn't.
788 */
789 if (!noBuiltins) {
790 LstNode ln;
791
792 sysMkPath = Lst_Init (FALSE);
793 Dir_Expand(_PATH_DEFSYSMK,
794 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
795 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(UNCONST("makefile"), NULL))
813 (void)ReadMakefile(UNCONST("Makefile"), NULL);
814
815 (void)ReadMakefile(UNCONST(".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 Main_ExportMAKEFLAGS(TRUE); /* initial export */
828
829 Check_Cwd_av(0, NULL, 0); /* initialize it */
830
831
832 /*
833 * For compatibility, look at the directories in the VPATH variable
834 * and add them to the search path, if the variable is defined. The
835 * variable's value is in the same format as the PATH envariable, i.e.
836 * <directory>:<directory>:<directory>...
837 */
838 if (Var_Exists("VPATH", VAR_CMD)) {
839 char *vpath, savec;
840 /*
841 * GCC stores string constants in read-only memory, but
842 * Var_Subst will want to write this thing, so store it
843 * in an array
844 */
845 static char VPATH[] = "${VPATH}";
846
847 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
848 path = vpath;
849 do {
850 /* skip to end of directory */
851 for (cp = path; *cp != ':' && *cp != '\0'; cp++)
852 continue;
853 /* Save terminator character so know when to stop */
854 savec = *cp;
855 *cp = '\0';
856 /* Add directory to search path */
857 (void) Dir_AddDir(dirSearchPath, path);
858 *cp = savec;
859 path = cp + 1;
860 } while (savec == ':');
861 (void)free((Address)vpath);
862 }
863
864 /*
865 * Now that all search paths have been read for suffixes et al, it's
866 * time to add the default search path to their lists...
867 */
868 Suff_DoPaths();
869
870 /*
871 * Propagate attributes through :: dependency lists.
872 */
873 Targ_Propagate();
874
875 /* print the initial graph, if the user requested it */
876 if (DEBUG(GRAPH1))
877 Targ_PrintGraph(1);
878
879 /* print the values of any variables requested by the user */
880 if (printVars) {
881 LstNode ln;
882
883 for (ln = Lst_First(variables); ln != NILLNODE;
884 ln = Lst_Succ(ln)) {
885 char *value = Var_Value((char *)Lst_Datum(ln),
886 VAR_GLOBAL, &p1);
887
888 printf("%s\n", value ? value : "");
889 if (p1)
890 free(p1);
891 }
892 }
893
894 /*
895 * Have now read the entire graph and need to make a list of targets
896 * to create. If none was given on the command line, we consult the
897 * parsing module to find the main target(s) to create.
898 */
899 if (Lst_IsEmpty(create))
900 targs = Parse_MainName();
901 else
902 targs = Targ_FindList(create, TARG_CREATE);
903
904 if (!compatMake && !printVars) {
905 /*
906 * Initialize job module before traversing the graph, now that
907 * any .BEGIN and .END targets have been read. This is done
908 * only if the -q flag wasn't given (to prevent the .BEGIN from
909 * being executed should it exist).
910 */
911 if (!queryFlag) {
912 if (maxLocal == -1)
913 maxLocal = maxJobs;
914 Job_Init(maxJobs, maxLocal);
915 jobsRunning = TRUE;
916 }
917
918 /* Traverse the graph, checking on all the targets */
919 outOfDate = Make_Run(targs);
920 } else if (!printVars) {
921 /*
922 * Compat_Init will take care of creating all the targets as
923 * well as initializing the module.
924 */
925 Compat_Run(targs);
926 }
927
928 #ifdef CLEANUP
929 Lst_Destroy(targs, NOFREE);
930 Lst_Destroy(variables, NOFREE);
931 Lst_Destroy(makefiles, NOFREE);
932 Lst_Destroy(create, (void (*)(ClientData))) free;
933 #endif
934
935 /* print the graph now it's been processed if the user requested it */
936 if (DEBUG(GRAPH2))
937 Targ_PrintGraph(2);
938
939 Trace_Log(MAKEEND, 0);
940
941 Suff_End();
942 Targ_End();
943 Arch_End();
944 Var_End();
945 Parse_End();
946 Dir_End();
947 Job_End();
948 Trace_End();
949
950 if (queryFlag && outOfDate)
951 return(1);
952 else
953 return(0);
954 }
955
956 /*-
957 * ReadMakefile --
958 * Open and parse the given makefile.
959 *
960 * Results:
961 * TRUE if ok. FALSE if couldn't open file.
962 *
963 * Side Effects:
964 * lots
965 */
966 static Boolean
967 ReadMakefile(ClientData p, ClientData 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(int ac, char **av, int copy)
1044 {
1045 static char *make[4];
1046 static char *cur_dir = NULL;
1047 char **mp;
1048 char *cp;
1049 int is_cmd, next_cmd;
1050 int i;
1051 int n;
1052
1053 if (Check_Cwd_Off)
1054 return NULL;
1055
1056 if (make[0] == NULL) {
1057 if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
1058 Check_Cwd_Off = 1;
1059 return NULL;
1060 }
1061
1062 make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
1063 if ((make[0] = strrchr(make[1], '/')) == NULL) {
1064 make[0] = make[1];
1065 make[1] = NULL;
1066 } else
1067 ++make[0];
1068 make[2] = NULL;
1069 cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
1070 }
1071 if (ac == 0 || av == NULL)
1072 return NULL; /* initialization only */
1073
1074 if (getenv("MAKEOBJDIR") == NULL &&
1075 getenv("MAKEOBJDIRPREFIX") == NULL)
1076 return NULL;
1077
1078
1079 next_cmd = 1;
1080 for (i = 0; i < ac; ++i) {
1081 is_cmd = next_cmd;
1082
1083 n = strlen(av[i]);
1084 cp = &(av[i])[n - 1];
1085 if (strspn(av[i], "|&;") == n) {
1086 next_cmd = 1;
1087 continue;
1088 } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
1089 next_cmd = 1;
1090 if (copy) {
1091 do {
1092 *cp-- = '\0';
1093 } while (*cp == ';' || *cp == '&' || *cp == '|' ||
1094 *cp == ')' || *cp == '}') ;
1095 } else {
1096 /*
1097 * XXX this should not happen.
1098 */
1099 fprintf(stderr, "WARNING: raw arg ends in shell meta '%s'\n",
1100 av[i]);
1101 }
1102 } else
1103 next_cmd = 0;
1104
1105 cp = av[i];
1106 if (*cp == ';' || *cp == '&' || *cp == '|')
1107 is_cmd = 1;
1108
1109 #ifdef check_cwd_debug
1110 fprintf(stderr, "av[%d] == %s '%s'",
1111 i, (is_cmd) ? "cmd" : "arg", av[i]);
1112 #endif
1113 if (is_cmd != 0) {
1114 if (*cp == '(' || *cp == '{' ||
1115 *cp == ';' || *cp == '&' || *cp == '|') {
1116 do {
1117 ++cp;
1118 } while (*cp == '(' || *cp == '{' ||
1119 *cp == ';' || *cp == '&' || *cp == '|');
1120 if (*cp == '\0') {
1121 next_cmd = 1;
1122 continue;
1123 }
1124 }
1125 if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
1126 #ifdef check_cwd_debug
1127 fprintf(stderr, " == cd, done.\n");
1128 #endif
1129 return NULL;
1130 }
1131 for (mp = make; *mp != NULL; ++mp) {
1132 n = strlen(*mp);
1133 if (strcmp(cp, *mp) == 0) {
1134 #ifdef check_cwd_debug
1135 fprintf(stderr, " %s == '%s', chdir(%s)\n",
1136 cp, *mp, cur_dir);
1137 #endif
1138 return cur_dir;
1139 }
1140 }
1141 }
1142 #ifdef check_cwd_debug
1143 fprintf(stderr, "\n");
1144 #endif
1145 }
1146 return NULL;
1147 }
1148
1149 char *
1150 Check_Cwd_Cmd(const char *cmd)
1151 {
1152 char *cp, *bp;
1153 char **av;
1154 int ac;
1155
1156 if (Check_Cwd_Off)
1157 return NULL;
1158
1159 if (cmd) {
1160 av = brk_string(cmd, &ac, TRUE, &bp);
1161 #ifdef check_cwd_debug
1162 fprintf(stderr, "splitting: '%s' -> %d words\n",
1163 cmd, ac);
1164 #endif
1165 } else {
1166 ac = 0;
1167 av = NULL;
1168 bp = NULL;
1169 }
1170 cp = Check_Cwd_av(ac, av, 1);
1171 if (bp) {
1172 free(av);
1173 free(bp);
1174 }
1175 return cp;
1176 }
1177
1178 void
1179 Check_Cwd(const char **argv)
1180 {
1181 char *cp;
1182 int ac;
1183
1184 if (Check_Cwd_Off)
1185 return;
1186
1187 for (ac = 0; argv[ac] != NULL; ++ac)
1188 /* NOTHING */;
1189 if (ac == 3 && *argv[1] == '-') {
1190 cp = Check_Cwd_Cmd(argv[2]);
1191 } else {
1192 cp = Check_Cwd_av(ac, UNCONST(argv), 0);
1193 }
1194 if (cp) {
1195 chdir(cp);
1196 }
1197 }
1198
1199 /*-
1200 * Cmd_Exec --
1201 * Execute the command in cmd, and return the output of that command
1202 * in a string.
1203 *
1204 * Results:
1205 * A string containing the output of the command, or the empty string
1206 * If err is not NULL, it contains the reason for the command failure
1207 *
1208 * Side Effects:
1209 * The string must be freed by the caller.
1210 */
1211 char *
1212 Cmd_Exec(const char *cmd, const char **err)
1213 {
1214 const char *args[4]; /* Args for invoking the shell */
1215 int fds[2]; /* Pipe streams */
1216 int cpid; /* Child PID */
1217 int pid; /* PID from wait() */
1218 char *res; /* result */
1219 int status; /* command exit status */
1220 Buffer buf; /* buffer to store the result */
1221 char *cp;
1222 int cc;
1223
1224
1225 *err = NULL;
1226
1227 if (!shellName)
1228 Shell_Init();
1229 /*
1230 * Set up arguments for shell
1231 */
1232 args[0] = shellName;
1233 args[1] = "-c";
1234 args[2] = cmd;
1235 args[3] = NULL;
1236
1237 /*
1238 * Open a pipe for fetching its output
1239 */
1240 if (pipe(fds) == -1) {
1241 *err = "Couldn't create pipe for \"%s\"";
1242 goto bad;
1243 }
1244
1245 /*
1246 * Fork
1247 */
1248 switch (cpid = vfork()) {
1249 case 0:
1250 /*
1251 * Close input side of pipe
1252 */
1253 (void) close(fds[0]);
1254
1255 /*
1256 * Duplicate the output stream to the shell's output, then
1257 * shut the extra thing down. Note we don't fetch the error
1258 * stream...why not? Why?
1259 */
1260 (void) dup2(fds[1], 1);
1261 (void) close(fds[1]);
1262
1263 (void) execv(shellPath, UNCONST(args));
1264 _exit(1);
1265 /*NOTREACHED*/
1266
1267 case -1:
1268 *err = "Couldn't exec \"%s\"";
1269 goto bad;
1270
1271 default:
1272 /*
1273 * No need for the writing half
1274 */
1275 (void) close(fds[1]);
1276
1277 buf = Buf_Init (MAKE_BSIZE);
1278
1279 do {
1280 char result[BUFSIZ];
1281 cc = read(fds[0], result, sizeof(result));
1282 if (cc > 0)
1283 Buf_AddBytes(buf, cc, (Byte *) result);
1284 }
1285 while (cc > 0 || (cc == -1 && errno == EINTR));
1286
1287 /*
1288 * Close the input side of the pipe.
1289 */
1290 (void) close(fds[0]);
1291
1292 /*
1293 * Wait for the process to exit.
1294 */
1295 while(((pid = wait(&status)) != cpid) && (pid >= 0))
1296 continue;
1297
1298 res = (char *)Buf_GetAll (buf, &cc);
1299 Buf_Destroy (buf, FALSE);
1300
1301 if (cc == 0)
1302 *err = "Couldn't read shell's output for \"%s\"";
1303
1304 if (status)
1305 *err = "\"%s\" returned non-zero status";
1306
1307 /*
1308 * Null-terminate the result, convert newlines to spaces and
1309 * install it in the variable.
1310 */
1311 res[cc] = '\0';
1312 cp = &res[cc];
1313
1314 if (cc > 0 && *--cp == '\n') {
1315 /*
1316 * A final newline is just stripped
1317 */
1318 *cp-- = '\0';
1319 }
1320 while (cp >= res) {
1321 if (*cp == '\n') {
1322 *cp = ' ';
1323 }
1324 cp--;
1325 }
1326 break;
1327 }
1328 return res;
1329 bad:
1330 res = emalloc(1);
1331 *res = '\0';
1332 return res;
1333 }
1334
1335 /*-
1336 * Error --
1337 * Print an error message given its format.
1338 *
1339 * Results:
1340 * None.
1341 *
1342 * Side Effects:
1343 * The message is printed.
1344 */
1345 /* VARARGS */
1346 void
1347 Error(const char *fmt, ...)
1348 {
1349 va_list ap;
1350
1351 va_start(ap, fmt);
1352 fprintf(stderr, "%s: ", progname);
1353 (void)vfprintf(stderr, fmt, ap);
1354 va_end(ap);
1355 (void)fprintf(stderr, "\n");
1356 (void)fflush(stderr);
1357 }
1358
1359 /*-
1360 * Fatal --
1361 * Produce a Fatal error message. If jobs are running, waits for them
1362 * to finish.
1363 *
1364 * Results:
1365 * None
1366 *
1367 * Side Effects:
1368 * The program exits
1369 */
1370 /* VARARGS */
1371 void
1372 Fatal(const char *fmt, ...)
1373 {
1374 va_list ap;
1375
1376 va_start(ap, fmt);
1377 if (jobsRunning)
1378 Job_Wait();
1379 Job_TokenFlush();
1380
1381 (void)vfprintf(stderr, fmt, ap);
1382 va_end(ap);
1383 (void)fprintf(stderr, "\n");
1384 (void)fflush(stderr);
1385
1386 PrintOnError(NULL);
1387
1388 if (DEBUG(GRAPH2))
1389 Targ_PrintGraph(2);
1390 Trace_Log(MAKEERROR, 0);
1391 exit(2); /* Not 1 so -q can distinguish error */
1392 }
1393
1394 /*
1395 * Punt --
1396 * Major exception once jobs are being created. Kills all jobs, prints
1397 * a message and exits.
1398 *
1399 * Results:
1400 * None
1401 *
1402 * Side Effects:
1403 * All children are killed indiscriminately and the program Lib_Exits
1404 */
1405 /* VARARGS */
1406 void
1407 Punt(const char *fmt, ...)
1408 {
1409 va_list ap;
1410
1411 va_start(ap, fmt);
1412 (void)fprintf(stderr, "%s: ", progname);
1413 (void)vfprintf(stderr, fmt, ap);
1414 va_end(ap);
1415 (void)fprintf(stderr, "\n");
1416 (void)fflush(stderr);
1417
1418 PrintOnError(NULL);
1419
1420 DieHorribly();
1421 }
1422
1423 /*-
1424 * DieHorribly --
1425 * Exit without giving a message.
1426 *
1427 * Results:
1428 * None
1429 *
1430 * Side Effects:
1431 * A big one...
1432 */
1433 void
1434 DieHorribly(void)
1435 {
1436 if (jobsRunning)
1437 Job_AbortAll();
1438 if (DEBUG(GRAPH2))
1439 Targ_PrintGraph(2);
1440 Trace_Log(MAKEERROR, 0);
1441 exit(2); /* Not 1, so -q can distinguish error */
1442 }
1443
1444 /*
1445 * Finish --
1446 * Called when aborting due to errors in child shell to signal
1447 * abnormal exit.
1448 *
1449 * Results:
1450 * None
1451 *
1452 * Side Effects:
1453 * The program exits
1454 */
1455 void
1456 Finish(int errors)
1457 /* number of errors encountered in Make_Make */
1458 {
1459 Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1460 }
1461
1462 /*
1463 * emalloc --
1464 * malloc, but die on error.
1465 */
1466 void *
1467 emalloc(size_t len)
1468 {
1469 void *p;
1470
1471 if ((p = malloc(len)) == NULL)
1472 enomem();
1473 return(p);
1474 }
1475
1476 /*
1477 * estrdup --
1478 * strdup, but die on error.
1479 */
1480 char *
1481 estrdup(const char *str)
1482 {
1483 char *p;
1484
1485 if ((p = strdup(str)) == NULL)
1486 enomem();
1487 return(p);
1488 }
1489
1490 /*
1491 * erealloc --
1492 * realloc, but die on error.
1493 */
1494 void *
1495 erealloc(void *ptr, size_t size)
1496 {
1497 if ((ptr = realloc(ptr, size)) == NULL)
1498 enomem();
1499 return(ptr);
1500 }
1501
1502 /*
1503 * enomem --
1504 * die when out of memory.
1505 */
1506 void
1507 enomem(void)
1508 {
1509 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
1510 exit(2);
1511 }
1512
1513 /*
1514 * enunlink --
1515 * Remove a file carefully, avoiding directories.
1516 */
1517 int
1518 eunlink(const char *file)
1519 {
1520 struct stat st;
1521
1522 if (lstat(file, &st) == -1)
1523 return -1;
1524
1525 if (S_ISDIR(st.st_mode)) {
1526 errno = EISDIR;
1527 return -1;
1528 }
1529 return unlink(file);
1530 }
1531
1532 /*
1533 * execError --
1534 * Print why exec failed, avoiding stdio.
1535 */
1536 void
1537 execError(const char *af, const char *av)
1538 {
1539 #ifdef USE_IOVEC
1540 int i = 0;
1541 struct iovec iov[8];
1542 #define IOADD(s) \
1543 (void)(iov[i].iov_base = UNCONST(s), \
1544 iov[i].iov_len = strlen(iov[i].iov_base), \
1545 i++)
1546 #else
1547 #define IOADD (void)write(2, s, strlen(s))
1548 #endif
1549
1550 IOADD(progname);
1551 IOADD(": ");
1552 IOADD(af);
1553 IOADD("(");
1554 IOADD(av);
1555 IOADD(") failed (");
1556 IOADD(strerror(errno));
1557 IOADD(")\n");
1558
1559 #ifdef USE_IOVEC
1560 (void)writev(2, iov, 8);
1561 #endif
1562 }
1563
1564 /*
1565 * usage --
1566 * exit with usage message
1567 */
1568 static void
1569 usage(void)
1570 {
1571 (void)fprintf(stderr,
1572 "Usage: %s [-Beiknqrst] [-D variable] [-d flags] [-f makefile]\n\
1573 [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
1574 [variable=value] [target ...]\n", progname);
1575 exit(2);
1576 }
1577
1578
1579 int
1580 PrintAddr(ClientData a, ClientData b)
1581 {
1582 printf("%lx ", (unsigned long) a);
1583 return b ? 0 : 0;
1584 }
1585
1586
1587
1588 void
1589 PrintOnError(const char *s)
1590 {
1591 char tmp[64];
1592
1593 if (s)
1594 printf("%s", s);
1595
1596 printf("\n%s: stopped in %s\n", progname, curdir);
1597 strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
1598 sizeof(tmp) - 1);
1599 s = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
1600 if (s && *s)
1601 printf("%s", s);
1602 }
1603
1604 void
1605 Main_ExportMAKEFLAGS(Boolean first)
1606 {
1607 static int once = 1;
1608 char tmp[64];
1609 char *s;
1610
1611 if (once != first)
1612 return;
1613 once = 0;
1614
1615 strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
1616 sizeof(tmp));
1617 s = Var_Subst(NULL, tmp, VAR_CMD, 0);
1618 if (s && *s) {
1619 #ifdef POSIX
1620 setenv("MAKEFLAGS", s, 1);
1621 #else
1622 setenv("MAKE", s, 1);
1623 #endif
1624 }
1625 }
1626