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