main.c revision 1.21 1 /* $NetBSD: main.c,v 1.21 1995/11/02 23:54:54 christos Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * Copyright (c) 1988, 1989 by Adam de Boor
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 #ifndef lint
42 char copyright[] =
43 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
44 All rights reserved.\n";
45 #endif /* not lint */
46
47 #ifndef lint
48 #if 0
49 static char sccsid[] = "@(#)main.c 5.25 (Berkeley) 4/1/91";
50 #else
51 static char rcsid[] = "$NetBSD: main.c,v 1.21 1995/11/02 23:54:54 christos Exp $";
52 #endif
53 #endif /* not lint */
54
55 /*-
56 * main.c --
57 * The main file for this entire program. Exit routines etc
58 * reside here.
59 *
60 * Utility functions defined in this file:
61 * Main_ParseArgLine Takes a line of arguments, breaks them and
62 * treats them as if they were given when first
63 * invoked. Used by the parse module to implement
64 * the .MFLAGS target.
65 *
66 * Error Print a tagged error message. The global
67 * MAKE variable must have been defined. This
68 * takes a format string and two optional
69 * arguments for it.
70 *
71 * Fatal Print an error message and exit. Also takes
72 * a format string and two arguments.
73 *
74 * Punt Aborts all jobs and exits with a message. Also
75 * takes a format string and two arguments.
76 *
77 * Finish Finish things up by printing the number of
78 * errors which occured, as passed to it, and
79 * exiting.
80 */
81
82 #include <sys/types.h>
83 #include <sys/time.h>
84 #include <sys/param.h>
85 #include <sys/resource.h>
86 #include <sys/signal.h>
87 #include <sys/stat.h>
88 #include <sys/utsname.h>
89 #include <sys/resource.h>
90 #include <errno.h>
91 #include <fcntl.h>
92 #include <stdio.h>
93 #if __STDC__
94 #include <stdarg.h>
95 #else
96 #include <varargs.h>
97 #endif
98 #include "make.h"
99 #include "hash.h"
100 #include "dir.h"
101 #include "job.h"
102 #include "pathnames.h"
103
104 #ifndef DEFMAXLOCAL
105 #define DEFMAXLOCAL DEFMAXJOBS
106 #endif DEFMAXLOCAL
107
108 #define MAKEFLAGS ".MAKEFLAGS"
109
110 Lst create; /* Targets to be made */
111 time_t now; /* Time at start of make */
112 GNode *DEFAULT; /* .DEFAULT node */
113 Boolean allPrecious; /* .PRECIOUS given on line by itself */
114
115 static Boolean noBuiltins; /* -r flag */
116 static Lst makefiles; /* ordered list of makefiles to read */
117 int maxJobs; /* -j argument */
118 static int maxLocal; /* -L argument */
119 Boolean compatMake; /* -B argument */
120 Boolean debug; /* -d flag */
121 Boolean noExecute; /* -n flag */
122 Boolean keepgoing; /* -k flag */
123 Boolean queryFlag; /* -q flag */
124 Boolean touchFlag; /* -t flag */
125 Boolean usePipes; /* !-P flag */
126 Boolean ignoreErrors; /* -i flag */
127 Boolean beSilent; /* -s flag */
128 Boolean oldVars; /* variable substitution style */
129 Boolean checkEnvFirst; /* -e flag */
130 static Boolean jobsRunning; /* TRUE if the jobs might be running */
131
132 static Boolean ReadMakefile();
133 static void usage();
134
135 static char *curdir; /* startup directory */
136 static char *objdir; /* where we chdir'ed to */
137
138 /*-
139 * MainParseArgs --
140 * Parse a given argument vector. Called from main() and from
141 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
142 *
143 * XXX: Deal with command line overriding .MAKEFLAGS in makefile
144 *
145 * Results:
146 * None
147 *
148 * Side Effects:
149 * Various global and local flags will be set depending on the flags
150 * given
151 */
152 static void
153 MainParseArgs(argc, argv)
154 int argc;
155 char **argv;
156 {
157 extern int optind;
158 extern char *optarg;
159 int c;
160
161 optind = 1; /* since we're called more than once */
162 #ifdef REMOTE
163 # define OPTFLAGS "BD:I:L:PSd:ef:ij:knqrst"
164 #else
165 # define OPTFLAGS "BD:I:PSd:ef:ij:knqrst"
166 #endif
167 rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
168 switch(c) {
169 case 'D':
170 Var_Set(optarg, "1", VAR_GLOBAL);
171 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
172 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
173 break;
174 case 'I':
175 Parse_AddIncludeDir(optarg);
176 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
177 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
178 break;
179 case 'B':
180 compatMake = TRUE;
181 break;
182 #ifdef REMOTE
183 case 'L':
184 maxLocal = atoi(optarg);
185 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
186 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
187 break;
188 #endif
189 case 'P':
190 usePipes = FALSE;
191 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
192 break;
193 case 'S':
194 keepgoing = FALSE;
195 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
196 break;
197 case 'd': {
198 char *modules = optarg;
199
200 for (; *modules; ++modules)
201 switch (*modules) {
202 case 'A':
203 debug = ~0;
204 break;
205 case 'a':
206 debug |= DEBUG_ARCH;
207 break;
208 case 'c':
209 debug |= DEBUG_COND;
210 break;
211 case 'd':
212 debug |= DEBUG_DIR;
213 break;
214 case 'f':
215 debug |= DEBUG_FOR;
216 break;
217 case 'g':
218 if (modules[1] == '1') {
219 debug |= DEBUG_GRAPH1;
220 ++modules;
221 }
222 else if (modules[1] == '2') {
223 debug |= DEBUG_GRAPH2;
224 ++modules;
225 }
226 break;
227 case 'j':
228 debug |= DEBUG_JOB;
229 break;
230 case 'm':
231 debug |= DEBUG_MAKE;
232 break;
233 case 's':
234 debug |= DEBUG_SUFF;
235 break;
236 case 't':
237 debug |= DEBUG_TARG;
238 break;
239 case 'v':
240 debug |= DEBUG_VAR;
241 break;
242 default:
243 (void)fprintf(stderr,
244 "make: illegal argument to d option -- %c\n",
245 *modules);
246 usage();
247 }
248 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
249 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
250 break;
251 }
252 case 'e':
253 checkEnvFirst = TRUE;
254 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
255 break;
256 case 'f':
257 (void)Lst_AtEnd(makefiles, (ClientData)optarg);
258 break;
259 case 'i':
260 ignoreErrors = TRUE;
261 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
262 break;
263 case 'j':
264 maxJobs = atoi(optarg);
265 #ifndef REMOTE
266 maxLocal = maxJobs;
267 #endif
268 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
269 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
270 break;
271 case 'k':
272 keepgoing = TRUE;
273 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
274 break;
275 case 'n':
276 noExecute = TRUE;
277 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
278 break;
279 case 'q':
280 queryFlag = TRUE;
281 /* Kind of nonsensical, wot? */
282 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
283 break;
284 case 'r':
285 noBuiltins = TRUE;
286 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
287 break;
288 case 's':
289 beSilent = TRUE;
290 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
291 break;
292 case 't':
293 touchFlag = TRUE;
294 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
295 break;
296 default:
297 case '?':
298 usage();
299 }
300 }
301
302 oldVars = TRUE;
303
304 /*
305 * See if the rest of the arguments are variable assignments and
306 * perform them if so. Else take them to be targets and stuff them
307 * on the end of the "create" list.
308 */
309 for (argv += optind, argc -= optind; *argv; ++argv, --argc)
310 if (Parse_IsVar(*argv))
311 Parse_DoVar(*argv, VAR_CMD);
312 else {
313 if (!**argv)
314 Punt("illegal (null) argument.");
315 if (**argv == '-') {
316 if ((*argv)[1])
317 optind = 0; /* -flag... */
318 else
319 optind = 1; /* - */
320 goto rearg;
321 }
322 (void)Lst_AtEnd(create, (ClientData)strdup(*argv));
323 }
324 }
325
326 /*-
327 * Main_ParseArgLine --
328 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
329 * is encountered and by main() when reading the .MAKEFLAGS envariable.
330 * Takes a line of arguments and breaks it into its
331 * component words and passes those words and the number of them to the
332 * MainParseArgs function.
333 * The line should have all its leading whitespace removed.
334 *
335 * Results:
336 * None
337 *
338 * Side Effects:
339 * Only those that come from the various arguments.
340 */
341 void
342 Main_ParseArgLine(line)
343 char *line; /* Line to fracture */
344 {
345 char **argv; /* Manufactured argument vector */
346 int argc; /* Number of arguments in argv */
347
348 if (line == NULL)
349 return;
350 for (; *line == ' '; ++line)
351 continue;
352 if (!*line)
353 return;
354
355 argv = brk_string(line, &argc, TRUE);
356 MainParseArgs(argc, argv);
357 }
358
359 /*-
360 * main --
361 * The main function, for obvious reasons. Initializes variables
362 * and a few modules, then parses the arguments give it in the
363 * environment and on the command line. Reads the system makefile
364 * followed by either Makefile, makefile or the file given by the
365 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
366 * flags it has received by then uses either the Make or the Compat
367 * module to create the initial list of targets.
368 *
369 * Results:
370 * If -q was given, exits -1 if anything was out-of-date. Else it exits
371 * 0.
372 *
373 * Side Effects:
374 * The program exits when done. Targets are created. etc. etc. etc.
375 */
376 int
377 main(argc, argv)
378 int argc;
379 char **argv;
380 {
381 Lst targs; /* target nodes to create -- passed to Make_Init */
382 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
383 struct stat sb, sa;
384 char *p, *p1, *path, *pwd, *getenv(), *getwd();
385 char mdpath[MAXPATHLEN + 1];
386 char obpath[MAXPATHLEN + 1];
387 char cdpath[MAXPATHLEN + 1];
388 struct utsname utsname;
389 char *machine = getenv("MACHINE");
390
391 #ifdef RLIMIT_NOFILE
392 /*
393 * get rid of resource limit on file descriptors
394 */
395 {
396 struct rlimit rl;
397 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
398 rl.rlim_cur != rl.rlim_max) {
399 rl.rlim_cur = rl.rlim_max;
400 (void) setrlimit(RLIMIT_NOFILE, &rl);
401 }
402 }
403 #endif
404 /*
405 * Find where we are and take care of PWD for the automounter...
406 * All this code is so that we know where we are when we start up
407 * on a different machine with pmake.
408 */
409 curdir = cdpath;
410 if (getcwd(curdir, MAXPATHLEN) == NULL) {
411 (void)fprintf(stderr, "make: %s.\n", strerror(errno));
412 exit(2);
413 }
414
415 if (stat(curdir, &sa) == -1) {
416 (void)fprintf(stderr, "make: %s: %s.\n",
417 curdir, strerror(errno));
418 exit(2);
419 }
420
421 if ((pwd = getenv("PWD")) != NULL) {
422 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
423 sa.st_dev == sb.st_dev)
424 (void) strcpy(curdir, pwd);
425 }
426
427 /*
428 * Get the name of this type of MACHINE from utsname
429 * so we can share an executable for similar machines.
430 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
431 *
432 * Note that while MACHINE is decided at run-time,
433 * MACHINE_ARCH is always known at compile time.
434 */
435 if (!machine) {
436 if (uname(&utsname)) {
437 perror("make: uname");
438 exit(2);
439 }
440 machine = utsname.machine;
441 }
442
443 /*
444 * if the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
445 * exists, change into it and build there. Once things are
446 * initted, have to add the original directory to the search path,
447 * and modify the paths for the Makefiles apropriately. The
448 * current directory is also placed as a variable for make scripts.
449 */
450 if (!(path = getenv("MAKEOBJDIR"))) {
451 path = _PATH_OBJDIR;
452 (void) sprintf(mdpath, "%s.%s", path, machine);
453 }
454 else
455 (void) strncpy(mdpath, path, MAXPATHLEN + 1);
456
457 if (stat(mdpath, &sb) == 0 && S_ISDIR(sb.st_mode)) {
458
459 if (chdir(mdpath)) {
460 (void)fprintf(stderr, "make warning: %s: %s.\n",
461 mdpath, strerror(errno));
462 objdir = curdir;
463 }
464 else {
465 if (mdpath[0] != '/') {
466 (void) sprintf(obpath, "%s/%s", curdir, mdpath);
467 objdir = obpath;
468 }
469 else
470 objdir = mdpath;
471 }
472 }
473 else {
474 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
475
476 if (chdir(path)) {
477 (void)fprintf(stderr, "make warning: %s: %s.\n",
478 path, strerror(errno));
479 objdir = curdir;
480 }
481 else {
482 if (path[0] != '/') {
483 (void) sprintf(obpath, "%s/%s", curdir,
484 path);
485 objdir = obpath;
486 }
487 else
488 objdir = obpath;
489 }
490 }
491 else
492 objdir = curdir;
493 }
494
495 setenv("PWD", objdir, 1);
496
497 create = Lst_Init(FALSE);
498 makefiles = Lst_Init(FALSE);
499 beSilent = FALSE; /* Print commands as executed */
500 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
501 noExecute = FALSE; /* Execute all commands */
502 keepgoing = FALSE; /* Stop on error */
503 allPrecious = FALSE; /* Remove targets when interrupted */
504 queryFlag = FALSE; /* This is not just a check-run */
505 noBuiltins = FALSE; /* Read the built-in rules */
506 touchFlag = FALSE; /* Actually update targets */
507 usePipes = TRUE; /* Catch child output in pipes */
508 debug = 0; /* No debug verbosity, please. */
509 jobsRunning = FALSE;
510
511 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
512 #ifdef REMOTE
513 maxJobs = DEFMAXJOBS; /* Set default max concurrency */
514 #else
515 maxJobs = maxLocal;
516 #endif
517 compatMake = FALSE; /* No compat mode */
518
519
520 /*
521 * Initialize the parsing, directory and variable modules to prepare
522 * for the reading of inclusion paths and variable settings on the
523 * command line
524 */
525 Dir_Init(); /* Initialize directory structures so -I flags
526 * can be processed correctly */
527 Parse_Init(); /* Need to initialize the paths of #include
528 * directories */
529 Var_Init(); /* As well as the lists of variables for
530 * parsing arguments */
531 str_init();
532 if (objdir != curdir)
533 Dir_AddDir(dirSearchPath, curdir);
534 Var_Set(".CURDIR", curdir, VAR_GLOBAL);
535 Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
536
537 /*
538 * Initialize various variables.
539 * MAKE also gets this name, for compatibility
540 * .MAKEFLAGS gets set to the empty string just in case.
541 * MFLAGS also gets initialized empty, for compatibility.
542 */
543 Var_Set("MAKE", argv[0], VAR_GLOBAL);
544 Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
545 Var_Set("MFLAGS", "", VAR_GLOBAL);
546 Var_Set("MACHINE", machine, VAR_GLOBAL);
547 #ifdef MACHINE_ARCH
548 Var_Set("MACHINE_ARCH", MACHINE_ARCH, VAR_GLOBAL);
549 #endif
550
551 /*
552 * First snag any flags out of the MAKE environment variable.
553 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
554 * in a different format).
555 */
556 #ifdef POSIX
557 Main_ParseArgLine(getenv("MAKEFLAGS"));
558 #else
559 Main_ParseArgLine(getenv("MAKE"));
560 #endif
561
562 MainParseArgs(argc, argv);
563
564 /*
565 * Initialize archive, target and suffix modules in preparation for
566 * parsing the makefile(s)
567 */
568 Arch_Init();
569 Targ_Init();
570 Suff_Init();
571
572 DEFAULT = NILGNODE;
573 (void)time(&now);
574
575 /*
576 * Set up the .TARGETS variable to contain the list of targets to be
577 * created. If none specified, make the variable empty -- the parser
578 * will fill the thing in with the default or .MAIN target.
579 */
580 if (!Lst_IsEmpty(create)) {
581 LstNode ln;
582
583 for (ln = Lst_First(create); ln != NILLNODE;
584 ln = Lst_Succ(ln)) {
585 char *name = (char *)Lst_Datum(ln);
586
587 Var_Append(".TARGETS", name, VAR_GLOBAL);
588 }
589 } else
590 Var_Set(".TARGETS", "", VAR_GLOBAL);
591
592 /*
593 * Read in the built-in rules first, followed by the specified makefile,
594 * if it was (makefile != (char *) NULL), or the default Makefile and
595 * makefile, in that order, if it wasn't.
596 */
597 if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
598 Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
599
600 if (!Lst_IsEmpty(makefiles)) {
601 LstNode ln;
602
603 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
604 if (ln != NILLNODE)
605 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
606 } else if (!ReadMakefile("makefile"))
607 (void)ReadMakefile("Makefile");
608
609 (void)ReadMakefile(".depend");
610
611 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
612 if (p1)
613 free(p1);
614
615 /* Install all the flags into the MAKE envariable. */
616 if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
617 #ifdef POSIX
618 setenv("MAKEFLAGS", p, 1);
619 #else
620 setenv("MAKE", p, 1);
621 #endif
622 if (p1)
623 free(p1);
624
625 /*
626 * For compatibility, look at the directories in the VPATH variable
627 * and add them to the search path, if the variable is defined. The
628 * variable's value is in the same format as the PATH envariable, i.e.
629 * <directory>:<directory>:<directory>...
630 */
631 if (Var_Exists("VPATH", VAR_CMD)) {
632 char *vpath, *path, *cp, savec;
633 /*
634 * GCC stores string constants in read-only memory, but
635 * Var_Subst will want to write this thing, so store it
636 * in an array
637 */
638 static char VPATH[] = "${VPATH}";
639
640 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
641 path = vpath;
642 do {
643 /* skip to end of directory */
644 for (cp = path; *cp != ':' && *cp != '\0'; cp++)
645 continue;
646 /* Save terminator character so know when to stop */
647 savec = *cp;
648 *cp = '\0';
649 /* Add directory to search path */
650 Dir_AddDir(dirSearchPath, path);
651 *cp = savec;
652 path = cp + 1;
653 } while (savec == ':');
654 (void)free((Address)vpath);
655 }
656
657 /*
658 * Now that all search paths have been read for suffixes et al, it's
659 * time to add the default search path to their lists...
660 */
661 Suff_DoPaths();
662
663 /* print the initial graph, if the user requested it */
664 if (DEBUG(GRAPH1))
665 Targ_PrintGraph(1);
666
667 /*
668 * Have now read the entire graph and need to make a list of targets
669 * to create. If none was given on the command line, we consult the
670 * parsing module to find the main target(s) to create.
671 */
672 if (Lst_IsEmpty(create))
673 targs = Parse_MainName();
674 else
675 targs = Targ_FindList(create, TARG_CREATE);
676
677 /*
678 * this was original amMake -- want to allow parallelism, so put this
679 * back in, eventually.
680 */
681 if (!compatMake) {
682 /*
683 * Initialize job module before traversing the graph, now that
684 * any .BEGIN and .END targets have been read. This is done
685 * only if the -q flag wasn't given (to prevent the .BEGIN from
686 * being executed should it exist).
687 */
688 if (!queryFlag) {
689 if (maxLocal == -1)
690 maxLocal = maxJobs;
691 Job_Init(maxJobs, maxLocal);
692 jobsRunning = TRUE;
693 }
694
695 /* Traverse the graph, checking on all the targets */
696 outOfDate = Make_Run(targs);
697 } else
698 /*
699 * Compat_Init will take care of creating all the targets as
700 * well as initializing the module.
701 */
702 Compat_Run(targs);
703
704 Lst_Destroy(targs, NOFREE);
705 Lst_Destroy(makefiles, NOFREE);
706 Lst_Destroy(create, (void (*) __P((ClientData))) free);
707
708 /* print the graph now it's been processed if the user requested it */
709 if (DEBUG(GRAPH2))
710 Targ_PrintGraph(2);
711
712 Suff_End();
713 Targ_End();
714 Arch_End();
715 str_end();
716 Var_End();
717 Parse_End();
718 Dir_End();
719
720 if (queryFlag && outOfDate)
721 return(1);
722 else
723 return(0);
724 }
725
726 /*-
727 * ReadMakefile --
728 * Open and parse the given makefile.
729 *
730 * Results:
731 * TRUE if ok. FALSE if couldn't open file.
732 *
733 * Side Effects:
734 * lots
735 */
736 static Boolean
737 ReadMakefile(fname)
738 char *fname; /* makefile to read */
739 {
740 extern Lst parseIncPath, sysIncPath;
741 FILE *stream;
742 char *name, path[MAXPATHLEN + 1];
743
744 if (!strcmp(fname, "-")) {
745 Parse_File("(stdin)", stdin);
746 Var_Set("MAKEFILE", "", VAR_GLOBAL);
747 } else {
748 if ((stream = fopen(fname, "r")) != NULL)
749 goto found;
750 /* if we've chdir'd, rebuild the path name */
751 if (curdir != objdir && *fname != '/') {
752 (void)sprintf(path, "%s/%s", curdir, fname);
753 if ((stream = fopen(path, "r")) != NULL) {
754 fname = path;
755 goto found;
756 }
757 }
758 /* look in -I and system include directories. */
759 name = Dir_FindFile(fname, parseIncPath);
760 if (!name)
761 name = Dir_FindFile(fname, sysIncPath);
762 if (!name || !(stream = fopen(name, "r")))
763 return(FALSE);
764 fname = name;
765 /*
766 * set the MAKEFILE variable desired by System V fans -- the
767 * placement of the setting here means it gets set to the last
768 * makefile specified, as it is set by SysV make.
769 */
770 found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
771 Parse_File(fname, stream);
772 (void)fclose(stream);
773 }
774 return(TRUE);
775 }
776
777 /*-
778 * Error --
779 * Print an error message given its format.
780 *
781 * Results:
782 * None.
783 *
784 * Side Effects:
785 * The message is printed.
786 */
787 /* VARARGS */
788 void
789 #if __STDC__
790 Error(char *fmt, ...)
791 #else
792 Error(va_alist)
793 va_dcl
794 #endif
795 {
796 va_list ap;
797 #if __STDC__
798 va_start(ap, fmt);
799 #else
800 char *fmt;
801
802 va_start(ap);
803 fmt = va_arg(ap, char *);
804 #endif
805 (void)vfprintf(stderr, fmt, ap);
806 va_end(ap);
807 (void)fprintf(stderr, "\n");
808 (void)fflush(stderr);
809 }
810
811 /*-
812 * Fatal --
813 * Produce a Fatal error message. If jobs are running, waits for them
814 * to finish.
815 *
816 * Results:
817 * None
818 *
819 * Side Effects:
820 * The program exits
821 */
822 /* VARARGS */
823 void
824 #if __STDC__
825 Fatal(char *fmt, ...)
826 #else
827 Fatal(va_alist)
828 va_dcl
829 #endif
830 {
831 va_list ap;
832 #if __STDC__
833 va_start(ap, fmt);
834 #else
835 char *fmt;
836
837 va_start(ap);
838 fmt = va_arg(ap, char *);
839 #endif
840 if (jobsRunning)
841 Job_Wait();
842
843 (void)vfprintf(stderr, fmt, ap);
844 va_end(ap);
845 (void)fprintf(stderr, "\n");
846 (void)fflush(stderr);
847
848 if (DEBUG(GRAPH2))
849 Targ_PrintGraph(2);
850 exit(2); /* Not 1 so -q can distinguish error */
851 }
852
853 /*
854 * Punt --
855 * Major exception once jobs are being created. Kills all jobs, prints
856 * a message and exits.
857 *
858 * Results:
859 * None
860 *
861 * Side Effects:
862 * All children are killed indiscriminately and the program Lib_Exits
863 */
864 /* VARARGS */
865 void
866 #if __STDC__
867 Punt(char *fmt, ...)
868 #else
869 Punt(va_alist)
870 va_dcl
871 #endif
872 {
873 va_list ap;
874 #if __STDC__
875 va_start(ap, fmt);
876 #else
877 char *fmt;
878
879 va_start(ap);
880 fmt = va_arg(ap, char *);
881 #endif
882
883 (void)fprintf(stderr, "make: ");
884 (void)vfprintf(stderr, fmt, ap);
885 va_end(ap);
886 (void)fprintf(stderr, "\n");
887 (void)fflush(stderr);
888
889 DieHorribly();
890 }
891
892 /*-
893 * DieHorribly --
894 * Exit without giving a message.
895 *
896 * Results:
897 * None
898 *
899 * Side Effects:
900 * A big one...
901 */
902 void
903 DieHorribly()
904 {
905 if (jobsRunning)
906 Job_AbortAll();
907 if (DEBUG(GRAPH2))
908 Targ_PrintGraph(2);
909 exit(2); /* Not 1, so -q can distinguish error */
910 }
911
912 /*
913 * Finish --
914 * Called when aborting due to errors in child shell to signal
915 * abnormal exit.
916 *
917 * Results:
918 * None
919 *
920 * Side Effects:
921 * The program exits
922 */
923 void
924 Finish(errors)
925 int errors; /* number of errors encountered in Make_Make */
926 {
927 Fatal("%d error%s", errors, errors == 1 ? "" : "s");
928 }
929
930 /*
931 * emalloc --
932 * malloc, but die on error.
933 */
934 char *
935 emalloc(len)
936 size_t len;
937 {
938 char *p;
939
940 if ((p = (char *) malloc(len)) == NULL)
941 enomem();
942 return(p);
943 }
944
945 /*
946 * enomem --
947 * die when out of memory.
948 */
949 void
950 enomem()
951 {
952 (void)fprintf(stderr, "make: %s.\n", strerror(errno));
953 exit(2);
954 }
955
956 /*
957 * enunlink --
958 * Remove a file carefully, avoiding directories.
959 */
960 int
961 eunlink(file)
962 const char *file;
963 {
964 struct stat st;
965
966 if (lstat(file, &st) == -1)
967 return -1;
968
969 if (S_ISDIR(st.st_mode)) {
970 errno = EISDIR;
971 return -1;
972 }
973 return unlink(file);
974 }
975
976 /*
977 * usage --
978 * exit with usage message
979 */
980 static void
981 usage()
982 {
983 (void)fprintf(stderr,
984 "usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
985 [-I directory] [-j max_jobs] [variable=value]\n");
986 exit(2);
987 }
988
989
990 int
991 PrintAddr(a, b)
992 ClientData a;
993 ClientData b;
994 {
995 printf("%lx ", (unsigned long) a);
996 return b ? 0 : 0;
997 }
998