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