patch-7.151
[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.118 2005/02/13 13:33:56 harti Exp $
41  * $DragonFly: src/usr.bin/make/main.c,v 1.64 2005/03/19 00:19:55 okumoto 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
56 #ifndef MACHINE
57 #include <sys/utsname.h>
58 #endif
59 #include <sys/param.h>
60 #include <sys/stat.h>
61 #include <sys/time.h>
62 #include <sys/resource.h>
63 #include <sys/wait.h>
64 #include <err.h>
65 #include <errno.h>
66 #include <signal.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <unistd.h>
70
71 #include "arch.h"
72 #include "buf.h"
73 #include "compat.h"
74 #include "config.h"
75 #include "dir.h"
76 #include "globals.h"
77 #include "job.h"
78 #include "make.h"
79 #include "nonints.h"
80 #include "parse.h"
81 #include "pathnames.h"
82 #include "str.h"
83 #include "suff.h"
84 #include "targ.h"
85 #include "util.h"
86 #include "var.h"
87
88 #define WANT_ENV_MKLVL  1
89 #define MKLVL_MAXVAL    500
90 #define MKLVL_ENVVAR    "__MKLVL__"
91
92 #define MAKEFLAGS       ".MAKEFLAGS"
93
94 /* Targets to be made */
95 Lst create = Lst_Initializer(create);
96
97 time_t                  now;            /* Time at start of make */
98 struct GNode            *DEFAULT;       /* .DEFAULT node */
99 Boolean                 allPrecious;    /* .PRECIOUS given on line by itself */
100
101 static Boolean          noBuiltins;     /* -r flag */
102
103 /* ordered list of makefiles to read */
104 static Lst makefiles = Lst_Initializer(makefiles);
105
106 static Boolean          expandVars;     /* fully expand printed variables */
107
108 /* list of variables to print */
109 static Lst variables = Lst_Initializer(variables);
110
111 int                     maxJobs;        /* -j argument */
112 static Boolean          forceJobs;      /* -j argument given */
113 Boolean                 compatMake;     /* -B argument */
114 Boolean                 debug;          /* -d flag */
115 Boolean                 noExecute;      /* -n flag */
116 Boolean                 keepgoing;      /* -k flag */
117 Boolean                 queryFlag;      /* -q flag */
118 Boolean                 touchFlag;      /* -t flag */
119 Boolean                 usePipes;       /* !-P flag */
120 Boolean                 ignoreErrors;   /* -i flag */
121 Boolean                 beSilent;       /* -s flag */
122 Boolean                 beVerbose;      /* -v flag */
123 Boolean                 oldVars;        /* variable substitution style */
124 Boolean                 checkEnvFirst;  /* -e flag */
125
126 /* (-E) vars to override from env */
127 Lst envFirstVars = Lst_Initializer(envFirstVars);
128
129 Boolean                 jobsRunning;    /* TRUE if the jobs might be running */
130
131 static void             MainParseArgs(int, char **);
132 char                    *chdir_verify_path(const char *, char *);
133 static int              ReadMakefile(const char *);
134 static void             usage(void);
135
136 static char *curdir;                    /* startup directory */
137 static char *objdir;                    /* where we chdir'ed to */
138
139 /*
140  * Append a flag with an optional argument to MAKEFLAGS and MFLAGS
141  */
142 static void
143 MFLAGS_append(const char *flag, char *arg)
144 {
145         char *str;
146
147         Var_Append(MAKEFLAGS, flag, VAR_GLOBAL);
148         if (arg != NULL) {
149                 str = MAKEFLAGS_quote(arg);
150                 Var_Append(MAKEFLAGS, str, VAR_GLOBAL);
151                 free(str);
152         }
153
154         Var_Append("MFLAGS", flag, VAR_GLOBAL);
155         if (arg != NULL) {
156                 str = MAKEFLAGS_quote(arg);
157                 Var_Append("MFLAGS", str, VAR_GLOBAL);
158                 free(str);
159         }
160 }
161
162 /*-
163  * MainParseArgs --
164  *      Parse a given argument vector. Called from main() and from
165  *      Main_ParseArgLine() when the .MAKEFLAGS target is used.
166  *
167  *      XXX: Deal with command line overriding .MAKEFLAGS in makefile
168  *
169  * Results:
170  *      None
171  *
172  * Side Effects:
173  *      Various global and local flags will be set depending on the flags
174  *      given
175  */
176 static void
177 MainParseArgs(int argc, char **argv)
178 {
179         int c;
180
181         optind = 1;     /* since we're called more than once */
182 #define OPTFLAGS "BC:D:E:I:PSV:Xd:ef:ij:km:nqrstv"
183 rearg:  while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
184                 switch(c) {
185                 case 'C':
186                         if (chdir(optarg) == -1)
187                                 err(1, "chdir %s", optarg);
188                         break;
189                 case 'D':
190                         Var_Set(optarg, "1", VAR_GLOBAL);
191                         MFLAGS_append("-D", optarg);
192                         break;
193                 case 'I':
194                         Parse_AddIncludeDir(optarg);
195                         MFLAGS_append("-I", optarg);
196                         break;
197                 case 'V':
198                         Lst_AtEnd(&variables, estrdup(optarg));
199                         MFLAGS_append("-V", optarg);
200                         break;
201                 case 'X':
202                         expandVars = FALSE;
203                         break;
204                 case 'B':
205                         compatMake = TRUE;
206                         MFLAGS_append("-B", NULL);
207                         unsetenv("MAKE_JOBS_FIFO");
208                         break;
209                 case 'P':
210                         usePipes = FALSE;
211                         MFLAGS_append("-P", NULL);
212                         break;
213                 case 'S':
214                         keepgoing = FALSE;
215                         MFLAGS_append("-S", NULL);
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 'l':
251                                         debug |= DEBUG_LOUD;
252                                         break;
253                                 case 'm':
254                                         debug |= DEBUG_MAKE;
255                                         break;
256                                 case 's':
257                                         debug |= DEBUG_SUFF;
258                                         break;
259                                 case 't':
260                                         debug |= DEBUG_TARG;
261                                         break;
262                                 case 'v':
263                                         debug |= DEBUG_VAR;
264                                         break;
265                                 default:
266                                         warnx("illegal argument to d option -- %c", *modules);
267                                         usage();
268                                 }
269                         MFLAGS_append("-d", optarg);
270                         break;
271                 }
272                 case 'E':
273                         Lst_AtEnd(&envFirstVars, estrdup(optarg));
274                         MFLAGS_append("-E", optarg);
275                         break;
276                 case 'e':
277                         checkEnvFirst = TRUE;
278                         MFLAGS_append("-e", NULL);
279                         break;
280                 case 'f':
281                         Lst_AtEnd(&makefiles, estrdup(optarg));
282                         break;
283                 case 'i':
284                         ignoreErrors = TRUE;
285                         MFLAGS_append("-i", NULL);
286                         break;
287                 case 'j': {
288                         char *endptr;
289
290                         forceJobs = TRUE;
291                         maxJobs = strtol(optarg, &endptr, 10);
292                         if (maxJobs <= 0 || *endptr != '\0') {
293                                 warnx("illegal number, -j argument -- %s",
294                                     optarg);
295                                 usage();
296                         }
297                         MFLAGS_append("-j", optarg);
298                         break;
299                 }
300                 case 'k':
301                         keepgoing = TRUE;
302                         MFLAGS_append("-k", NULL);
303                         break;
304                 case 'm':
305                         Dir_AddDir(&sysIncPath, optarg);
306                         MFLAGS_append("-m", optarg);
307                         break;
308                 case 'n':
309                         noExecute = TRUE;
310                         MFLAGS_append("-n", NULL);
311                         break;
312                 case 'q':
313                         queryFlag = TRUE;
314                         /* Kind of nonsensical, wot? */
315                         MFLAGS_append("-q", NULL);
316                         break;
317                 case 'r':
318                         noBuiltins = TRUE;
319                         MFLAGS_append("-r", NULL);
320                         break;
321                 case 's':
322                         beSilent = TRUE;
323                         MFLAGS_append("-s", NULL);
324                         break;
325                 case 't':
326                         touchFlag = TRUE;
327                         MFLAGS_append("-t", NULL);
328                         break;
329                 case 'v':
330                         beVerbose = TRUE;
331                         MFLAGS_append("-v", NULL);
332                         break;
333                 default:
334                 case '?':
335                         usage();
336                 }
337         }
338
339         oldVars = TRUE;
340
341         /*
342          * See if the rest of the arguments are variable assignments and
343          * perform them if so. Else take them to be targets and stuff them
344          * on the end of the "create" list.
345          */
346         for (argv += optind, argc -= optind; *argv; ++argv, --argc)
347                 if (Parse_IsVar(*argv)) {
348                         char *ptr = MAKEFLAGS_quote(*argv);
349
350                         Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL);
351                         free(ptr);
352
353                         Parse_DoVar(*argv, VAR_CMD);
354                 } else {
355                         if (!**argv)
356                                 Punt("illegal (null) argument.");
357                         if (**argv == '-') {
358                                 if ((*argv)[1])
359                                         optind = 0;     /* -flag... */
360                                 else
361                                         optind = 1;     /* - */
362                                 goto rearg;
363                         }
364                         Lst_AtEnd(&create, estrdup(*argv));
365                 }
366 }
367
368 /*-
369  * Main_ParseArgLine --
370  *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target
371  *      is encountered and by main() when reading the .MAKEFLAGS envariable.
372  *      Takes a line of arguments and breaks it into its
373  *      component words and passes those words and the number of them to the
374  *      MainParseArgs function.
375  *      The line should have all its leading whitespace removed.
376  *
377  * Results:
378  *      None
379  *
380  * Side Effects:
381  *      Only those that come from the various arguments.
382  */
383 void
384 Main_ParseArgLine(char *line, int mflags)
385 {
386         char **argv;                    /* Manufactured argument vector */
387         int argc;                       /* Number of arguments in argv */
388
389         if (line == NULL)
390                 return;
391         for (; *line == ' '; ++line)
392                 continue;
393         if (!*line)
394                 return;
395
396         if (mflags)
397                 argv = MAKEFLAGS_break(line, &argc);
398         else
399                 argv = brk_string(line, &argc, TRUE);
400
401         MainParseArgs(argc, argv);
402 }
403
404 char *
405 chdir_verify_path(const char *path, char *obpath)
406 {
407         struct stat sb;
408
409         if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
410                 if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
411                         warn("warning: %s", path);
412                         return (NULL);
413                 }
414                 return (obpath);
415         }
416
417         return (NULL);
418 }
419
420 static void
421 catch_child(int sig __unused)
422 {
423 }
424
425 /*
426  * In lieu of a good way to prevent every possible looping in
427  * make(1), stop there from being more than MKLVL_MAXVAL processes forked
428  * by make(1), to prevent a forkbomb from happening, in a dumb and
429  * mechanical way.
430  */
431 static void
432 check_make_level(void)
433 {
434 #ifdef WANT_ENV_MKLVL
435         char    *value = getenv(MKLVL_ENVVAR);
436         int     level = (value == NULL) ? 0 : atoi(value);
437
438         if (level < 0) {
439                 errc(2, EAGAIN, "Invalid value for recursion level (%d).", level);
440         } else if (level > MKLVL_MAXVAL) {
441                 errc(2, EAGAIN, "Max recursion level (%d) exceeded.", MKLVL_MAXVAL);
442         } else {
443                 char new_value[32];
444                 sprintf(new_value, "%d", level + 1);
445                 setenv(MKLVL_ENVVAR, new_value, 1);
446         }
447 #endif /* WANT_ENV_MKLVL */
448 }
449
450 /*-
451  * main --
452  *      The main function, for obvious reasons. Initializes variables
453  *      and a few modules, then parses the arguments give it in the
454  *      environment and on the command line. Reads the system makefile
455  *      followed by either Makefile, makefile or the file given by the
456  *      -f argument. Sets the .MAKEFLAGS PMake variable based on all the
457  *      flags it has received by then uses either the Make or the Compat
458  *      module to create the initial list of targets.
459  *
460  * Results:
461  *      If -q was given, exits -1 if anything was out-of-date. Else it exits
462  *      0.
463  *
464  * Side Effects:
465  *      The program exits when done. Targets are created. etc. etc. etc.
466  */
467 int
468 main(int argc, char **argv)
469 {
470         Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
471         char *p, *p1;
472         const char *pathp;
473         const char *path;
474         char mdpath[MAXPATHLEN];
475         char obpath[MAXPATHLEN];
476         char cdpath[MAXPATHLEN];
477         const char *machine = getenv("MACHINE");
478         const char *machine_arch = getenv("MACHINE_ARCH");
479         const char *machine_cpu = getenv("MACHINE_CPU");
480         char *cp = NULL, *start;
481
482                                         /* avoid faults on read-only strings */
483         static char syspath[] = PATH_DEFSYSPATH;
484
485         {
486         /*
487          * Catch SIGCHLD so that we get kicked out of select() when we
488          * need to look at a child.  This is only known to matter for the
489          * -j case (perhaps without -P).
490          *
491          * XXX this is intentionally misplaced.
492          */
493         struct sigaction sa;
494
495         sigemptyset(&sa.sa_mask);
496         sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
497         sa.sa_handler = catch_child;
498         sigaction(SIGCHLD, &sa, NULL);
499         }
500
501         check_make_level();
502
503 #if DEFSHELL == 2
504         /*
505          * Turn off ENV to make ksh happier.
506          */
507         unsetenv("ENV");
508 #endif
509
510 #ifdef RLIMIT_NOFILE
511         /*
512          * get rid of resource limit on file descriptors
513          */
514         {
515                 struct rlimit rl;
516                 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
517                     rl.rlim_cur != rl.rlim_max) {
518                         rl.rlim_cur = rl.rlim_max;
519                         setrlimit(RLIMIT_NOFILE, &rl);
520                 }
521         }
522 #endif
523         /*
524          * Get the name of this type of MACHINE from utsname
525          * so we can share an executable for similar machines.
526          * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
527          *
528          * Note that while MACHINE is decided at run-time,
529          * MACHINE_ARCH is always known at compile time.
530          */
531         if (!machine) {
532 #ifndef MACHINE
533             static struct utsname utsname;
534
535             if (uname(&utsname) == -1)
536                     err(2, "uname");
537             machine = utsname.machine;
538 #else
539             machine = MACHINE;
540 #endif
541         }
542
543         if (!machine_arch) {
544 #ifndef MACHINE_ARCH
545                 machine_arch = "unknown";
546 #else
547                 machine_arch = MACHINE_ARCH;
548 #endif
549         }
550
551         /*
552          * Set machine_cpu to the minumum supported CPU revision based
553          * on the target architecture, if not already set.
554          */
555         if (!machine_cpu) {
556                 if (!strcmp(machine_arch, "i386"))
557                         machine_cpu = "i386";
558                 else if (!strcmp(machine_arch, "alpha"))
559                         machine_cpu = "ev4";
560                 else
561                         machine_cpu = "unknown";
562         }
563
564         expandVars = TRUE;
565         beSilent = FALSE;               /* Print commands as executed */
566         ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
567         noExecute = FALSE;              /* Execute all commands */
568         keepgoing = FALSE;              /* Stop on error */
569         allPrecious = FALSE;            /* Remove targets when interrupted */
570         queryFlag = FALSE;              /* This is not just a check-run */
571         noBuiltins = FALSE;             /* Read the built-in rules */
572         touchFlag = FALSE;              /* Actually update targets */
573         usePipes = TRUE;                /* Catch child output in pipes */
574         debug = 0;                      /* No debug verbosity, please. */
575         jobsRunning = FALSE;
576
577         maxJobs = DEFMAXJOBS;
578         forceJobs = FALSE;              /* No -j flag */
579         compatMake = FALSE;             /* No compat mode */
580
581         /*
582          * Initialize the parsing, directory and variable modules to prepare
583          * for the reading of inclusion paths and variable settings on the
584          * command line
585          */
586         Dir_Init();             /* Initialize directory structures so -I flags
587                                  * can be processed correctly */
588         Parse_Init();           /* Need to initialize the paths of #include
589                                  * directories */
590         Var_Init();             /* As well as the lists of variables for
591                                  * parsing arguments */
592         str_init();
593
594         /*
595          * Initialize various variables.
596          *      MAKE also gets this name, for compatibility
597          *      .MAKEFLAGS gets set to the empty string just in case.
598          *      MFLAGS also gets initialized empty, for compatibility.
599          */
600         Var_Set("MAKE", argv[0], VAR_GLOBAL);
601         Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
602         Var_Set("MFLAGS", "", VAR_GLOBAL);
603         Var_Set("MACHINE", machine, VAR_GLOBAL);
604         Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
605         Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
606 #ifdef MAKE_VERSION
607         Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
608 #endif
609
610         /*
611          * First snag any flags out of the MAKE environment variable.
612          * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
613          * in a different format).
614          */
615         Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
616
617         MainParseArgs(argc, argv);
618
619         /*
620          * Find where we are...
621          * All this code is so that we know where we are when we start up
622          * on a different machine with pmake.
623          */
624         curdir = cdpath;
625         if (getcwd(curdir, MAXPATHLEN) == NULL)
626                 err(2, NULL);
627
628         {
629         struct stat sa;
630
631         if (stat(curdir, &sa) == -1)
632             err(2, "%s", curdir);
633         }
634
635         /*
636          * The object directory location is determined using the
637          * following order of preference:
638          *
639          *      1. MAKEOBJDIRPREFIX`cwd`
640          *      2. MAKEOBJDIR
641          *      3. PATH_OBJDIR.${MACHINE}
642          *      4. PATH_OBJDIR
643          *      5. PATH_OBJDIRPREFIX`cwd`
644          *
645          * If one of the first two fails, use the current directory.
646          * If the remaining three all fail, use the current directory.
647          *
648          * Once things are initted,
649          * have to add the original directory to the search path,
650          * and modify the paths for the Makefiles apropriately.  The
651          * current directory is also placed as a variable for make scripts.
652          */
653         if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
654                 if (!(path = getenv("MAKEOBJDIR"))) {
655                         path = PATH_OBJDIR;
656                         pathp = PATH_OBJDIRPREFIX;
657                         snprintf(mdpath, MAXPATHLEN, "%s.%s",
658                                         path, machine);
659                         if (!(objdir = chdir_verify_path(mdpath, obpath)))
660                                 if (!(objdir=chdir_verify_path(path, obpath))) {
661                                         snprintf(mdpath, MAXPATHLEN,
662                                                         "%s%s", pathp, curdir);
663                                         if (!(objdir=chdir_verify_path(mdpath,
664                                                                        obpath)))
665                                                 objdir = curdir;
666                                 }
667                 }
668                 else if (!(objdir = chdir_verify_path(path, obpath)))
669                         objdir = curdir;
670         }
671         else {
672                 snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
673                 if (!(objdir = chdir_verify_path(mdpath, obpath)))
674                         objdir = curdir;
675         }
676         Dir_InitDot();          /* Initialize the "." directory */
677         if (objdir != curdir)
678                 Dir_AddDir(&dirSearchPath, curdir);
679         Var_Set(".DIRECTIVE_MAKEENV", "YES", VAR_GLOBAL);
680         Var_Set(".CURDIR", curdir, VAR_GLOBAL);
681         Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
682
683         if (getenv("MAKE_JOBS_FIFO") != NULL)
684                 forceJobs = TRUE;
685         /*
686          * Be compatible if user did not specify -j and did not explicitly
687          * turned compatibility on
688          */
689         if (!compatMake && !forceJobs)
690                 compatMake = TRUE;
691
692         /*
693          * Initialize archive, target and suffix modules in preparation for
694          * parsing the makefile(s)
695          */
696         Arch_Init();
697         Targ_Init();
698         Suff_Init();
699
700         DEFAULT = NULL;
701         time(&now);
702
703         /*
704          * Set up the .TARGETS variable to contain the list of targets to be
705          * created. If none specified, make the variable empty -- the parser
706          * will fill the thing in with the default or .MAIN target.
707          */
708         if (!Lst_IsEmpty(&create)) {
709                 LstNode *ln;
710
711                 for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
712                         char *name = Lst_Datum(ln);
713
714                         Var_Append(".TARGETS", name, VAR_GLOBAL);
715                 }
716         } else
717                 Var_Set(".TARGETS", "", VAR_GLOBAL);
718
719
720         /*
721          * If no user-supplied system path was given (through the -m option)
722          * add the directories from the DEFSYSPATH (more than one may be given
723          * as dir1:...:dirn) to the system include path.
724          */
725         if (Lst_IsEmpty(&sysIncPath)) {
726                 for (start = syspath; *start != '\0'; start = cp) {
727                         for (cp = start; *cp != '\0' && *cp != ':'; cp++)
728                                 continue;
729                         if (*cp == '\0') {
730                                 Dir_AddDir(&sysIncPath, start);
731                         } else {
732                                 *cp++ = '\0';
733                                 Dir_AddDir(&sysIncPath, start);
734                         }
735                 }
736         }
737
738         /*
739          * Read in the built-in rules first, followed by the specified
740          * makefile, if it was (makefile != (char *) NULL), or the default
741          * Makefile and makefile, in that order, if it wasn't.
742          */
743         if (!noBuiltins) {
744                 /* Path of sys.mk */
745                 Lst sysMkPath = Lst_Initializer(sysMkPath);
746                 LstNode *ln;
747
748                 Dir_Expand(PATH_DEFSYSMK, &sysIncPath, &sysMkPath);
749                 if (Lst_IsEmpty(&sysMkPath))
750                         Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
751                 LST_FOREACH(ln, &sysMkPath) {
752                         if (!ReadMakefile(Lst_Datum(ln)))
753                                 break;
754                 }
755                 if (ln != NULL)
756                         Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
757                 Lst_Destroy(&sysMkPath, free);
758         }
759
760         if (!Lst_IsEmpty(&makefiles)) {
761                 LstNode *ln;
762
763                 LST_FOREACH(ln, &makefiles) {
764                         if (!ReadMakefile(Lst_Datum(ln)))
765                                 break;
766                 }
767                 if (ln != NULL)
768                         Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
769         } else if (!ReadMakefile("BSDmakefile"))
770             if (!ReadMakefile("makefile"))
771                 ReadMakefile("Makefile");
772
773         ReadMakefile(".depend");
774
775         /* Install all the flags into the MAKE envariable. */
776         if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
777                 setenv("MAKEFLAGS", p, 1);
778         free(p1);
779
780         /*
781          * For compatibility, look at the directories in the VPATH variable
782          * and add them to the search path, if the variable is defined. The
783          * variable's value is in the same format as the PATH envariable, i.e.
784          * <directory>:<directory>:<directory>...
785          */
786         if (Var_Exists("VPATH", VAR_CMD)) {
787                 /*
788                  * GCC stores string constants in read-only memory, but
789                  * Var_Subst will want to write this thing, so store it
790                  * in an array
791                  */
792                 static char VPATH[] = "${VPATH}";
793                 Buffer  *buf;
794                 char    *vpath;
795                 char    *ptr;
796                 char    savec;
797
798                 buf = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
799
800                 vpath = Buf_Data(buf);
801                 do {
802                         /* skip to end of directory */
803                         for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
804                                 ;
805
806                         /* Save terminator character so know when to stop */
807                         savec = *ptr;
808                         *ptr = '\0';
809
810                         /* Add directory to search path */
811                         Dir_AddDir(&dirSearchPath, vpath);
812
813                         vpath = ptr + 1;
814                 } while (savec != '\0');
815
816                 Buf_Destroy(buf, TRUE);
817         }
818
819         /*
820          * Now that all search paths have been read for suffixes et al, it's
821          * time to add the default search path to their lists...
822          */
823         Suff_DoPaths();
824
825         /* print the initial graph, if the user requested it */
826         if (DEBUG(GRAPH1))
827                 Targ_PrintGraph(1);
828
829         /* print the values of any variables requested by the user */
830         if (Lst_IsEmpty(&variables)) {
831                 /*
832                  * Since the user has not requested that any variables
833                  * be printed, we can build targets.
834                  *
835                  * Have read the entire graph and need to make a list of targets
836                  * to create. If none was given on the command line, we consult
837                  * the parsing module to find the main target(s) to create.
838                  */
839                 Lst targs = Lst_Initializer(targs);
840
841                 if (Lst_IsEmpty(&create))
842                         Parse_MainName(&targs);
843                 else
844                         Targ_FindList(&targs, &create, TARG_CREATE);
845
846                 if (compatMake) {
847                         /*
848                          * Compat_Init will take care of creating
849                          * all the targets as well as initializing
850                          * the module.
851                          */
852                         Compat_Run(&targs);
853                         outOfDate = 0;
854                 } else {
855                         /*
856                          * Initialize job module before traversing
857                          * the graph, now that any .BEGIN and .END
858                          * targets have been read.  This is done
859                          * only if the -q flag wasn't given (to
860                          * prevent the .BEGIN from being executed
861                          * should it exist).
862                          */
863                         if (!queryFlag) {
864                                 Job_Init(maxJobs);
865                                 jobsRunning = TRUE;
866                         }
867
868                         /* Traverse the graph, checking on all the targets */
869                         outOfDate = Make_Run(&targs);
870                 }
871                 Lst_Destroy(&targs, NOFREE);
872
873         } else {
874                 /*
875                  * Print the values of any variables requested by
876                  * the user.
877                  */
878                 LstNode *n;
879
880                 LST_FOREACH(n, &variables) {
881                         const char      *name = Lst_Datum(n);
882                         if (expandVars) {
883                                 char            *v;
884                                 char            *value;
885
886                                 v = emalloc(strlen(name) + 1 + 3);
887                                 sprintf(v, "${%s}", name);
888
889                                 value = Buf_Peel(Var_Subst(NULL, v,
890                                     VAR_GLOBAL, FALSE));
891                                 printf("%s\n", value);
892
893                                 free(v);
894                                 free(value);
895                         } else {
896                                 char    *value;
897                                 char    *v;
898                                 value = Var_Value(name, VAR_GLOBAL, &v);
899                                 printf("%s\n", value != NULL ? value : "");
900                                 if (v != NULL)
901                                         free(v);
902                         }
903                 }
904         }
905
906         Lst_Destroy(&variables, free);
907         Lst_Destroy(&makefiles, free);
908         Lst_Destroy(&create, free);
909
910         /* print the graph now it's been processed if the user requested it */
911         if (DEBUG(GRAPH2))
912                 Targ_PrintGraph(2);
913
914         if (queryFlag && outOfDate)
915                 return (1);
916         else
917                 return (0);
918 }
919
920 /*-
921  * ReadMakefile  --
922  *      Open and parse the given makefile.
923  *
924  * Results:
925  *      TRUE if ok. FALSE if couldn't open file.
926  *
927  * Side Effects:
928  *      lots
929  */
930 static Boolean
931 ReadMakefile(const char *p)
932 {
933         char *fname;                    /* makefile to read */
934         FILE *stream;
935         char *name, path[MAXPATHLEN];
936         char *MAKEFILE;
937         int setMAKEFILE;
938
939         /* XXX - remove this once constification is done */
940         fname = estrdup(p);
941
942         if (!strcmp(fname, "-")) {
943                 Parse_File("(stdin)", stdin);
944                 Var_Set("MAKEFILE", "", VAR_GLOBAL);
945         } else {
946                 setMAKEFILE = strcmp(fname, ".depend");
947
948                 /* if we've chdir'd, rebuild the path name */
949                 if (curdir != objdir && *fname != '/') {
950                         snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
951                         /*
952                          * XXX The realpath stuff breaks relative includes
953                          * XXX in some cases.   The problem likely is in
954                          * XXX parse.c where it does special things in
955                          * XXX ParseDoInclude if the file is relateive
956                          * XXX or absolute and not a system file.  There
957                          * XXX it assumes that if the current file that's
958                          * XXX being included is absolute, that any files
959                          * XXX that it includes shouldn't do the -I path
960                          * XXX stuff, which is inconsistant with historical
961                          * XXX behavior.  However, I can't pentrate the mists
962                          * XXX further, so I'm putting this workaround in
963                          * XXX here until such time as the underlying bug
964                          * XXX can be fixed.
965                          */
966 #if THIS_BREAKS_THINGS
967                         if (realpath(path, path) != NULL &&
968                             (stream = fopen(path, "r")) != NULL) {
969                                 MAKEFILE = fname;
970                                 fname = path;
971                                 goto found;
972                         }
973                 } else if (realpath(fname, path) != NULL) {
974                         MAKEFILE = fname;
975                         fname = path;
976                         if ((stream = fopen(fname, "r")) != NULL)
977                                 goto found;
978                 }
979 #else
980                         if ((stream = fopen(path, "r")) != NULL) {
981                                 MAKEFILE = fname;
982                                 fname = path;
983                                 goto found;
984                         }
985                 } else {
986                         MAKEFILE = fname;
987                         if ((stream = fopen(fname, "r")) != NULL)
988                                 goto found;
989                 }
990 #endif
991                 /* look in -I and system include directories. */
992                 name = Dir_FindFile(fname, &parseIncPath);
993                 if (!name)
994                         name = Dir_FindFile(fname, &sysIncPath);
995                 if (!name || !(stream = fopen(name, "r")))
996                         return (FALSE);
997                 MAKEFILE = fname = name;
998                 /*
999                  * set the MAKEFILE variable desired by System V fans -- the
1000                  * placement of the setting here means it gets set to the last
1001                  * makefile specified, as it is set by SysV make.
1002                  */
1003 found:
1004                 if (setMAKEFILE)
1005                         Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL);
1006                 Parse_File(fname, stream);
1007                 fclose(stream);
1008         }
1009         return (TRUE);
1010 }
1011
1012 /*-
1013  * Cmd_Exec --
1014  *      Execute the command in cmd, and return the output of that command
1015  *      in a string.
1016  *
1017  * Results:
1018  *      A string containing the output of the command, or the empty string
1019  *      If error is not NULL, it contains the reason for the command failure
1020  *
1021  * Side Effects:
1022  *      The string must be freed by the caller.
1023  */
1024 Buffer *
1025 Cmd_Exec(const char *cmd, const char **error)
1026 {
1027     int         fds[2];         /* Pipe streams */
1028     int         cpid;           /* Child PID */
1029     int         pid;            /* PID from wait() */
1030     int         status;         /* command exit status */
1031     Buffer      *buf;           /* buffer to store the result */
1032     ssize_t     rcnt;
1033
1034     *error = NULL;
1035     buf = Buf_Init(0);
1036
1037     if (shellPath == NULL)
1038         Shell_Init();
1039     /*
1040      * Open a pipe for fetching its output
1041      */
1042     if (pipe(fds) == -1) {
1043         *error = "Couldn't create pipe for \"%s\"";
1044         return (buf);
1045     }
1046
1047     /*
1048      * Fork
1049      */
1050     switch (cpid = vfork()) {
1051     case 0:
1052         /*
1053          * Close input side of pipe
1054          */
1055         close(fds[0]);
1056
1057         /*
1058          * Duplicate the output stream to the shell's output, then
1059          * shut the extra thing down. Note we don't fetch the error
1060          * stream...why not? Why?
1061          */
1062         dup2(fds[1], 1);
1063         close(fds[1]);
1064
1065         {
1066             char        *args[4];
1067
1068             /* Set up arguments for shell */
1069             args[0] = shellName;
1070             args[1] = "-c";
1071             args[2] = cmd;
1072             args[3] = NULL;
1073
1074             execv(shellPath, args);
1075             _exit(1);
1076             /*NOTREACHED*/
1077         }
1078
1079     case -1:
1080         *error = "Couldn't exec \"%s\"";
1081         return (buf);
1082
1083     default:
1084         /*
1085          * No need for the writing half
1086          */
1087         close(fds[1]);
1088
1089         do {
1090             char   result[BUFSIZ];
1091             rcnt = read(fds[0], result, sizeof(result));
1092             if (rcnt != -1)
1093                 Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result);
1094         } while (rcnt > 0 || (rcnt == -1 && errno == EINTR));
1095
1096         if (rcnt == -1)
1097             *error = "Error reading shell's output for \"%s\"";
1098
1099         /*
1100          * Close the input side of the pipe.
1101          */
1102         close(fds[0]);
1103
1104         /*
1105          * Wait for the process to exit.
1106          */
1107         while (((pid = wait(&status)) != cpid) && (pid >= 0))
1108             continue;
1109
1110         if (status)
1111             *error = "\"%s\" returned non-zero status";
1112
1113         Buf_StripNewlines(buf);
1114
1115         break;
1116     }
1117     return (buf);
1118 }
1119
1120 /*
1121  * usage --
1122  *      exit with usage message
1123  */
1124 static void
1125 usage(void)
1126 {
1127         fprintf(stderr, "%s\n%s\n%s\n",
1128 "usage: make [-BPSXeiknqrstv] [-C directory] [-D variable] [-d flags]",
1129 "            [-E variable] [-f makefile] [-I directory] [-j max_jobs]",
1130 "            [-m directory] [-V variable] [variable=value] [target ...]");
1131         exit(2);
1132 }