Change .EXPORT: to .EXPORTVAR: earlier versions of pmake used
[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.78 2005/04/22 10:38:30 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 "nonints.h"
81 #include "parse.h"
82 #include "pathnames.h"
83 #include "str.h"
84 #include "suff.h"
85 #include "targ.h"
86 #include "util.h"
87 #include "var.h"
88
89 #define WANT_ENV_MKLVL  1
90 #define MKLVL_MAXVAL    500
91 #define MKLVL_ENVVAR    "__MKLVL__"
92
93 #define MAKEFLAGS       ".MAKEFLAGS"
94
95 extern char **environ;  /* XXX what header declares this variable? */
96
97 /* Targets to be made */
98 Lst create = Lst_Initializer(create);
99
100 time_t          now;            /* Time at start of make */
101 struct GNode    *DEFAULT;       /* .DEFAULT node */
102 Boolean         allPrecious;    /* .PRECIOUS given on line by itself */
103
104 static Boolean  noBuiltins;     /* -r flag */
105
106 /* ordered list of makefiles to read */
107 static Lst makefiles = Lst_Initializer(makefiles);
108
109 static Boolean  expandVars;     /* fully expand printed variables */
110
111 /* list of variables to print */
112 static Lst variables = Lst_Initializer(variables);
113
114 int             maxJobs;        /* -j argument */
115 static Boolean  forceJobs;      /* -j argument given */
116 Boolean         compatMake;     /* -B argument */
117 Boolean         debug;          /* -d flag */
118 Boolean         noExecute;      /* -n flag */
119 Boolean         keepgoing;      /* -k flag */
120 Boolean         queryFlag;      /* -q flag */
121 Boolean         touchFlag;      /* -t flag */
122 Boolean         usePipes;       /* !-P flag */
123 Boolean         ignoreErrors;   /* -i flag */
124 Boolean         beSilent;       /* -s flag */
125 Boolean         beVerbose;      /* -v flag */
126 Boolean         oldVars;        /* variable substitution style */
127 Boolean         checkEnvFirst;  /* -e flag */
128
129 /* (-E) vars to override from env */
130 Lst envFirstVars = Lst_Initializer(envFirstVars);
131
132 Boolean         jobsRunning;    /* TRUE if the jobs might be running */
133
134 char            *chdir_verify_path(const char *, char *);
135 static int      ReadMakefile(const char *);
136 static void     usage(void);
137
138 static char     *curdir;        /* startup directory */
139 static char     *objdir;        /* where we chdir'ed to */
140
141 /**
142  * MFLAGS_append
143  *      Append a flag with an optional argument to MAKEFLAGS and MFLAGS
144  */
145 static void
146 MFLAGS_append(const char *flag, char *arg)
147 {
148         char *str;
149
150         Var_Append(MAKEFLAGS, flag, VAR_GLOBAL);
151         if (arg != NULL) {
152                 str = MAKEFLAGS_quote(arg);
153                 Var_Append(MAKEFLAGS, str, VAR_GLOBAL);
154                 free(str);
155         }
156
157         Var_Append("MFLAGS", flag, VAR_GLOBAL);
158         if (arg != NULL) {
159                 str = MAKEFLAGS_quote(arg);
160                 Var_Append("MFLAGS", str, VAR_GLOBAL);
161                 free(str);
162         }
163 }
164
165 /**
166  * MainParseArgs
167  *      Parse a given argument vector. Called from main() and from
168  *      Main_ParseArgLine() when the .MAKEFLAGS target is used.
169  *
170  *      XXX: Deal with command line overriding .MAKEFLAGS in makefile
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         Boolean found_dd = FALSE;
181
182 rearg:
183         optind = 1;     /* since we're called more than once */
184         optreset = 1;
185 #define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstv"
186         for (;;) {
187                 if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
188                         found_dd = TRUE;
189                 }
190                 if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
191                         break;
192                 }
193                 switch(c) {
194
195                 case 'A':
196                         arch_fatal = FALSE;
197                         MFLAGS_append("-A", NULL);
198                         break;
199                 case 'C':
200                         if (chdir(optarg) == -1)
201                                 err(1, "chdir %s", optarg);
202                         break;
203                 case 'D':
204                         Var_Set(optarg, "1", VAR_GLOBAL);
205                         MFLAGS_append("-D", optarg);
206                         break;
207                 case 'I':
208                         Parse_AddIncludeDir(optarg);
209                         MFLAGS_append("-I", optarg);
210                         break;
211                 case 'V':
212                         Lst_AtEnd(&variables, estrdup(optarg));
213                         MFLAGS_append("-V", optarg);
214                         break;
215                 case 'X':
216                         expandVars = FALSE;
217                         break;
218                 case 'B':
219                         compatMake = TRUE;
220                         MFLAGS_append("-B", NULL);
221                         unsetenv("MAKE_JOBS_FIFO");
222                         break;
223                 case 'P':
224                         usePipes = FALSE;
225                         MFLAGS_append("-P", NULL);
226                         break;
227                 case 'S':
228                         keepgoing = FALSE;
229                         MFLAGS_append("-S", NULL);
230                         break;
231                 case 'd': {
232                         char *modules = optarg;
233
234                         for (; *modules; ++modules)
235                                 switch (*modules) {
236                                 case 'A':
237                                         debug = ~0;
238                                         break;
239                                 case 'a':
240                                         debug |= DEBUG_ARCH;
241                                         break;
242                                 case 'c':
243                                         debug |= DEBUG_COND;
244                                         break;
245                                 case 'd':
246                                         debug |= DEBUG_DIR;
247                                         break;
248                                 case 'f':
249                                         debug |= DEBUG_FOR;
250                                         break;
251                                 case 'g':
252                                         if (modules[1] == '1') {
253                                                 debug |= DEBUG_GRAPH1;
254                                                 ++modules;
255                                         }
256                                         else if (modules[1] == '2') {
257                                                 debug |= DEBUG_GRAPH2;
258                                                 ++modules;
259                                         }
260                                         break;
261                                 case 'j':
262                                         debug |= DEBUG_JOB;
263                                         break;
264                                 case 'l':
265                                         debug |= DEBUG_LOUD;
266                                         break;
267                                 case 'm':
268                                         debug |= DEBUG_MAKE;
269                                         break;
270                                 case 's':
271                                         debug |= DEBUG_SUFF;
272                                         break;
273                                 case 't':
274                                         debug |= DEBUG_TARG;
275                                         break;
276                                 case 'v':
277                                         debug |= DEBUG_VAR;
278                                         break;
279                                 default:
280                                         warnx("illegal argument to d option "
281                                             "-- %c", *modules);
282                                         usage();
283                                 }
284                         MFLAGS_append("-d", optarg);
285                         break;
286                 }
287                 case 'E':
288                         Lst_AtEnd(&envFirstVars, estrdup(optarg));
289                         MFLAGS_append("-E", optarg);
290                         break;
291                 case 'e':
292                         checkEnvFirst = TRUE;
293                         MFLAGS_append("-e", NULL);
294                         break;
295                 case 'f':
296                         Lst_AtEnd(&makefiles, estrdup(optarg));
297                         break;
298                 case 'i':
299                         ignoreErrors = TRUE;
300                         MFLAGS_append("-i", NULL);
301                         break;
302                 case 'j': {
303                         char *endptr;
304
305                         forceJobs = TRUE;
306                         maxJobs = strtol(optarg, &endptr, 10);
307                         if (maxJobs <= 0 || *endptr != '\0') {
308                                 warnx("illegal number, -j argument -- %s",
309                                     optarg);
310                                 usage();
311                         }
312                         MFLAGS_append("-j", optarg);
313                         break;
314                 }
315                 case 'k':
316                         keepgoing = TRUE;
317                         MFLAGS_append("-k", NULL);
318                         break;
319                 case 'm':
320                         Path_AddDir(&sysIncPath, optarg);
321                         MFLAGS_append("-m", optarg);
322                         break;
323                 case 'n':
324                         noExecute = TRUE;
325                         MFLAGS_append("-n", NULL);
326                         break;
327                 case 'q':
328                         queryFlag = TRUE;
329                         /* Kind of nonsensical, wot? */
330                         MFLAGS_append("-q", NULL);
331                         break;
332                 case 'r':
333                         noBuiltins = TRUE;
334                         MFLAGS_append("-r", NULL);
335                         break;
336                 case 's':
337                         beSilent = TRUE;
338                         MFLAGS_append("-s", NULL);
339                         break;
340                 case 't':
341                         touchFlag = TRUE;
342                         MFLAGS_append("-t", NULL);
343                         break;
344                 case 'v':
345                         beVerbose = TRUE;
346                         MFLAGS_append("-v", NULL);
347                         break;
348                 default:
349                 case '?':
350                         usage();
351                 }
352         }
353         argv += optind;
354         argc -= optind;
355
356         oldVars = TRUE;
357
358         /*
359          * Parse the rest of the arguments.
360          *      o Check for variable assignments and perform them if so.
361          *      o Check for more flags and restart getopt if so.
362          *      o Anything else is taken to be a target and added
363          *        to the end of the "create" list.
364          */
365         for (; *argv != NULL; ++argv, --argc) {
366                 if (Parse_IsVar(*argv)) {
367                         char *ptr = MAKEFLAGS_quote(*argv);
368
369                         Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL);
370                         Parse_DoVar(*argv, VAR_CMD);
371                         free(ptr);
372
373                 } else if ((*argv)[0] == '-') {
374                         if ((*argv)[1] == '\0') {
375                                 /*
376                                  * (*argv) is a single dash, so we
377                                  * just ignore it.
378                                  */
379                         } else if (found_dd) {
380                                 /*
381                                  * Double dash has been found, ignore
382                                  * any more options.  But what do we do
383                                  * with it?  For now treat it like a target.
384                                  */
385                                 Lst_AtEnd(&create, estrdup(*argv));
386                         } else {
387                                 /*
388                                  * (*argv) is a -flag, so backup argv and
389                                  * argc.  getopt() expects options to start
390                                  * in the 2nd position.
391                                  */
392                                 argc++;
393                                 argv--;
394                                 goto rearg;
395                         }
396
397                 } else if ((*argv)[0] == '\0') {
398                         Punt("illegal (null) argument.");
399
400                 } else {
401                         Lst_AtEnd(&create, estrdup(*argv));
402                 }
403         }
404 }
405
406 /**
407  * Main_ParseArgLine
408  *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target
409  *      is encountered and by main() when reading the .MAKEFLAGS envariable.
410  *      Takes a line of arguments and breaks it into its
411  *      component words and passes those words and the number of them to the
412  *      MainParseArgs function.
413  *      The line should have all its leading whitespace removed.
414  *
415  * Side Effects:
416  *      Only those that come from the various arguments.
417  */
418 void
419 Main_ParseArgLine(char *line, int mflags)
420 {
421         char **argv;                    /* Manufactured argument vector */
422         int argc;                       /* Number of arguments in argv */
423
424         if (line == NULL)
425                 return;
426         for (; *line == ' '; ++line)
427                 continue;
428         if (!*line)
429                 return;
430
431         if (mflags)
432                 argv = MAKEFLAGS_break(line, &argc);
433         else
434                 argv = brk_string(line, &argc, TRUE);
435
436         MainParseArgs(argc, argv);
437 }
438
439 char *
440 chdir_verify_path(const char *path, char *obpath)
441 {
442         struct stat sb;
443
444         if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
445                 if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
446                         warn("warning: %s", path);
447                         return (NULL);
448                 }
449                 return (obpath);
450         }
451
452         return (NULL);
453 }
454
455 static void
456 catch_child(int sig __unused)
457 {
458 }
459
460 /*
461  * In lieu of a good way to prevent every possible looping in
462  * make(1), stop there from being more than MKLVL_MAXVAL processes forked
463  * by make(1), to prevent a forkbomb from happening, in a dumb and
464  * mechanical way.
465  */
466 static void
467 check_make_level(void)
468 {
469 #ifdef WANT_ENV_MKLVL
470         char    *value = getenv(MKLVL_ENVVAR);
471         int     level = (value == NULL) ? 0 : atoi(value);
472
473         if (level < 0) {
474                 errc(2, EAGAIN, "Invalid value for recursion level (%d).",
475                     level);
476         } else if (level > MKLVL_MAXVAL) {
477                 errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
478                     MKLVL_MAXVAL);
479         } else {
480                 char new_value[32];
481                 sprintf(new_value, "%d", level + 1);
482                 setenv(MKLVL_ENVVAR, new_value, 1);
483         }
484 #endif /* WANT_ENV_MKLVL */
485 }
486
487 /**
488  * main
489  *      The main function, for obvious reasons. Initializes variables
490  *      and a few modules, then parses the arguments give it in the
491  *      environment and on the command line. Reads the system makefile
492  *      followed by either Makefile, makefile or the file given by the
493  *      -f argument. Sets the .MAKEFLAGS PMake variable based on all the
494  *      flags it has received by then uses either the Make or the Compat
495  *      module to create the initial list of targets.
496  *
497  * Results:
498  *      If -q was given, exits -1 if anything was out-of-date. Else it exits
499  *      0.
500  *
501  * Side Effects:
502  *      The program exits when done. Targets are created. etc. etc. etc.
503  */
504 int
505 main(int argc, char **argv)
506 {
507         Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
508         char *p, *p1;
509         const char *pathp;
510         const char *path;
511         char mdpath[MAXPATHLEN];
512         char obpath[MAXPATHLEN];
513         char cdpath[MAXPATHLEN];
514         const char *machine = getenv("MACHINE");
515         const char *machine_arch = getenv("MACHINE_ARCH");
516         const char *machine_cpu = getenv("MACHINE_CPU");
517         char *cp = NULL, *start;
518
519         /* avoid faults on read-only strings */
520         static char syspath[] = PATH_DEFSYSPATH;
521
522         {
523         /*
524          * Catch SIGCHLD so that we get kicked out of select() when we
525          * need to look at a child.  This is only known to matter for the
526          * -j case (perhaps without -P).
527          *
528          * XXX this is intentionally misplaced.
529          */
530         struct sigaction sa;
531
532         sigemptyset(&sa.sa_mask);
533         sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
534         sa.sa_handler = catch_child;
535         sigaction(SIGCHLD, &sa, NULL);
536         }
537
538         check_make_level();
539
540 #if DEFSHELL == 2
541         /*
542          * Turn off ENV to make ksh happier.
543          */
544         unsetenv("ENV");
545 #endif
546
547 #ifdef RLIMIT_NOFILE
548         /*
549          * get rid of resource limit on file descriptors
550          */
551         {
552                 struct rlimit rl;
553                 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
554                     rl.rlim_cur != rl.rlim_max) {
555                         rl.rlim_cur = rl.rlim_max;
556                         setrlimit(RLIMIT_NOFILE, &rl);
557                 }
558         }
559 #endif
560         /*
561          * Get the name of this type of MACHINE from utsname
562          * so we can share an executable for similar machines.
563          * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
564          *
565          * Note that while MACHINE is decided at run-time,
566          * MACHINE_ARCH is always known at compile time.
567          */
568         if (!machine) {
569 #ifndef MACHINE
570                 static struct utsname utsname;
571
572                 if (uname(&utsname) == -1)
573                         err(2, "uname");
574                 machine = utsname.machine;
575 #else
576                 machine = MACHINE;
577 #endif
578         }
579
580         if (!machine_arch) {
581 #ifndef MACHINE_ARCH
582                 machine_arch = "unknown";
583 #else
584                 machine_arch = MACHINE_ARCH;
585 #endif
586         }
587
588         /*
589          * Set machine_cpu to the minumum supported CPU revision based
590          * on the target architecture, if not already set.
591          */
592         if (!machine_cpu) {
593                 if (!strcmp(machine_arch, "i386"))
594                         machine_cpu = "i386";
595                 else if (!strcmp(machine_arch, "alpha"))
596                         machine_cpu = "ev4";
597                 else
598                         machine_cpu = "unknown";
599         }
600
601         expandVars = TRUE;
602         beSilent = FALSE;               /* Print commands as executed */
603         ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
604         noExecute = FALSE;              /* Execute all commands */
605         keepgoing = FALSE;              /* Stop on error */
606         allPrecious = FALSE;            /* Remove targets when interrupted */
607         queryFlag = FALSE;              /* This is not just a check-run */
608         noBuiltins = FALSE;             /* Read the built-in rules */
609         touchFlag = FALSE;              /* Actually update targets */
610         usePipes = TRUE;                /* Catch child output in pipes */
611         debug = 0;                      /* No debug verbosity, please. */
612         jobsRunning = FALSE;
613
614         maxJobs = DEFMAXJOBS;
615         forceJobs = FALSE;              /* No -j flag */
616         compatMake = FALSE;             /* No compat mode */
617
618         /*
619          * Initialize the parsing, directory and variable modules to prepare
620          * for the reading of inclusion paths and variable settings on the
621          * command line
622          */
623         Dir_Init();             /* Initialize directory structures so -I flags
624                                  * can be processed correctly */
625         Var_Init(environ);      /* As well as the lists of variables for
626                                  * parsing arguments */
627         str_init();
628
629         /*
630          * Initialize various variables.
631          *      MAKE also gets this name, for compatibility
632          *      .MAKEFLAGS gets set to the empty string just in case.
633          *      MFLAGS also gets initialized empty, for compatibility.
634          */
635         Var_Set("MAKE", argv[0], VAR_GLOBAL);
636         Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
637         Var_Set("MFLAGS", "", VAR_GLOBAL);
638         Var_Set("MACHINE", machine, VAR_GLOBAL);
639         Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
640         Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
641 #ifdef MAKE_VERSION
642         Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
643 #endif
644
645         /*
646          * First snag things out of the MAKEFLAGS environment
647          * variable.  Then parse the command line arguments.
648          */
649         Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
650
651         MainParseArgs(argc, argv);
652
653         /*
654          * Find where we are...
655          */
656         curdir = cdpath;
657         if (getcwd(curdir, MAXPATHLEN) == NULL)
658                 err(2, NULL);
659
660         {
661         struct stat sa;
662
663         if (stat(curdir, &sa) == -1)
664             err(2, "%s", curdir);
665         }
666
667         /*
668          * The object directory location is determined using the
669          * following order of preference:
670          *
671          *      1. MAKEOBJDIRPREFIX`cwd`
672          *      2. MAKEOBJDIR
673          *      3. PATH_OBJDIR.${MACHINE}
674          *      4. PATH_OBJDIR
675          *      5. PATH_OBJDIRPREFIX`cwd`
676          *
677          * If one of the first two fails, use the current directory.
678          * If the remaining three all fail, use the current directory.
679          *
680          * Once things are initted,
681          * have to add the original directory to the search path,
682          * and modify the paths for the Makefiles apropriately.  The
683          * current directory is also placed as a variable for make scripts.
684          */
685         if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
686                 if (!(path = getenv("MAKEOBJDIR"))) {
687                         path = PATH_OBJDIR;
688                         pathp = PATH_OBJDIRPREFIX;
689                         snprintf(mdpath, MAXPATHLEN, "%s.%s",
690                                         path, machine);
691                         if (!(objdir = chdir_verify_path(mdpath, obpath)))
692                                 if (!(objdir=chdir_verify_path(path, obpath))) {
693                                         snprintf(mdpath, MAXPATHLEN,
694                                                         "%s%s", pathp, curdir);
695                                         if (!(objdir=chdir_verify_path(mdpath,
696                                                                        obpath)))
697                                                 objdir = curdir;
698                                 }
699                 }
700                 else if (!(objdir = chdir_verify_path(path, obpath)))
701                         objdir = curdir;
702         }
703         else {
704                 snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
705                 if (!(objdir = chdir_verify_path(mdpath, obpath)))
706                         objdir = curdir;
707         }
708         Dir_InitDot();          /* Initialize the "." directory */
709         if (objdir != curdir)
710                 Path_AddDir(&dirSearchPath, curdir);
711         Var_Set(".DIRECTIVE_MAKEENV", "YES", VAR_GLOBAL);
712         Var_Set(".ST_EXPORTVAR", "YES", VAR_GLOBAL);
713         Var_Set(".CURDIR", curdir, VAR_GLOBAL);
714         Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
715
716         if (getenv("MAKE_JOBS_FIFO") != NULL)
717                 forceJobs = TRUE;
718         /*
719          * Be compatible if user did not specify -j and did not explicitly
720          * turned compatibility on
721          */
722         if (!compatMake && !forceJobs)
723                 compatMake = TRUE;
724
725         /*
726          * Initialize target and suffix modules in preparation for
727          * parsing the makefile(s)
728          */
729         Targ_Init();
730         Suff_Init();
731
732         DEFAULT = NULL;
733         time(&now);
734
735         /*
736          * Set up the .TARGETS variable to contain the list of targets to be
737          * created. If none specified, make the variable empty -- the parser
738          * will fill the thing in with the default or .MAIN target.
739          */
740         if (!Lst_IsEmpty(&create)) {
741                 LstNode *ln;
742
743                 for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
744                         char *name = Lst_Datum(ln);
745
746                         Var_Append(".TARGETS", name, VAR_GLOBAL);
747                 }
748         } else
749                 Var_Set(".TARGETS", "", VAR_GLOBAL);
750
751
752         /*
753          * If no user-supplied system path was given (through the -m option)
754          * add the directories from the DEFSYSPATH (more than one may be given
755          * as dir1:...:dirn) to the system include path.
756          */
757         if (TAILQ_EMPTY(&sysIncPath)) {
758                 for (start = syspath; *start != '\0'; start = cp) {
759                         for (cp = start; *cp != '\0' && *cp != ':'; cp++)
760                                 continue;
761                         if (*cp == '\0') {
762                                 Path_AddDir(&sysIncPath, start);
763                         } else {
764                                 *cp++ = '\0';
765                                 Path_AddDir(&sysIncPath, start);
766                         }
767                 }
768         }
769
770         /*
771          * Read in the built-in rules first, followed by the specified
772          * makefile, if it was (makefile != (char *) NULL), or the default
773          * Makefile and makefile, in that order, if it wasn't.
774          */
775         if (!noBuiltins) {
776                 /* Path of sys.mk */
777                 Lst sysMkPath = Lst_Initializer(sysMkPath);
778                 LstNode *ln;
779
780                 Path_Expand(PATH_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 }