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