fd129a3635803143472ccdc854effedc5e6124ef
[dragonfly.git] / usr.bin / make / main.c
1 /*
2  * Copyright (c) 1988, 1989, 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1989 by Berkeley Softworks
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Adam de Boor.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * @(#) Copyright (c) 1988, 1989, 1990, 1993 The Regents of the University of California.  All rights reserved.
39  * @(#)main.c   8.3 (Berkeley) 3/19/94
40  * $FreeBSD: src/usr.bin/make/main.c,v 1.35.2.9 2003/04/15 14:37:35 ru Exp $
41  * $DragonFly: src/usr.bin/make/main.c,v 1.2 2003/06/17 04:29:29 dillon Exp $
42  */
43
44 /*-
45  * main.c --
46  *      The main file for this entire program. Exit routines etc
47  *      reside here.
48  *
49  * Utility functions defined in this file:
50  *      Main_ParseArgLine       Takes a line of arguments, breaks them and
51  *                              treats them as if they were given when first
52  *                              invoked. Used by the parse module to implement
53  *                              the .MFLAGS target.
54  *
55  *      Error                   Print a tagged error message. The global
56  *                              MAKE variable must have been defined. This
57  *                              takes a format string and two optional
58  *                              arguments for it.
59  *
60  *      Fatal                   Print an error message and exit. Also takes
61  *                              a format string and two arguments.
62  *
63  *      Punt                    Aborts all jobs and exits with a message. Also
64  *                              takes a format string and two arguments.
65  *
66  *      Finish                  Finish things up by printing the number of
67  *                              errors which occured, as passed to it, and
68  *                              exiting.
69  */
70
71 #include <sys/types.h>
72 #include <sys/time.h>
73 #include <sys/param.h>
74 #include <sys/resource.h>
75 #include <sys/signal.h>
76 #include <sys/stat.h>
77 #if defined(__i386__)
78 #include <sys/sysctl.h>
79 #endif
80 #ifndef MACHINE
81 #include <sys/utsname.h>
82 #endif
83 #include <sys/wait.h>
84 #include <err.h>
85 #include <stdlib.h>
86 #include <errno.h>
87 #include <fcntl.h>
88 #include <stdio.h>
89 #include <sysexits.h>
90 #ifdef __STDC__
91 #include <stdarg.h>
92 #else
93 #include <varargs.h>
94 #endif
95 #include "make.h"
96 #include "hash.h"
97 #include "dir.h"
98 #include "job.h"
99 #include "pathnames.h"
100
101 #ifndef DEFMAXLOCAL
102 #define DEFMAXLOCAL DEFMAXJOBS
103 #endif  /* DEFMAXLOCAL */
104
105 #define MAKEFLAGS       ".MAKEFLAGS"
106
107 Lst                     create;         /* Targets to be made */
108 time_t                  now;            /* Time at start of make */
109 GNode                   *DEFAULT;       /* .DEFAULT node */
110 Boolean                 allPrecious;    /* .PRECIOUS given on line by itself */
111
112 static Boolean          noBuiltins;     /* -r flag */
113 static Lst              makefiles;      /* ordered list of makefiles to read */
114 static Boolean          printVars;      /* print value of one or more vars */
115 static Boolean          expandVars;     /* fully expand printed variables */
116 static Lst              variables;      /* list of variables to print */
117 int                     maxJobs;        /* -j argument */
118 static Boolean          forceJobs;      /* -j argument given */
119 static int              maxLocal;       /* -L argument */
120 Boolean                 compatMake;     /* -B argument */
121 Boolean                 debug;          /* -d flag */
122 Boolean                 noExecute;      /* -n flag */
123 Boolean                 keepgoing;      /* -k flag */
124 Boolean                 queryFlag;      /* -q flag */
125 Boolean                 touchFlag;      /* -t flag */
126 Boolean                 usePipes;       /* !-P flag */
127 Boolean                 ignoreErrors;   /* -i flag */
128 Boolean                 beSilent;       /* -s flag */
129 Boolean                 beVerbose;      /* -v flag */
130 Boolean                 oldVars;        /* variable substitution style */
131 Boolean                 checkEnvFirst;  /* -e flag */
132 Lst                     envFirstVars;   /* (-E) vars to override from env */
133 static Boolean          jobsRunning;    /* TRUE if the jobs might be running */
134
135 static void             MainParseArgs __P((int, char **));
136 char *                  chdir_verify_path __P((char *, char *));
137 static int              ReadMakefile __P((ClientData, ClientData));
138 static void             usage __P((void));
139
140 static char *curdir;                    /* startup directory */
141 static char *objdir;                    /* where we chdir'ed to */
142
143 /*-
144  * MainParseArgs --
145  *      Parse a given argument vector. Called from main() and from
146  *      Main_ParseArgLine() when the .MAKEFLAGS target is used.
147  *
148  *      XXX: Deal with command line overriding .MAKEFLAGS in makefile
149  *
150  * Results:
151  *      None
152  *
153  * Side Effects:
154  *      Various global and local flags will be set depending on the flags
155  *      given
156  */
157 static void
158 MainParseArgs(argc, argv)
159         int argc;
160         char **argv;
161 {
162         extern int optind;
163         extern char *optarg;
164         char *p;
165         int c;
166
167         optind = 1;     /* since we're called more than once */
168 #ifdef REMOTE
169 # define OPTFLAGS "BC:D:E:I:L:PSV:Xd:ef:ij:km:nqrstv"
170 #else
171 # define OPTFLAGS "BC:D:E:I:PSV:Xd:ef:ij:km:nqrstv"
172 #endif
173 rearg:  while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
174                 switch(c) {
175                 case 'C':
176                         if (chdir(optarg) == -1)
177                                 err(1, "chdir %s", optarg);
178                         break;
179                 case 'D':
180                         Var_Set(optarg, "1", VAR_GLOBAL);
181                         Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
182                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
183                         break;
184                 case 'I':
185                         Parse_AddIncludeDir(optarg);
186                         Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
187                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
188                         break;
189                 case 'V':
190                         printVars = TRUE;
191                         (void)Lst_AtEnd(variables, (ClientData)optarg);
192                         Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
193                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
194                         break;
195                 case 'X':
196                         expandVars = FALSE;
197                         break;
198                 case 'B':
199                         compatMake = TRUE;
200                         Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
201                         break;
202 #ifdef REMOTE
203                 case 'L': {
204                         char *endptr;
205
206                         maxLocal = strtol(optarg, &endptr, 10);
207                         if (maxLocal < 0 || *endptr != '\0') {
208                                 warnx("illegal number, -L argument -- %s",
209                                     optarg);
210                                 usage();
211                         }
212                         Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
213                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
214                         break;
215                 }
216 #endif
217                 case 'P':
218                         usePipes = FALSE;
219                         Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
220                         break;
221                 case 'S':
222                         keepgoing = FALSE;
223                         Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
224                         break;
225                 case 'd': {
226                         char *modules = optarg;
227
228                         for (; *modules; ++modules)
229                                 switch (*modules) {
230                                 case 'A':
231                                         debug = ~0;
232                                         break;
233                                 case 'a':
234                                         debug |= DEBUG_ARCH;
235                                         break;
236                                 case 'c':
237                                         debug |= DEBUG_COND;
238                                         break;
239                                 case 'd':
240                                         debug |= DEBUG_DIR;
241                                         break;
242                                 case 'f':
243                                         debug |= DEBUG_FOR;
244                                         break;
245                                 case 'g':
246                                         if (modules[1] == '1') {
247                                                 debug |= DEBUG_GRAPH1;
248                                                 ++modules;
249                                         }
250                                         else if (modules[1] == '2') {
251                                                 debug |= DEBUG_GRAPH2;
252                                                 ++modules;
253                                         }
254                                         break;
255                                 case 'j':
256                                         debug |= DEBUG_JOB;
257                                         break;
258                                 case 'l':
259                                         debug |= DEBUG_LOUD;
260                                         break;
261                                 case 'm':
262                                         debug |= DEBUG_MAKE;
263                                         break;
264                                 case 's':
265                                         debug |= DEBUG_SUFF;
266                                         break;
267                                 case 't':
268                                         debug |= DEBUG_TARG;
269                                         break;
270                                 case 'v':
271                                         debug |= DEBUG_VAR;
272                                         break;
273                                 default:
274                                         warnx("illegal argument to d option -- %c", *modules);
275                                         usage();
276                                 }
277                         Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
278                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
279                         break;
280                 }
281                 case 'E':
282                         p = malloc(strlen(optarg) + 1);
283                         if (!p)
284                                 Punt("make: cannot allocate memory.");
285                         (void)strcpy(p, optarg);
286                         (void)Lst_AtEnd(envFirstVars, (ClientData)p);
287                         Var_Append(MAKEFLAGS, "-E", VAR_GLOBAL);
288                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
289                         break;
290                 case 'e':
291                         checkEnvFirst = TRUE;
292                         Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
293                         break;
294                 case 'f':
295                         (void)Lst_AtEnd(makefiles, (ClientData)optarg);
296                         break;
297                 case 'i':
298                         ignoreErrors = TRUE;
299                         Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
300                         break;
301                 case 'j': {
302                         char *endptr;
303
304                         forceJobs = TRUE;
305                         maxJobs = strtol(optarg, &endptr, 10);
306                         if (maxJobs <= 0 || *endptr != '\0') {
307                                 warnx("illegal number, -j argument -- %s",
308                                     optarg);
309                                 usage();
310                         }
311 #ifndef REMOTE
312                         maxLocal = maxJobs;
313 #endif
314                         Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
315                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
316                         break;
317                 }
318                 case 'k':
319                         keepgoing = TRUE;
320                         Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
321                         break;
322                 case 'm':
323                         Dir_AddDir(sysIncPath, optarg);
324                         Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
325                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
326                         break;
327                 case 'n':
328                         noExecute = TRUE;
329                         Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
330                         break;
331                 case 'q':
332                         queryFlag = TRUE;
333                         /* Kind of nonsensical, wot? */
334                         Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
335                         break;
336                 case 'r':
337                         noBuiltins = TRUE;
338                         Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
339                         break;
340                 case 's':
341                         beSilent = TRUE;
342                         Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
343                         break;
344                 case 't':
345                         touchFlag = TRUE;
346                         Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
347                         break;
348                 case 'v':
349                         beVerbose = TRUE;
350                         Var_Append(MAKEFLAGS, "-v", VAR_GLOBAL);
351                         break;
352                 default:
353                 case '?':
354                         usage();
355                 }
356         }
357
358         oldVars = TRUE;
359
360         /*
361          * See if the rest of the arguments are variable assignments and
362          * perform them if so. Else take them to be targets and stuff them
363          * on the end of the "create" list.
364          */
365         for (argv += optind, argc -= optind; *argv; ++argv, --argc)
366                 if (Parse_IsVar(*argv))
367                         Parse_DoVar(*argv, VAR_CMD);
368                 else {
369                         if (!**argv)
370                                 Punt("illegal (null) argument.");
371                         if (**argv == '-') {
372                                 if ((*argv)[1])
373                                         optind = 0;     /* -flag... */
374                                 else
375                                         optind = 1;     /* - */
376                                 goto rearg;
377                         }
378                         (void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
379                 }
380 }
381
382 /*-
383  * Main_ParseArgLine --
384  *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target
385  *      is encountered and by main() when reading the .MAKEFLAGS envariable.
386  *      Takes a line of arguments and breaks it into its
387  *      component words and passes those words and the number of them to the
388  *      MainParseArgs function.
389  *      The line should have all its leading whitespace removed.
390  *
391  * Results:
392  *      None
393  *
394  * Side Effects:
395  *      Only those that come from the various arguments.
396  */
397 void
398 Main_ParseArgLine(line)
399         char *line;                     /* Line to fracture */
400 {
401         char **argv;                    /* Manufactured argument vector */
402         int argc;                       /* Number of arguments in argv */
403
404         if (line == NULL)
405                 return;
406         for (; *line == ' '; ++line)
407                 continue;
408         if (!*line)
409                 return;
410
411         argv = brk_string(line, &argc, TRUE);
412         MainParseArgs(argc, argv);
413 }
414
415 char *
416 chdir_verify_path(path, obpath)
417         char *path;
418         char *obpath;
419 {
420         struct stat sb;
421
422         if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
423                 if (chdir(path)) {
424                         warn("warning: %s", path);
425                         return 0;
426                 }
427                 else {
428                         if (path[0] != '/') {
429                                 (void) snprintf(obpath, MAXPATHLEN, "%s/%s",
430                                                 curdir, path);
431                                 return obpath;
432                         }
433                         else
434                                 return path;
435                 }
436         }
437
438         return 0;
439 }
440
441
442 /*-
443  * main --
444  *      The main function, for obvious reasons. Initializes variables
445  *      and a few modules, then parses the arguments give it in the
446  *      environment and on the command line. Reads the system makefile
447  *      followed by either Makefile, makefile or the file given by the
448  *      -f argument. Sets the .MAKEFLAGS PMake variable based on all the
449  *      flags it has received by then uses either the Make or the Compat
450  *      module to create the initial list of targets.
451  *
452  * Results:
453  *      If -q was given, exits -1 if anything was out-of-date. Else it exits
454  *      0.
455  *
456  * Side Effects:
457  *      The program exits when done. Targets are created. etc. etc. etc.
458  */
459 int
460 main(argc, argv)
461         int argc;
462         char **argv;
463 {
464         Lst targs;      /* target nodes to create -- passed to Make_Init */
465         Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
466         struct stat sa;
467         char *p, *p1, *path, *pathp;
468 #ifdef WANT_ENV_PWD
469         struct stat sb;
470         char *pwd;
471 #endif
472         char mdpath[MAXPATHLEN + 1];
473         char obpath[MAXPATHLEN + 1];
474         char cdpath[MAXPATHLEN + 1];
475         char *machine = getenv("MACHINE");
476         char *machine_arch = getenv("MACHINE_ARCH");
477         char *machine_cpu = getenv("MACHINE_CPU");
478         Lst sysMkPath;                  /* Path of sys.mk */
479         char *cp = NULL, *start;
480                                         /* avoid faults on read-only strings */
481         static char syspath[] = _PATH_DEFSYSPATH;
482
483 #ifdef RLIMIT_NOFILE
484         /*
485          * get rid of resource limit on file descriptors
486          */
487         {
488                 struct rlimit rl;
489                 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
490                     rl.rlim_cur != rl.rlim_max) {
491                         rl.rlim_cur = rl.rlim_max;
492                         (void) setrlimit(RLIMIT_NOFILE, &rl);
493                 }
494         }
495 #endif
496         /*
497          * Find where we are and take care of PWD for the automounter...
498          * All this code is so that we know where we are when we start up
499          * on a different machine with pmake.
500          */
501         curdir = cdpath;
502         if (getcwd(curdir, MAXPATHLEN) == NULL)
503                 err(2, NULL);
504
505         if (stat(curdir, &sa) == -1)
506             err(2, "%s", curdir);
507
508 #ifdef WANT_ENV_PWD
509         if ((pwd = getenv("PWD")) != NULL) {
510             if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
511                 sa.st_dev == sb.st_dev)
512                 (void) strcpy(curdir, pwd);
513         }
514 #endif
515
516 #if defined(__i386__) && defined(__FreeBSD_version) && \
517     __FreeBSD_version > 300003
518         /*
519          * PC-98 kernel sets the `i386' string to the utsname.machine and
520          * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
521          * we check machine.ispc98 and adjust the machine variable before
522          * using usname(3) below.
523          * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
524          * __FreeBSD_version was defined as 300003. So, this check can
525          * safely be done with any kernel with version > 300003.
526          */
527         if (!machine) {
528                 int     ispc98;
529                 size_t  len;
530
531                 len = sizeof(ispc98);
532                 if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
533                         if (ispc98)
534                                 machine = "pc98";
535                 }
536         }
537 #endif
538
539         /*
540          * Get the name of this type of MACHINE from utsname
541          * so we can share an executable for similar machines.
542          * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
543          *
544          * Note that while MACHINE is decided at run-time,
545          * MACHINE_ARCH is always known at compile time.
546          */
547         if (!machine) {
548 #ifndef MACHINE
549             struct utsname utsname;
550
551             if (uname(&utsname) == -1) {
552                     perror("make: uname");
553                     exit(2);
554             }
555             machine = utsname.machine;
556 #else
557             machine = MACHINE;
558 #endif
559         }
560
561         if (!machine_arch) {
562 #ifndef MACHINE_ARCH
563                 machine_arch = "unknown";
564 #else
565                 machine_arch = MACHINE_ARCH;
566 #endif
567         }
568
569         /*
570          * Set machine_cpu to the minumum supported CPU revision based
571          * on the target architecture, if not already set.
572          */
573         if (!machine_cpu) {
574                 if (!strcmp(machine_arch, "i386"))
575                         machine_cpu = "i386";
576                 else if (!strcmp(machine_arch, "alpha"))
577                         machine_cpu = "ev4";
578                 else
579                         machine_cpu = "unknown";
580         }
581         
582         /*
583          * The object directory location is determined using the
584          * following order of preference:
585          *
586          *      1. MAKEOBJDIRPREFIX`cwd`
587          *      2. MAKEOBJDIR
588          *      3. _PATH_OBJDIR.${MACHINE}
589          *      4. _PATH_OBJDIR
590          *      5. _PATH_OBJDIRPREFIX`cwd`
591          *
592          * If one of the first two fails, use the current directory.
593          * If the remaining three all fail, use the current directory.
594          *
595          * Once things are initted,
596          * have to add the original directory to the search path,
597          * and modify the paths for the Makefiles apropriately.  The
598          * current directory is also placed as a variable for make scripts.
599          */
600         if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
601                 if (!(path = getenv("MAKEOBJDIR"))) {
602                         path = _PATH_OBJDIR;
603                         pathp = _PATH_OBJDIRPREFIX;
604                         (void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
605                                         path, machine);
606                         if (!(objdir = chdir_verify_path(mdpath, obpath)))
607                                 if (!(objdir=chdir_verify_path(path, obpath))) {
608                                         (void) snprintf(mdpath, MAXPATHLEN,
609                                                         "%s%s", pathp, curdir);
610                                         if (!(objdir=chdir_verify_path(mdpath,
611                                                                        obpath)))
612                                                 objdir = curdir;
613                                 }
614                 }
615                 else if (!(objdir = chdir_verify_path(path, obpath)))
616                         objdir = curdir;
617         }
618         else {
619                 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
620                 if (!(objdir = chdir_verify_path(mdpath, obpath)))
621                         objdir = curdir;
622         }
623
624 #ifdef WANT_ENV_PWD
625         setenv("PWD", objdir, 1);
626 #endif
627
628         create = Lst_Init(FALSE);
629         makefiles = Lst_Init(FALSE);
630         envFirstVars = Lst_Init(FALSE);
631         printVars = FALSE;
632         expandVars = TRUE;
633         variables = Lst_Init(FALSE);
634         beSilent = FALSE;               /* Print commands as executed */
635         ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
636         noExecute = FALSE;              /* Execute all commands */
637         keepgoing = FALSE;              /* Stop on error */
638         allPrecious = FALSE;            /* Remove targets when interrupted */
639         queryFlag = FALSE;              /* This is not just a check-run */
640         noBuiltins = FALSE;             /* Read the built-in rules */
641         touchFlag = FALSE;              /* Actually update targets */
642         usePipes = TRUE;                /* Catch child output in pipes */
643         debug = 0;                      /* No debug verbosity, please. */
644         jobsRunning = FALSE;
645
646         maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
647 #ifdef REMOTE
648         maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
649 #else
650         maxJobs = maxLocal;
651 #endif
652         forceJobs = FALSE;              /* No -j flag */
653         compatMake = FALSE;             /* No compat mode */
654
655
656         /*
657          * Initialize the parsing, directory and variable modules to prepare
658          * for the reading of inclusion paths and variable settings on the
659          * command line
660          */
661         Dir_Init();             /* Initialize directory structures so -I flags
662                                  * can be processed correctly */
663         Parse_Init();           /* Need to initialize the paths of #include
664                                  * directories */
665         Var_Init();             /* As well as the lists of variables for
666                                  * parsing arguments */
667         str_init();
668         if (objdir != curdir)
669                 Dir_AddDir(dirSearchPath, curdir);
670         Var_Set(".CURDIR", curdir, VAR_GLOBAL);
671         Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
672
673         /*
674          * Initialize various variables.
675          *      MAKE also gets this name, for compatibility
676          *      .MAKEFLAGS gets set to the empty string just in case.
677          *      MFLAGS also gets initialized empty, for compatibility.
678          */
679         Var_Set("MAKE", argv[0], VAR_GLOBAL);
680         Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
681         Var_Set("MFLAGS", "", VAR_GLOBAL);
682         Var_Set("MACHINE", machine, VAR_GLOBAL);
683         Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
684         Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
685
686         /*
687          * First snag any flags out of the MAKE environment variable.
688          * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
689          * in a different format).
690          */
691 #ifdef POSIX
692         Main_ParseArgLine(getenv("MAKEFLAGS"));
693 #else
694         Main_ParseArgLine(getenv("MAKE"));
695 #endif
696
697         MainParseArgs(argc, argv);
698
699         /*
700          * Be compatible if user did not specify -j and did not explicitly
701          * turned compatibility on
702          */
703         if (!compatMake && !forceJobs)
704                 compatMake = TRUE;
705
706         /*
707          * Initialize archive, target and suffix modules in preparation for
708          * parsing the makefile(s)
709          */
710         Arch_Init();
711         Targ_Init();
712         Suff_Init();
713
714         DEFAULT = NILGNODE;
715         (void)time(&now);
716
717         /*
718          * Set up the .TARGETS variable to contain the list of targets to be
719          * created. If none specified, make the variable empty -- the parser
720          * will fill the thing in with the default or .MAIN target.
721          */
722         if (!Lst_IsEmpty(create)) {
723                 LstNode ln;
724
725                 for (ln = Lst_First(create); ln != NILLNODE;
726                     ln = Lst_Succ(ln)) {
727                         char *name = (char *)Lst_Datum(ln);
728
729                         Var_Append(".TARGETS", name, VAR_GLOBAL);
730                 }
731         } else
732                 Var_Set(".TARGETS", "", VAR_GLOBAL);
733
734
735         /*
736          * If no user-supplied system path was given (through the -m option)
737          * add the directories from the DEFSYSPATH (more than one may be given
738          * as dir1:...:dirn) to the system include path.
739          */
740         if (Lst_IsEmpty(sysIncPath)) {
741                 for (start = syspath; *start != '\0'; start = cp) {
742                         for (cp = start; *cp != '\0' && *cp != ':'; cp++)
743                                 continue;
744                         if (*cp == '\0') {
745                                 Dir_AddDir(sysIncPath, start);
746                         } else {
747                                 *cp++ = '\0';
748                                 Dir_AddDir(sysIncPath, start);
749                         }
750                 }
751         }
752
753         /*
754          * Read in the built-in rules first, followed by the specified
755          * makefile, if it was (makefile != (char *) NULL), or the default
756          * Makefile and makefile, in that order, if it wasn't.
757          */
758         if (!noBuiltins) {
759                 LstNode ln;
760
761                 sysMkPath = Lst_Init (FALSE);
762                 Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
763                 if (Lst_IsEmpty(sysMkPath))
764                         Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
765                 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
766                 if (ln != NILLNODE)
767                         Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
768         }
769
770         if (!Lst_IsEmpty(makefiles)) {
771                 LstNode ln;
772
773                 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
774                 if (ln != NILLNODE)
775                         Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
776         } else if (!ReadMakefile("makefile", NULL))
777                 (void)ReadMakefile("Makefile", NULL);
778
779         (void)ReadMakefile(".depend", NULL);
780
781         Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
782         efree(p1);
783
784         /* Install all the flags into the MAKE envariable. */
785         if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
786 #ifdef POSIX
787                 setenv("MAKEFLAGS", p, 1);
788 #else
789                 setenv("MAKE", p, 1);
790 #endif
791         efree(p1);
792
793         /*
794          * For compatibility, look at the directories in the VPATH variable
795          * and add them to the search path, if the variable is defined. The
796          * variable's value is in the same format as the PATH envariable, i.e.
797          * <directory>:<directory>:<directory>...
798          */
799         if (Var_Exists("VPATH", VAR_CMD)) {
800                 char *vpath, *path, *cp, savec;
801                 /*
802                  * GCC stores string constants in read-only memory, but
803                  * Var_Subst will want to write this thing, so store it
804                  * in an array
805                  */
806                 static char VPATH[] = "${VPATH}";
807
808                 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
809                 path = vpath;
810                 do {
811                         /* skip to end of directory */
812                         for (cp = path; *cp != ':' && *cp != '\0'; cp++)
813                                 continue;
814                         /* Save terminator character so know when to stop */
815                         savec = *cp;
816                         *cp = '\0';
817                         /* Add directory to search path */
818                         Dir_AddDir(dirSearchPath, path);
819                         *cp = savec;
820                         path = cp + 1;
821                 } while (savec == ':');
822                 (void)free((Address)vpath);
823         }
824
825         /*
826          * Now that all search paths have been read for suffixes et al, it's
827          * time to add the default search path to their lists...
828          */
829         Suff_DoPaths();
830
831         /* print the initial graph, if the user requested it */
832         if (DEBUG(GRAPH1))
833                 Targ_PrintGraph(1);
834
835         /* print the values of any variables requested by the user */
836         if (printVars) {
837                 LstNode ln;
838
839                 for (ln = Lst_First(variables); ln != NILLNODE;
840                     ln = Lst_Succ(ln)) {
841                         char *value;
842                         if (expandVars) {
843                                 p1 = malloc(strlen((char *)Lst_Datum(ln)) + 1 + 3);
844                                 if (!p1)
845                                         Punt("make: cannot allocate memory.");
846                                 /* This sprintf is safe, because of the malloc above */
847                                 (void)sprintf(p1, "${%s}", (char *)Lst_Datum(ln));
848                                 value = Var_Subst(NULL, p1, VAR_GLOBAL, FALSE);
849                         } else {
850                                 value = Var_Value((char *)Lst_Datum(ln),
851                                                   VAR_GLOBAL, &p1);
852                         }
853                         printf("%s\n", value ? value : "");
854                         if (p1)
855                                 free(p1);
856                 }
857         }
858
859         /*
860          * Have now read the entire graph and need to make a list of targets
861          * to create. If none was given on the command line, we consult the
862          * parsing module to find the main target(s) to create.
863          */
864         if (Lst_IsEmpty(create))
865                 targs = Parse_MainName();
866         else
867                 targs = Targ_FindList(create, TARG_CREATE);
868
869         if (!compatMake && !printVars) {
870                 /*
871                  * Initialize job module before traversing the graph, now that
872                  * any .BEGIN and .END targets have been read.  This is done
873                  * only if the -q flag wasn't given (to prevent the .BEGIN from
874                  * being executed should it exist).
875                  */
876                 if (!queryFlag) {
877                         if (maxLocal == -1)
878                                 maxLocal = maxJobs;
879                         Job_Init(maxJobs, maxLocal);
880                         jobsRunning = TRUE;
881                 }
882
883                 /* Traverse the graph, checking on all the targets */
884                 outOfDate = Make_Run(targs);
885         } else if (!printVars) {
886                 /*
887                  * Compat_Init will take care of creating all the targets as
888                  * well as initializing the module.
889                  */
890                 Compat_Run(targs);
891         }
892
893         Lst_Destroy(targs, NOFREE);
894         Lst_Destroy(variables, NOFREE);
895         Lst_Destroy(makefiles, NOFREE);
896         Lst_Destroy(create, (void (*) __P((ClientData))) free);
897
898         /* print the graph now it's been processed if the user requested it */
899         if (DEBUG(GRAPH2))
900                 Targ_PrintGraph(2);
901
902         Suff_End();
903         Targ_End();
904         Arch_End();
905         str_end();
906         Var_End();
907         Parse_End();
908         Dir_End();
909
910         if (queryFlag && outOfDate)
911                 return(1);
912         else
913                 return(0);
914 }
915
916 /*-
917  * ReadMakefile  --
918  *      Open and parse the given makefile.
919  *
920  * Results:
921  *      TRUE if ok. FALSE if couldn't open file.
922  *
923  * Side Effects:
924  *      lots
925  */
926 static Boolean
927 ReadMakefile(p, q)
928         ClientData p, q;
929 {
930         char *fname = p;                /* makefile to read */
931         extern Lst parseIncPath;
932         FILE *stream;
933         char *name, path[MAXPATHLEN + 1];
934         char *MAKEFILE;
935         int setMAKEFILE;
936
937         if (!strcmp(fname, "-")) {
938                 Parse_File("(stdin)", stdin);
939                 Var_Set("MAKEFILE", "", VAR_GLOBAL);
940         } else {
941                 setMAKEFILE = strcmp(fname, ".depend");
942
943                 /* if we've chdir'd, rebuild the path name */
944                 if (curdir != objdir && *fname != '/') {
945                         (void)snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
946                         /*
947                          * XXX The realpath stuff breaks relative includes
948                          * XXX in some cases.   The problem likely is in
949                          * XXX parse.c where it does special things in
950                          * XXX ParseDoInclude if the file is relateive
951                          * XXX or absolute and not a system file.  There
952                          * XXX it assumes that if the current file that's
953                          * XXX being included is absolute, that any files
954                          * XXX that it includes shouldn't do the -I path
955                          * XXX stuff, which is inconsistant with historical
956                          * XXX behavior.  However, I can't pentrate the mists
957                          * XXX further, so I'm putting this workaround in
958                          * XXX here until such time as the underlying bug
959                          * XXX can be fixed.
960                          */
961 #if THIS_BREAKS_THINGS
962                         if (realpath(path, path) != NULL &&
963                             (stream = fopen(path, "r")) != NULL) {
964                                 MAKEFILE = fname;
965                                 fname = path;
966                                 goto found;
967                         }
968                 } else if (realpath(fname, path) != NULL) {
969                         MAKEFILE = fname;
970                         fname = path;
971                         if ((stream = fopen(fname, "r")) != NULL)
972                                 goto found;
973                 }
974 #else
975                         if ((stream = fopen(path, "r")) != NULL) {
976                                 MAKEFILE = fname;
977                                 fname = path;
978                                 goto found;
979                         }
980                 } else {
981                         MAKEFILE = fname;
982                         if ((stream = fopen(fname, "r")) != NULL)
983                                 goto found;
984                 }
985 #endif
986                 /* look in -I and system include directories. */
987                 name = Dir_FindFile(fname, parseIncPath);
988                 if (!name)
989                         name = Dir_FindFile(fname, sysIncPath);
990                 if (!name || !(stream = fopen(name, "r")))
991                         return(FALSE);
992                 MAKEFILE = fname = name;
993                 /*
994                  * set the MAKEFILE variable desired by System V fans -- the
995                  * placement of the setting here means it gets set to the last
996                  * makefile specified, as it is set by SysV make.
997                  */
998 found:
999                 if (setMAKEFILE)
1000                         Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL);
1001                 Parse_File(fname, stream);
1002                 (void)fclose(stream);
1003         }
1004         return(TRUE);
1005 }
1006
1007 /*-
1008  * Cmd_Exec --
1009  *      Execute the command in cmd, and return the output of that command
1010  *      in a string.
1011  *
1012  * Results:
1013  *      A string containing the output of the command, or the empty string
1014  *      If err is not NULL, it contains the reason for the command failure
1015  *
1016  * Side Effects:
1017  *      The string must be freed by the caller.
1018  */
1019 char *
1020 Cmd_Exec(cmd, err)
1021     char *cmd;
1022     char **err;
1023 {
1024     char        *args[4];       /* Args for invoking the shell */
1025     int         fds[2];         /* Pipe streams */
1026     int         cpid;           /* Child PID */
1027     int         pid;            /* PID from wait() */
1028     char        *res;           /* result */
1029     int         status;         /* command exit status */
1030     Buffer      buf;            /* buffer to store the result */
1031     char        *cp;
1032     int         cc;
1033
1034
1035     *err = NULL;
1036
1037     /*
1038      * Set up arguments for shell
1039      */
1040     args[0] = "sh";
1041     args[1] = "-c";
1042     args[2] = cmd;
1043     args[3] = NULL;
1044
1045     /*
1046      * Open a pipe for fetching its output
1047      */
1048     if (pipe(fds) == -1) {
1049         *err = "Couldn't create pipe for \"%s\"";
1050         goto bad;
1051     }
1052
1053     /*
1054      * Fork
1055      */
1056     switch (cpid = vfork()) {
1057     case 0:
1058         /*
1059          * Close input side of pipe
1060          */
1061         (void) close(fds[0]);
1062
1063         /*
1064          * Duplicate the output stream to the shell's output, then
1065          * shut the extra thing down. Note we don't fetch the error
1066          * stream...why not? Why?
1067          */
1068         (void) dup2(fds[1], 1);
1069         (void) close(fds[1]);
1070
1071         (void) execv("/bin/sh", args);
1072         _exit(1);
1073         /*NOTREACHED*/
1074
1075     case -1:
1076         *err = "Couldn't exec \"%s\"";
1077         goto bad;
1078
1079     default:
1080         /*
1081          * No need for the writing half
1082          */
1083         (void) close(fds[1]);
1084
1085         buf = Buf_Init (MAKE_BSIZE);
1086
1087         do {
1088             char   result[BUFSIZ];
1089             cc = read(fds[0], result, sizeof(result));
1090             if (cc > 0)
1091                 Buf_AddBytes(buf, cc, (Byte *) result);
1092         }
1093         while (cc > 0 || (cc == -1 && errno == EINTR));
1094
1095         /*
1096          * Close the input side of the pipe.
1097          */
1098         (void) close(fds[0]);
1099
1100         /*
1101          * Wait for the process to exit.
1102          */
1103         while(((pid = wait(&status)) != cpid) && (pid >= 0))
1104             continue;
1105
1106         if (cc == -1)
1107             *err = "Error reading shell's output for \"%s\"";
1108
1109         res = (char *)Buf_GetAll (buf, &cc);
1110         Buf_Destroy (buf, FALSE);
1111
1112         if (status)
1113             *err = "\"%s\" returned non-zero status";
1114
1115         /*
1116          * Null-terminate the result, convert newlines to spaces and
1117          * install it in the variable.
1118          */
1119         res[cc] = '\0';
1120         cp = &res[cc] - 1;
1121
1122         if (*cp == '\n') {
1123             /*
1124              * A final newline is just stripped
1125              */
1126             *cp-- = '\0';
1127         }
1128         while (cp >= res) {
1129             if (*cp == '\n') {
1130                 *cp = ' ';
1131             }
1132             cp--;
1133         }
1134         break;
1135     }
1136     return res;
1137 bad:
1138     res = emalloc(1);
1139     *res = '\0';
1140     return res;
1141 }
1142
1143 /*-
1144  * Error --
1145  *      Print an error message given its format.
1146  *
1147  * Results:
1148  *      None.
1149  *
1150  * Side Effects:
1151  *      The message is printed.
1152  */
1153 /* VARARGS */
1154 void
1155 #ifdef __STDC__
1156 Error(char *fmt, ...)
1157 #else
1158 Error(va_alist)
1159         va_dcl
1160 #endif
1161 {
1162         va_list ap;
1163 #ifdef __STDC__
1164         va_start(ap, fmt);
1165 #else
1166         char *fmt;
1167
1168         va_start(ap);
1169         fmt = va_arg(ap, char *);
1170 #endif
1171         (void)vfprintf(stderr, fmt, ap);
1172         va_end(ap);
1173         (void)fprintf(stderr, "\n");
1174         (void)fflush(stderr);
1175 }
1176
1177 /*-
1178  * Fatal --
1179  *      Produce a Fatal error message. If jobs are running, waits for them
1180  *      to finish.
1181  *
1182  * Results:
1183  *      None
1184  *
1185  * Side Effects:
1186  *      The program exits
1187  */
1188 /* VARARGS */
1189 void
1190 #ifdef __STDC__
1191 Fatal(char *fmt, ...)
1192 #else
1193 Fatal(va_alist)
1194         va_dcl
1195 #endif
1196 {
1197         va_list ap;
1198 #ifdef __STDC__
1199         va_start(ap, fmt);
1200 #else
1201         char *fmt;
1202
1203         va_start(ap);
1204         fmt = va_arg(ap, char *);
1205 #endif
1206         if (jobsRunning)
1207                 Job_Wait();
1208
1209         (void)vfprintf(stderr, fmt, ap);
1210         va_end(ap);
1211         (void)fprintf(stderr, "\n");
1212         (void)fflush(stderr);
1213
1214         if (DEBUG(GRAPH2))
1215                 Targ_PrintGraph(2);
1216         exit(2);                /* Not 1 so -q can distinguish error */
1217 }
1218
1219 /*
1220  * Punt --
1221  *      Major exception once jobs are being created. Kills all jobs, prints
1222  *      a message and exits.
1223  *
1224  * Results:
1225  *      None
1226  *
1227  * Side Effects:
1228  *      All children are killed indiscriminately and the program Lib_Exits
1229  */
1230 /* VARARGS */
1231 void
1232 #ifdef __STDC__
1233 Punt(char *fmt, ...)
1234 #else
1235 Punt(va_alist)
1236         va_dcl
1237 #endif
1238 {
1239         va_list ap;
1240 #if __STDC__
1241         va_start(ap, fmt);
1242 #else
1243         char *fmt;
1244
1245         va_start(ap);
1246         fmt = va_arg(ap, char *);
1247 #endif
1248
1249         (void)fprintf(stderr, "make: ");
1250         (void)vfprintf(stderr, fmt, ap);
1251         va_end(ap);
1252         (void)fprintf(stderr, "\n");
1253         (void)fflush(stderr);
1254
1255         DieHorribly();
1256 }
1257
1258 /*-
1259  * DieHorribly --
1260  *      Exit without giving a message.
1261  *
1262  * Results:
1263  *      None
1264  *
1265  * Side Effects:
1266  *      A big one...
1267  */
1268 void
1269 DieHorribly()
1270 {
1271         if (jobsRunning)
1272                 Job_AbortAll();
1273         if (DEBUG(GRAPH2))
1274                 Targ_PrintGraph(2);
1275         exit(2);                /* Not 1, so -q can distinguish error */
1276 }
1277
1278 /*
1279  * Finish --
1280  *      Called when aborting due to errors in child shell to signal
1281  *      abnormal exit.
1282  *
1283  * Results:
1284  *      None
1285  *
1286  * Side Effects:
1287  *      The program exits
1288  */
1289 void
1290 Finish(errors)
1291         int errors;     /* number of errors encountered in Make_Make */
1292 {
1293         Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1294 }
1295
1296 /*
1297  * emalloc --
1298  *      malloc, but die on error.
1299  */
1300 void *
1301 emalloc(len)
1302         size_t len;
1303 {
1304         void *p;
1305
1306         if ((p = malloc(len)) == NULL)
1307                 enomem();
1308         return(p);
1309 }
1310
1311 /*
1312  * estrdup --
1313  *      strdup, but die on error.
1314  */
1315 char *
1316 estrdup(str)
1317         const char *str;
1318 {
1319         char *p;
1320
1321         if ((p = strdup(str)) == NULL)
1322                 enomem();
1323         return(p);
1324 }
1325
1326 /*
1327  * erealloc --
1328  *      realloc, but die on error.
1329  */
1330 void *
1331 erealloc(ptr, size)
1332         void *ptr;
1333         size_t size;
1334 {
1335         if ((ptr = realloc(ptr, size)) == NULL)
1336                 enomem();
1337         return(ptr);
1338 }
1339
1340 /*
1341  * enomem --
1342  *      die when out of memory.
1343  */
1344 void
1345 enomem()
1346 {
1347         err(2, NULL);
1348 }
1349
1350 /*
1351  * enunlink --
1352  *      Remove a file carefully, avoiding directories.
1353  */
1354 int
1355 eunlink(file)
1356         const char *file;
1357 {
1358         struct stat st;
1359
1360         if (lstat(file, &st) == -1)
1361                 return -1;
1362
1363         if (S_ISDIR(st.st_mode)) {
1364                 errno = EISDIR;
1365                 return -1;
1366         }
1367         return unlink(file);
1368 }
1369
1370 /*
1371  * usage --
1372  *      exit with usage message
1373  */
1374 static void
1375 usage()
1376 {
1377         (void)fprintf(stderr, "%s\n%s\n%s\n",
1378 "usage: make [-BPSXeiknqrstv] [-C directory] [-D variable] [-d flags]",
1379 "            [-E variable] [-f makefile] [-I directory] [-j max_jobs]",
1380 "            [-m directory] [-V variable] [variable=value] [target ...]");
1381         exit(2);
1382 }
1383
1384
1385 int
1386 PrintAddr(a, b)
1387     ClientData a;
1388     ClientData b;
1389 {
1390     printf("%lx ", (unsigned long) a);
1391     return b ? 0 : 0;
1392 }