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