1 /* $NetBSD: main.c,v 1.205 2013/01/26 15:53:00 christos Exp $ */
4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * Copyright (c) 1989 by Berkeley Softworks
37 * All rights reserved.
39 * This code is derived from software contributed to Berkeley by
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software
51 * must display the following acknowledgement:
52 * This product includes software developed by the University of
53 * California, Berkeley and its contributors.
54 * 4. Neither the name of the University nor the names of its contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72 static char rcsid[] = "$NetBSD: main.c,v 1.205 2013/01/26 15:53:00 christos Exp $";
74 #include <sys/cdefs.h>
76 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
77 The Regents of the University of California. All rights reserved.");
82 static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
84 __RCSID("$NetBSD: main.c,v 1.205 2013/01/26 15:53:00 christos Exp $");
91 * The main file for this entire program. Exit routines etc
94 * Utility functions defined in this file:
95 * Main_ParseArgLine Takes a line of arguments, breaks them and
96 * treats them as if they were given when first
97 * invoked. Used by the parse module to implement
100 * Error Print a tagged error message. The global
101 * MAKE variable must have been defined. This
102 * takes a format string and two optional
105 * Fatal Print an error message and exit. Also takes
106 * a format string and two arguments.
108 * Punt Aborts all jobs and exits with a message. Also
109 * takes a format string and two arguments.
111 * Finish Finish things up by printing the number of
112 * errors which occurred, as passed to it, and
116 #include <sys/types.h>
117 #include <sys/time.h>
118 #include <sys/param.h>
119 #include <sys/resource.h>
121 #include <sys/stat.h>
123 #include <sys/utsname.h>
138 #include "pathnames.h"
146 #define DEFMAXLOCAL DEFMAXJOBS
147 #endif /* DEFMAXLOCAL */
149 Lst create; /* Targets to be made */
150 time_t now; /* Time at start of make */
151 GNode *DEFAULT; /* .DEFAULT node */
152 Boolean allPrecious; /* .PRECIOUS given on line by itself */
154 static Boolean noBuiltins; /* -r flag */
155 static Lst makefiles; /* ordered list of makefiles to read */
156 static Boolean printVars; /* print value of one or more vars */
157 static Lst variables; /* list of variables to print */
158 int maxJobs; /* -j argument */
159 static int maxJobTokens; /* -j argument */
160 Boolean compatMake; /* -B argument */
161 int debug; /* -d argument */
162 Boolean debugVflag; /* -dV */
163 Boolean noExecute; /* -n flag */
164 Boolean noRecursiveExecute; /* -N flag */
165 Boolean keepgoing; /* -k flag */
166 Boolean queryFlag; /* -q flag */
167 Boolean touchFlag; /* -t flag */
168 Boolean ignoreErrors; /* -i flag */
169 Boolean beSilent; /* -s flag */
170 Boolean oldVars; /* variable substitution style */
171 Boolean checkEnvFirst; /* -e flag */
172 Boolean parseWarnFatal; /* -W flag */
173 Boolean jobServer; /* -J flag */
174 static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
175 Boolean varNoExportEnv; /* -X flag */
176 Boolean doing_depend; /* Set while reading .depend */
177 static Boolean jobsRunning; /* TRUE if the jobs might be running */
178 static const char * tracefile;
179 static void MainParseArgs(int, char **);
180 static int ReadMakefile(const void *, const void *);
181 static void usage(void) MAKE_ATTR_DEAD;
183 static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
184 static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
185 char curdir[MAXPATHLEN + 1]; /* Startup directory */
186 char *progname; /* the program name */
187 char *makeDependfile;
190 Boolean forceJobs = FALSE;
193 * On some systems MACHINE is defined as something other than
198 # define MACHINE FORCE_MACHINE
201 extern Lst parseIncPath;
204 parse_debug_options(const char *argvalue)
211 for (modules = argvalue; *modules; ++modules) {
229 debug |= DEBUG_ERROR;
235 if (modules[1] == '1') {
236 debug |= DEBUG_GRAPH1;
239 else if (modules[1] == '2') {
240 debug |= DEBUG_GRAPH2;
243 else if (modules[1] == '3') {
244 debug |= DEBUG_GRAPH3;
261 debug |= DEBUG_SCRIPT;
264 debug |= DEBUG_PARSE;
279 debug |= DEBUG_SHELL;
282 if (debug_file != stdout && debug_file != stderr)
284 if (*++modules == '+') {
289 if (strcmp(modules, "stdout") == 0) {
293 if (strcmp(modules, "stderr") == 0) {
297 len = strlen(modules);
298 fname = malloc(len + 20);
299 memcpy(fname, modules, len + 1);
300 /* Let the filename be modified by the pid */
301 if (strcmp(fname + len - 3, ".%d") == 0)
302 snprintf(fname + len - 2, 20, "%d", getpid());
303 debug_file = fopen(fname, mode);
305 fprintf(stderr, "Cannot open debug file %s\n",
312 (void)fprintf(stderr,
313 "%s: illegal argument to d option -- %c\n",
320 * Make the debug_file unbuffered, and make
321 * stdout line buffered (unless debugfile == stdout).
323 setvbuf(debug_file, NULL, _IONBF, 0);
324 if (debug_file != stdout) {
325 setvbuf(stdout, NULL, _IOLBF, 0);
331 * Parse a given argument vector. Called from main() and from
332 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
334 * XXX: Deal with command line overriding .MAKEFLAGS in makefile
340 * Various global and local flags will be set depending on the flags
344 MainParseArgs(int argc, char **argv)
350 const char *getopt_def;
352 Boolean inOption, dashDash = FALSE;
353 char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
355 #define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst"
356 /* Can't actually use getopt(3) because rescanning is not portable */
358 getopt_def = OPTFLAGS;
376 if (c != '-' || dashDash)
381 /* '-' found at some earlier point */
382 getopt_spec = strchr(getopt_def, c);
383 if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') {
384 /* -<something> found, and <something> should have an arg */
388 if(*argvalue == '\0') {
404 Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
405 Var_Set(MAKE_MODE, "compat", VAR_GLOBAL, 0);
408 if (chdir(argvalue) == -1) {
409 (void)fprintf(stderr,
410 "%s: chdir %s: %s\n",
415 if (getcwd(curdir, MAXPATHLEN) == NULL) {
416 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
422 if (argvalue == NULL || argvalue[0] == 0) goto noarg;
423 Var_Set(argvalue, "1", VAR_GLOBAL, 0);
424 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
425 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
428 if (argvalue == NULL) goto noarg;
429 Parse_AddIncludeDir(argvalue);
430 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
431 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
434 if (argvalue == NULL) goto noarg;
435 if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
436 (void)fprintf(stderr,
437 "%s: internal error -- J option malformed (%s)\n",
441 if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
442 (fcntl(jp_1, F_GETFD, 0) < 0)) {
444 (void)fprintf(stderr,
445 "%s: ###### warning -- J descriptors were closed!\n",
453 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
454 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
460 noRecursiveExecute = TRUE;
461 Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
465 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
468 if (argvalue == NULL) goto noarg;
469 tracefile = bmake_strdup(argvalue);
470 Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
471 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
474 if (argvalue == NULL) goto noarg;
476 (void)Lst_AtEnd(variables, argvalue);
477 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
478 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
481 parseWarnFatal = TRUE;
484 varNoExportEnv = TRUE;
485 Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
488 if (argvalue == NULL) goto noarg;
489 /* If '-d-opts' don't pass to children */
490 if (argvalue[0] == '-')
493 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
494 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
496 parse_debug_options(argvalue);
499 checkEnvFirst = TRUE;
500 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
503 if (argvalue == NULL) goto noarg;
504 (void)Lst_AtEnd(makefiles, argvalue);
508 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
511 if (argvalue == NULL) goto noarg;
513 maxJobs = strtol(argvalue, &p, 0);
514 if (*p != '\0' || maxJobs < 1) {
515 (void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
519 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
520 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
521 Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL, 0);
522 maxJobTokens = maxJobs;
526 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
529 if (argvalue == NULL) goto noarg;
530 /* look for magic parent directory search string */
531 if (strncmp(".../", argvalue, 4) == 0) {
532 if (!Dir_FindHereOrAbove(curdir, argvalue+4,
533 found_path, sizeof(found_path)))
534 break; /* nothing doing */
535 (void)Dir_AddDir(sysIncPath, found_path);
537 (void)Dir_AddDir(sysIncPath, argvalue);
539 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
540 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
544 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
548 /* Kind of nonsensical, wot? */
549 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
553 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
557 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
561 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
569 fprintf(stderr, "getopt(%s) -> %d (%c)\n",
581 * See if the rest of the arguments are variable assignments and
582 * perform them if so. Else take them to be targets and stuff them
583 * on the end of the "create" list.
585 for (; argc > 1; ++argv, --argc)
586 if (Parse_IsVar(argv[1])) {
587 Parse_DoVar(argv[1], VAR_CMD);
590 Punt("illegal (null) argument.");
591 if (*argv[1] == '-' && !dashDash)
593 (void)Lst_AtEnd(create, bmake_strdup(argv[1]));
598 (void)fprintf(stderr, "%s: option requires an argument -- %c\n",
604 * Main_ParseArgLine --
605 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
606 * is encountered and by main() when reading the .MAKEFLAGS envariable.
607 * Takes a line of arguments and breaks it into its
608 * component words and passes those words and the number of them to the
609 * MainParseArgs function.
610 * The line should have all its leading whitespace removed.
613 * line Line to fracture
619 * Only those that come from the various arguments.
622 Main_ParseArgLine(const char *line)
624 char **argv; /* Manufactured argument vector */
625 int argc; /* Number of arguments in argv */
626 char *args; /* Space used by the args */
628 char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
633 for (; *line == ' '; ++line)
641 * $MAKE may simply be naming the make(1) binary
645 if (!(cp = strrchr(line, '/')))
647 if ((cp = strstr(cp, "make")) &&
648 strcmp(cp, "make") == 0)
652 buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2);
653 (void)snprintf(buf, len, "%s %s", argv0, line);
657 argv = brk_string(buf, &argc, TRUE, &args);
659 Error("Unterminated quoted string [%s]", buf);
664 MainParseArgs(argc, argv);
671 Main_SetObjdir(const char *path)
675 char buf[MAXPATHLEN + 1];
678 /* expand variable substitutions */
679 if (strchr(path, '$') != 0) {
680 snprintf(buf, MAXPATHLEN, "%s", path);
681 path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0);
684 if (path[0] != '/') {
685 snprintf(buf, MAXPATHLEN, "%s/%s", curdir, path);
689 /* look for the directory and try to chdir there */
690 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
692 (void)fprintf(stderr, "make warning: %s: %s.\n",
693 path, strerror(errno));
695 strncpy(objdir, path, MAXPATHLEN);
696 Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0);
697 setenv("PWD", objdir, 1);
709 * ReadAllMakefiles --
710 * wrapper around ReadMakefile() to read all.
713 * TRUE if ok, FALSE on error
716 ReadAllMakefiles(const void *p, const void *q)
718 return (ReadMakefile(p, q) == 0);
722 str2Lst_Append(Lst lp, char *str, const char *sep)
730 for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
731 (void)Lst_AtEnd(lp, cp);
740 siginfo(int signo MAKE_ATTR_UNUSED)
742 char dir[MAXPATHLEN];
743 char str[2 * MAXPATHLEN];
745 if (getcwd(dir, sizeof(dir)) == NULL)
747 len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir);
749 (void)write(STDERR_FILENO, str, (size_t)len);
754 * Allow makefiles some control over the mode we run in.
757 MakeMode(const char *mode)
762 mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0);
765 if (strstr(mode, "compat")) {
770 if (strstr(mode, "meta"))
780 * The main function, for obvious reasons. Initializes variables
781 * and a few modules, then parses the arguments give it in the
782 * environment and on the command line. Reads the system makefile
783 * followed by either Makefile, makefile or the file given by the
784 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
785 * flags it has received by then uses either the Make or the Compat
786 * module to create the initial list of targets.
789 * If -q was given, exits -1 if anything was out-of-date. Else it exits
793 * The program exits when done. Targets are created. etc. etc. etc.
796 main(int argc, char **argv)
798 Lst targs; /* target nodes to create -- passed to Make_Init */
799 Boolean outOfDate = FALSE; /* FALSE if all targets up to date */
801 char *p1, *path, *pwd;
802 char mdpath[MAXPATHLEN];
804 const char *machine = FORCE_MACHINE;
806 const char *machine = getenv("MACHINE");
808 const char *machine_arch = getenv("MACHINE_ARCH");
809 char *syspath = getenv("MAKESYSPATH");
810 Lst sysMkPath; /* Path of sys.mk */
811 char *cp = NULL, *start;
812 /* avoid faults on read-only strings */
813 static char defsyspath[] = _PATH_DEFSYSPATH;
814 char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
815 struct timeval rightnow; /* to initialize random seed */
817 struct utsname utsname;
820 /* default to writing debug to stderr */
824 (void)bmake_signal(SIGINFO, siginfo);
827 * Set the seed to produce a different random sequence
828 * on each program execution.
830 gettimeofday(&rightnow, NULL);
831 srandom(rightnow.tv_sec + rightnow.tv_usec);
833 if ((progname = strrchr(argv[0], '/')) != NULL)
839 * get rid of resource limit on file descriptors
843 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
844 rl.rlim_cur != rl.rlim_max) {
845 rl.rlim_cur = rl.rlim_max;
846 (void)setrlimit(RLIMIT_NOFILE, &rl);
852 * Get the name of this type of MACHINE from utsname
853 * so we can share an executable for similar machines.
854 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
856 * Note that both MACHINE and MACHINE_ARCH are decided at
861 if (uname(&utsname) == -1) {
862 (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
866 machine = utsname.machine;
869 machine = MAKE_MACHINE;
878 #ifdef MAKE_MACHINE_ARCH
879 machine_arch = MAKE_MACHINE_ARCH;
881 machine_arch = "unknown";
884 machine_arch = MACHINE_ARCH;
888 myPid = getpid(); /* remember this for vFork() */
891 * Just in case MAKEOBJDIR wants us to do something tricky.
893 Var_Init(); /* Initialize the lists of variables for
894 * parsing arguments */
895 Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
896 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
898 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
900 Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
902 * This is the traditional preference for makefiles.
904 #ifndef MAKEFILE_PREFERENCE_LIST
905 # define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
907 Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
909 Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0);
911 create = Lst_Init(FALSE);
912 makefiles = Lst_Init(FALSE);
915 variables = Lst_Init(FALSE);
916 beSilent = FALSE; /* Print commands as executed */
917 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
918 noExecute = FALSE; /* Execute all commands */
919 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
920 keepgoing = FALSE; /* Stop on error */
921 allPrecious = FALSE; /* Remove targets when interrupted */
922 queryFlag = FALSE; /* This is not just a check-run */
923 noBuiltins = FALSE; /* Read the built-in rules */
924 touchFlag = FALSE; /* Actually update targets */
925 debug = 0; /* No debug verbosity, please. */
928 maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */
929 maxJobTokens = maxJobs;
930 compatMake = FALSE; /* No compat mode */
934 * Initialize the parsing, directory and variable modules to prepare
935 * for the reading of inclusion paths and variable settings on the
940 * Initialize various variables.
941 * MAKE also gets this name, for compatibility
942 * .MAKEFLAGS gets set to the empty string just in case.
943 * MFLAGS also gets initialized empty, for compatibility.
946 if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) {
948 * Leave alone if it is an absolute path, or if it does
949 * not contain a '/' in which case we need to find it in
950 * the path, like execvp(3) and the shells do.
955 * A relative path, canonicalize it.
957 p1 = realpath(argv[0], mdpath);
958 if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) {
959 p1 = argv[0]; /* realpath failed */
962 Var_Set("MAKE", p1, VAR_GLOBAL, 0);
963 Var_Set(".MAKE", p1, VAR_GLOBAL, 0);
964 Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0);
965 Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
966 Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
967 Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);
970 * Set some other useful macros
976 if (!(ep = getenv(MAKE_LEVEL))) {
977 #ifdef MAKE_LEVEL_SAFE
978 if (!(ep = getenv(MAKE_LEVEL_SAFE)))
982 Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0);
983 snprintf(tmp, sizeof(tmp), "%u", myPid);
984 Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
985 snprintf(tmp, sizeof(tmp), "%u", getppid());
986 Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
991 * First snag any flags out of the MAKE environment variable.
992 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
993 * in a different format).
996 Main_ParseArgLine(getenv("MAKEFLAGS"));
998 Main_ParseArgLine(getenv("MAKE"));
1002 * Find where we are (now).
1003 * We take care of PWD for the automounter below...
1005 if (getcwd(curdir, MAXPATHLEN) == NULL) {
1006 (void)fprintf(stderr, "%s: getcwd: %s.\n",
1007 progname, strerror(errno));
1011 MainParseArgs(argc, argv);
1014 * Verify that cwd is sane.
1016 if (stat(curdir, &sa) == -1) {
1017 (void)fprintf(stderr, "%s: %s: %s.\n",
1018 progname, curdir, strerror(errno));
1023 * All this code is so that we know where we are when we start up
1024 * on a different machine with pmake.
1025 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
1026 * since the value of curdir can vary depending on how we got
1027 * here. Ie sitting at a shell prompt (shell that provides $PWD)
1028 * or via subdir.mk in which case its likely a shell which does
1030 * So, to stop it breaking this case only, we ignore PWD if
1031 * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
1033 #ifndef NO_PWD_OVERRIDE
1035 (pwd = getenv("PWD")) != NULL &&
1036 getenv("MAKEOBJDIRPREFIX") == NULL) {
1037 const char *makeobjdir = getenv("MAKEOBJDIR");
1039 if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
1040 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
1041 sa.st_dev == sb.st_dev)
1042 (void)strncpy(curdir, pwd, MAXPATHLEN);
1046 Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
1049 * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that,
1050 * MAKEOBJDIR is set in the environment, try only that value
1051 * and fall back to .CURDIR if it does not exist.
1053 * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and
1054 * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
1055 * of these paths exist, just use .CURDIR.
1058 (void)Main_SetObjdir(curdir);
1060 if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) {
1061 (void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir);
1062 (void)Main_SetObjdir(mdpath);
1063 } else if ((path = getenv("MAKEOBJDIR")) != NULL) {
1064 (void)Main_SetObjdir(path);
1066 (void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine);
1067 if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) {
1068 (void)snprintf(mdpath, MAXPATHLEN, "%s%s",
1069 _PATH_OBJDIRPREFIX, curdir);
1070 (void)Main_SetObjdir(mdpath);
1075 * Be compatible if user did not specify -j and did not explicitly
1076 * turned compatibility on
1078 if (!compatMake && !forceJobs) {
1083 * Initialize archive, target and suffix modules in preparation for
1084 * parsing the makefile(s)
1089 Trace_Init(tracefile);
1094 Trace_Log(MAKESTART, NULL);
1097 * Set up the .TARGETS variable to contain the list of targets to be
1098 * created. If none specified, make the variable empty -- the parser
1099 * will fill the thing in with the default or .MAIN target.
1101 if (!Lst_IsEmpty(create)) {
1104 for (ln = Lst_First(create); ln != NULL;
1105 ln = Lst_Succ(ln)) {
1106 char *name = (char *)Lst_Datum(ln);
1108 Var_Append(".TARGETS", name, VAR_GLOBAL);
1111 Var_Set(".TARGETS", "", VAR_GLOBAL, 0);
1115 * If no user-supplied system path was given (through the -m option)
1116 * add the directories from the DEFSYSPATH (more than one may be given
1117 * as dir1:...:dirn) to the system include path.
1119 if (syspath == NULL || *syspath == '\0')
1120 syspath = defsyspath;
1122 syspath = bmake_strdup(syspath);
1124 for (start = syspath; *start != '\0'; start = cp) {
1125 for (cp = start; *cp != '\0' && *cp != ':'; cp++)
1130 /* look for magic parent directory search string */
1131 if (strncmp(".../", start, 4) != 0) {
1132 (void)Dir_AddDir(defIncPath, start);
1134 if (Dir_FindHereOrAbove(curdir, start+4,
1135 found_path, sizeof(found_path))) {
1136 (void)Dir_AddDir(defIncPath, found_path);
1140 if (syspath != defsyspath)
1144 * Read in the built-in rules first, followed by the specified
1145 * makefile, if it was (makefile != NULL), or the default
1146 * makefile and Makefile, in that order, if it wasn't.
1151 sysMkPath = Lst_Init(FALSE);
1152 Dir_Expand(_PATH_DEFSYSMK,
1153 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
1155 if (Lst_IsEmpty(sysMkPath))
1156 Fatal("%s: no system rules (%s).", progname,
1158 ln = Lst_Find(sysMkPath, NULL, ReadMakefile);
1160 Fatal("%s: cannot open %s.", progname,
1161 (char *)Lst_Datum(ln));
1164 if (!Lst_IsEmpty(makefiles)) {
1167 ln = Lst_Find(makefiles, NULL, ReadAllMakefiles);
1169 Fatal("%s: cannot open %s.", progname,
1170 (char *)Lst_Datum(ln));
1172 p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
1175 (void)str2Lst_Append(makefiles, p1, NULL);
1176 (void)Lst_Find(makefiles, NULL, ReadMakefile);
1181 /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
1182 if (!noBuiltins || !printVars) {
1183 makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
1185 doing_depend = TRUE;
1186 (void)ReadMakefile(makeDependfile, NULL);
1187 doing_depend = FALSE;
1192 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
1197 Job_ServerStart(maxJobTokens, jp_0, jp_1);
1199 fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
1200 jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
1202 Main_ExportMAKEFLAGS(TRUE); /* initial export */
1205 * For compatibility, look at the directories in the VPATH variable
1206 * and add them to the search path, if the variable is defined. The
1207 * variable's value is in the same format as the PATH envariable, i.e.
1208 * <directory>:<directory>:<directory>...
1210 if (Var_Exists("VPATH", VAR_CMD)) {
1213 * GCC stores string constants in read-only memory, but
1214 * Var_Subst will want to write this thing, so store it
1217 static char VPATH[] = "${VPATH}";
1219 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
1222 /* skip to end of directory */
1223 for (cp = path; *cp != ':' && *cp != '\0'; cp++)
1225 /* Save terminator character so know when to stop */
1228 /* Add directory to search path */
1229 (void)Dir_AddDir(dirSearchPath, path);
1232 } while (savec == ':');
1237 * Now that all search paths have been read for suffixes et al, it's
1238 * time to add the default search path to their lists...
1243 * Propagate attributes through :: dependency lists.
1247 /* print the initial graph, if the user requested it */
1251 /* print the values of any variables requested by the user */
1259 expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
1260 for (ln = Lst_First(variables); ln != NULL;
1261 ln = Lst_Succ(ln)) {
1262 char *var = (char *)Lst_Datum(ln);
1265 if (strchr(var, '$')) {
1266 value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0);
1267 } else if (expandVars) {
1270 if (snprintf(tmp, sizeof(tmp), "${%s}", var) >= (int)(sizeof(tmp)))
1271 Fatal("%s: variable name too big: %s",
1273 value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
1275 value = Var_Value(var, VAR_GLOBAL, &p1);
1277 printf("%s\n", value ? value : "");
1283 * Have now read the entire graph and need to make a list of
1284 * targets to create. If none was given on the command line,
1285 * we consult the parsing module to find the main target(s)
1288 if (Lst_IsEmpty(create))
1289 targs = Parse_MainName();
1291 targs = Targ_FindList(create, TARG_CREATE);
1295 * Initialize job module before traversing the graph
1296 * now that any .BEGIN and .END targets have been read.
1297 * This is done only if the -q flag wasn't given
1298 * (to prevent the .BEGIN from being executed should
1306 /* Traverse the graph, checking on all the targets */
1307 outOfDate = Make_Run(targs);
1310 * Compat_Init will take care of creating all the
1311 * targets as well as initializing the module.
1318 Lst_Destroy(targs, NULL);
1319 Lst_Destroy(variables, NULL);
1320 Lst_Destroy(makefiles, NULL);
1321 Lst_Destroy(create, (FreeProc *)free);
1324 /* print the graph now it's been processed if the user requested it */
1328 Trace_Log(MAKEEND, 0);
1339 return outOfDate ? 1 : 0;
1344 * Open and parse the given makefile.
1347 * 0 if ok. -1 if couldn't open file.
1353 ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
1355 const char *fname = p; /* makefile to read */
1357 size_t len = MAXPATHLEN;
1358 char *name, *path = bmake_malloc(len);
1360 if (!strcmp(fname, "-")) {
1361 Parse_File(NULL /*stdin*/, -1);
1362 Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
1364 /* if we've chdir'd, rebuild the path name */
1365 if (strcmp(curdir, objdir) && *fname != '/') {
1366 size_t plen = strlen(curdir) + strlen(fname) + 2;
1368 path = bmake_realloc(path, len = 2 * plen);
1370 (void)snprintf(path, len, "%s/%s", curdir, fname);
1371 fd = open(path, O_RDONLY);
1377 /* If curdir failed, try objdir (ala .depend) */
1378 plen = strlen(objdir) + strlen(fname) + 2;
1380 path = bmake_realloc(path, len = 2 * plen);
1381 (void)snprintf(path, len, "%s/%s", objdir, fname);
1382 fd = open(path, O_RDONLY);
1388 fd = open(fname, O_RDONLY);
1392 /* look in -I and system include directories. */
1393 name = Dir_FindFile(fname, parseIncPath);
1395 name = Dir_FindFile(fname,
1396 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
1397 if (!name || (fd = open(name, O_RDONLY)) == -1) {
1405 * set the MAKEFILE variable desired by System V fans -- the
1406 * placement of the setting here means it gets set to the last
1407 * makefile specified, as it is set by SysV make.
1411 Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
1412 Parse_File(fname, fd);
1422 * Execute the command in cmd, and return the output of that command
1426 * A string containing the output of the command, or the empty string
1427 * If errnum is not NULL, it contains the reason for the command failure
1430 * The string must be freed by the caller.
1433 Cmd_Exec(const char *cmd, const char **errnum)
1435 const char *args[4]; /* Args for invoking the shell */
1436 int fds[2]; /* Pipe streams */
1437 int cpid; /* Child PID */
1438 int pid; /* PID from wait() */
1439 char *res; /* result */
1440 WAIT_T status; /* command exit status */
1441 Buffer buf; /* buffer to store the result */
1451 * Set up arguments for shell
1453 args[0] = shellName;
1459 * Open a pipe for fetching its output
1461 if (pipe(fds) == -1) {
1462 *errnum = "Couldn't create pipe for \"%s\"";
1469 switch (cpid = vFork()) {
1472 * Close input side of pipe
1474 (void)close(fds[0]);
1477 * Duplicate the output stream to the shell's output, then
1478 * shut the extra thing down. Note we don't fetch the error
1479 * stream...why not? Why?
1481 (void)dup2(fds[1], 1);
1482 (void)close(fds[1]);
1486 (void)execv(shellPath, UNCONST(args));
1491 *errnum = "Couldn't exec \"%s\"";
1496 * No need for the writing half
1498 (void)close(fds[1]);
1503 char result[BUFSIZ];
1504 cc = read(fds[0], result, sizeof(result));
1506 Buf_AddBytes(&buf, cc, result);
1508 while (cc > 0 || (cc == -1 && errno == EINTR));
1511 * Close the input side of the pipe.
1513 (void)close(fds[0]);
1516 * Wait for the process to exit.
1518 while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) {
1519 JobReapChild(pid, status, FALSE);
1522 cc = Buf_Size(&buf);
1523 res = Buf_Destroy(&buf, FALSE);
1526 *errnum = "Couldn't read shell's output for \"%s\"";
1528 if (WIFSIGNALED(status))
1529 *errnum = "\"%s\" exited on a signal";
1530 else if (WEXITSTATUS(status) != 0)
1531 *errnum = "\"%s\" returned non-zero status";
1534 * Null-terminate the result, convert newlines to spaces and
1535 * install it in the variable.
1540 if (cc > 0 && *--cp == '\n') {
1542 * A final newline is just stripped
1556 res = bmake_malloc(1);
1563 * Print an error message given its format.
1569 * The message is printed.
1573 Error(const char *fmt, ...)
1578 err_file = debug_file;
1579 if (err_file == stdout)
1581 (void)fflush(stdout);
1584 fprintf(err_file, "%s: ", progname);
1585 (void)vfprintf(err_file, fmt, ap);
1587 (void)fprintf(err_file, "\n");
1588 (void)fflush(err_file);
1589 if (err_file == stderr)
1597 * Produce a Fatal error message. If jobs are running, waits for them
1608 Fatal(const char *fmt, ...)
1616 (void)fflush(stdout);
1617 (void)vfprintf(stderr, fmt, ap);
1619 (void)fprintf(stderr, "\n");
1620 (void)fflush(stderr);
1622 PrintOnError(NULL, NULL);
1624 if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
1626 Trace_Log(MAKEERROR, 0);
1627 exit(2); /* Not 1 so -q can distinguish error */
1632 * Major exception once jobs are being created. Kills all jobs, prints
1633 * a message and exits.
1639 * All children are killed indiscriminately and the program Lib_Exits
1643 Punt(const char *fmt, ...)
1648 (void)fflush(stdout);
1649 (void)fprintf(stderr, "%s: ", progname);
1650 (void)vfprintf(stderr, fmt, ap);
1652 (void)fprintf(stderr, "\n");
1653 (void)fflush(stderr);
1655 PrintOnError(NULL, NULL);
1662 * Exit without giving a message.
1677 Trace_Log(MAKEERROR, 0);
1678 exit(2); /* Not 1, so -q can distinguish error */
1683 * Called when aborting due to errors in child shell to signal
1694 /* number of errors encountered in Make_Make */
1696 Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1701 * Remove a file carefully, avoiding directories.
1704 eunlink(const char *file)
1708 if (lstat(file, &st) == -1)
1711 if (S_ISDIR(st.st_mode)) {
1715 return unlink(file);
1720 * Print why exec failed, avoiding stdio.
1723 execError(const char *af, const char *av)
1727 struct iovec iov[8];
1729 (void)(iov[i].iov_base = UNCONST(s), \
1730 iov[i].iov_len = strlen(iov[i].iov_base), \
1733 #define IOADD(s) (void)write(2, s, strlen(s))
1741 IOADD(") failed (");
1742 IOADD(strerror(errno));
1746 while (writev(2, iov, 8) == -1 && errno == EAGAIN)
1753 * exit with usage message
1758 (void)fprintf(stderr,
1759 "usage: %s [-BeikNnqrstWX] \n\
1760 [-C directory] [-D variable] [-d flags] [-f makefile]\n\
1761 [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
1762 [-V variable] [variable=value] [target ...]\n", progname);
1768 PrintAddr(void *a, void *b)
1770 printf("%lx ", (unsigned long) a);
1777 PrintOnError(GNode *gn, const char *s)
1779 static GNode *en = NULL;
1786 printf("\n%s: stopped in %s\n", progname, curdir);
1789 return; /* we've been here! */
1792 * We can print this even if there is no .ERROR target.
1794 Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0);
1796 strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
1798 cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
1805 * Finally, see if there is a .ERROR target, and run it if so.
1807 en = Targ_FindNode(".ERROR", TARG_NOCREATE);
1809 en->type |= OP_SPECIAL;
1810 Compat_Make(en, en);
1815 Main_ExportMAKEFLAGS(Boolean first)
1817 static int once = 1;
1825 strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
1827 s = Var_Subst(NULL, tmp, VAR_CMD, 0);
1830 setenv("MAKEFLAGS", s, 1);
1832 setenv("MAKE", s, 1);
1840 static char *tmpdir = NULL;
1846 * Honor $TMPDIR but only if it is valid.
1847 * Ensure it ends with /.
1849 tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0);
1850 if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
1852 tmpdir = bmake_strdup(_PATH_TMP);
1859 * Create and open a temp file using "pattern".
1860 * If "fnamep" is provided set it to a copy of the filename created.
1861 * Otherwise unlink the file once open.
1864 mkTempFile(const char *pattern, char **fnamep)
1866 static char *tmpdir = NULL;
1867 char tfile[MAXPATHLEN];
1873 tmpdir = getTmpdir();
1874 if (pattern[0] == '/') {
1875 snprintf(tfile, sizeof(tfile), "%s", pattern);
1877 snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern);
1879 if ((fd = mkstemp(tfile)) < 0)
1880 Punt("Could not create temporary file %s: %s", tfile, strerror(errno));
1882 *fnamep = bmake_strdup(tfile);
1884 unlink(tfile); /* we just want the descriptor */
1891 * Return a Boolean based on setting of a knob.
1893 * If the knob is not set, the supplied default is the return value.
1894 * If set, anything that looks or smells like "No", "False", "Off", "0" etc,
1895 * is FALSE, otherwise TRUE.
1898 getBoolean(const char *name, Boolean bf)
1903 if (snprintf(tmp, sizeof(tmp), "${%s:tl}", name) < (int)(sizeof(tmp))) {
1904 cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
1908 case '\0': /* not set - the default wins */