1 /* $OpenBSD: main.c,v 1.133 2024/06/18 02:11:03 millert Exp $ */
2 /* $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $ */
3
4 /*
5 * Copyright (c) 1988, 1989, 1990, 1993
6 * The Regents of the University of California. All rights reserved.
7 * Copyright (c) 1989 by Berkeley Softworks
8 * All rights reserved.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * Adam de Boor.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38 #include <sys/param.h> /* MACHINE MACHINE_ARCH */
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/utsname.h>
42 #include <err.h>
43 #include <errno.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include "defines.h"
49 #include "var.h"
50 #include "lowparse.h"
51 #include "parse.h"
52 #include "parsevar.h"
53 #include "dir.h"
54 #include "direxpand.h"
55 #include "error.h"
56 #include "pathnames.h"
57 #include "init.h"
58 #include "job.h"
59 #include "targ.h"
60 #include "suff.h"
61 #include "str.h"
62 #include "main.h"
63 #include "lst.h"
64 #include "memory.h"
65 #include "dump.h"
66 #include "enginechoice.h"
67
68 #define MAKEFLAGS ".MAKEFLAGS"
69
70 static LIST to_create; /* Targets to be made */
71 Lst create = &to_create;
72 bool allPrecious; /* .PRECIOUS given on line by itself */
73
74 static bool noBuiltins; /* -r flag */
75 static LIST makefiles; /* ordered list of makefiles to read */
76 static LIST varstoprint; /* list of variables to print */
77 static int optj; /* -j argument */
78 static bool compatMake; /* -B argument */
79 static bool forceJobs = false;
80 int debug; /* -d flag */
81 bool noExecute; /* -n flag */
82 bool keepgoing; /* -k flag */
83 bool queryFlag; /* -q flag */
84 bool touchFlag; /* -t flag */
85 bool ignoreErrors; /* -i flag */
86 bool beSilent; /* -s flag */
87 bool dumpData; /* -p flag */
88
89 static LIST unreadable;
90
91 struct dirs {
92 char *current;
93 char *object;
94 };
95
96 static void MainParseArgs(int, char **);
97 static void add_dirpath(Lst, const char *);
98 static void usage(void);
99 static void posixParseOptLetter(int);
100 static void record_option(int, const char *);
101
102 static char *figure_out_MACHINE(void);
103 static char *figure_out_MACHINE_ARCH(void);
104 static char *figure_out_MACHINE_CPU(void);
105
106 static char *chdir_verify_path(const char *, struct dirs *);
107 static char *figure_out_CURDIR(void);
108 static void setup_CURDIR_OBJDIR(struct dirs *);
109
110 static void setup_VPATH(void);
111
112 static void read_all_make_rules(bool, bool, Lst, struct dirs *);
113 static void read_makefile_list(Lst, struct dirs *);
114 static bool ReadMakefile(void *, void *);
115
116 static void
record_option(int c,const char * arg)117 record_option(int c, const char *arg)
118 {
119 char opt[3];
120
121 opt[0] = '-';
122 opt[1] = c;
123 opt[2] = '\0';
124 Var_Append(MAKEFLAGS, opt);
125 if (arg != NULL)
126 Var_Append(MAKEFLAGS, arg);
127 }
128
129 void
set_notparallel(void)130 set_notparallel(void)
131 {
132 compatMake = true;
133 }
134
135 static void
posixParseOptLetter(int c)136 posixParseOptLetter(int c)
137 {
138 switch(c) {
139 case 'B':
140 compatMake = true;
141 return; /* XXX don't pass to submakes. */
142 case 'S':
143 keepgoing = false;
144 break;
145 case 'e':
146 Var_setCheckEnvFirst(true);
147 break;
148 case 'i':
149 ignoreErrors = true;
150 break;
151 case 'k':
152 keepgoing = true;
153 break;
154 case 'n':
155 noExecute = true;
156 break;
157 case 'p':
158 dumpData = true;
159 break;
160 case 'q':
161 queryFlag = true;
162 /* Kind of nonsensical, wot? */
163 break;
164 case 'r':
165 noBuiltins = true;
166 break;
167 case 's':
168 beSilent = true;
169 break;
170 case 't':
171 touchFlag = true;
172 break;
173 default:
174 usage();
175 }
176 record_option(c, NULL);
177 }
178
179 /*-
180 * MainParseArgs --
181 * Parse a given argument vector. Called from main() and from
182 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
183 *
184 * XXX: Deal with command line overriding .MAKEFLAGS in makefile
185 *
186 * Side Effects:
187 * Various global and local flags will be set depending on the flags
188 * given
189 */
190 static void
MainParseArgs(int argc,char ** argv)191 MainParseArgs(int argc, char **argv)
192 {
193 int c, optend;
194
195 #define OPTFLAGS "BC:D:I:SV:d:ef:ij:km:npqrst"
196 #define OPTLETTERS "BSiknpqrst"
197
198 if (pledge("stdio rpath wpath cpath fattr proc exec", NULL) == -1)
199 err(2, "pledge");
200
201 optind = 1; /* since we're called more than once */
202 optreset = 1;
203 optend = 0;
204 while (optind < argc) {
205 if (!optend && argv[optind][0] == '-') {
206 if (argv[optind][1] == '\0')
207 optind++; /* ignore "-" */
208 else if (argv[optind][1] == '-' &&
209 argv[optind][2] == '\0') {
210 optind++; /* ignore "--" */
211 optend++; /* "--" denotes end of flags */
212 }
213 }
214 c = optend ? -1 : getopt(argc, argv, OPTFLAGS);
215 switch (c) {
216 case 'C':
217 break;
218 case 'D':
219 Var_Set(optarg, "1");
220 record_option(c, optarg);
221 break;
222 case 'I':
223 Parse_AddIncludeDir(optarg);
224 record_option(c, optarg);
225 break;
226 case 'V':
227 Lst_AtEnd(&varstoprint, optarg);
228 record_option(c, optarg);
229 break;
230 case 'd': {
231 char *modules = optarg;
232
233 for (; *modules; ++modules)
234 switch (*modules) {
235 case 'A':
236 debug = ~0;
237 break;
238 case 'a':
239 debug |= DEBUG_ARCH;
240 break;
241 case 'c':
242 debug |= DEBUG_COND;
243 break;
244 case 'd':
245 debug |= DEBUG_DIR;
246 break;
247 case 'D':
248 debug |= DEBUG_DOUBLE;
249 break;
250 case 'e':
251 debug |= DEBUG_EXPENSIVE;
252 break;
253 case 'f':
254 debug |= DEBUG_FOR;
255 break;
256 case 'g':
257 if (modules[1] == '1') {
258 debug |= DEBUG_GRAPH1;
259 ++modules;
260 }
261 else if (modules[1] == '2') {
262 debug |= DEBUG_GRAPH2;
263 ++modules;
264 }
265 break;
266 case 'h':
267 debug |= DEBUG_HELDJOBS;
268 break;
269 case 'j':
270 debug |= DEBUG_JOB | DEBUG_KILL;
271 break;
272 case 'J':
273 /* ignore */
274 break;
275 case 'k':
276 debug |= DEBUG_KILL;
277 break;
278 case 'l':
279 debug |= DEBUG_LOUD;
280 break;
281 case 'm':
282 debug |= DEBUG_MAKE;
283 break;
284 case 'n':
285 debug |= DEBUG_NAME_MATCHING;
286 break;
287 case 'p':
288 debug |= DEBUG_PARALLEL;
289 break;
290 case 'q':
291 debug |= DEBUG_QUICKDEATH;
292 break;
293 case 's':
294 debug |= DEBUG_SUFF;
295 break;
296 case 't':
297 debug |= DEBUG_TARG;
298 break;
299 case 'T':
300 debug |= DEBUG_TARGGROUP;
301 break;
302 case 'v':
303 debug |= DEBUG_VAR;
304 break;
305 default:
306 (void)fprintf(stderr,
307 "make: illegal argument to -d option -- %c\n",
308 *modules);
309 usage();
310 }
311 record_option(c, optarg);
312 break;
313 }
314 case 'f':
315 Lst_AtEnd(&makefiles, optarg);
316 break;
317 case 'j': {
318 const char *errstr;
319
320 forceJobs = true;
321 optj = strtonum(optarg, 1, INT_MAX, &errstr);
322 if (errstr != NULL) {
323 fprintf(stderr,
324 "make: illegal argument to -j option"
325 " -- %s -- %s\n", optarg, errstr);
326 usage();
327 }
328 record_option(c, optarg);
329 break;
330 }
331 case 'm':
332 Dir_AddDir(systemIncludePath, optarg);
333 record_option(c, optarg);
334 break;
335 case -1:
336 /* Check for variable assignments and targets. */
337 if (argv[optind] != NULL &&
338 !Parse_CmdlineVar(argv[optind])) {
339 if (!*argv[optind])
340 Punt("illegal (null) argument.");
341 Lst_AtEnd(create, estrdup(argv[optind]));
342 }
343 optind++; /* skip over non-option */
344 break;
345 default:
346 posixParseOptLetter(c);
347 }
348 }
349 }
350
351 static void
MainParseChdir(int argc,char ** argv)352 MainParseChdir(int argc, char **argv)
353 {
354 int c, optend, oldopterr;
355
356 optind = 1; /* since we're called more than once */
357 optreset = 1;
358 optend = 0;
359 oldopterr = opterr;
360 opterr = 0;
361 while (optind < argc) {
362 if (!optend && argv[optind][0] == '-') {
363 if (argv[optind][1] == '\0')
364 optind++; /* ignore "-" */
365 else if (argv[optind][1] == '-' &&
366 argv[optind][2] == '\0') {
367 optind++; /* ignore "--" */
368 optend++; /* "--" denotes end of flags */
369 }
370 }
371 c = optend ? -1 : getopt(argc, argv, OPTFLAGS);
372 switch (c) {
373 case 'C':
374 if (chdir(optarg) == -1)
375 err(2, "chdir(%s)", optarg);
376 break;
377 case -1:
378 optind++; /* skip over non-option */
379 break;
380 default:
381 break;
382 }
383 }
384 opterr = oldopterr;
385 }
386
387 /*-
388 * Main_ParseArgLine --
389 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
390 * is encountered and by main() when reading the .MAKEFLAGS envariable.
391 * Takes a line of arguments and breaks it into its
392 * component words and passes those words and the number of them to the
393 * MainParseArgs function.
394 * The line should have all its leading whitespace removed.
395 *
396 * Side Effects:
397 * Only those that come from the various arguments.
398 */
399 void
Main_ParseArgLine(const char * line)400 Main_ParseArgLine(const char *line) /* Line to fracture */
401 {
402 char **argv; /* Manufactured argument vector */
403 int argc; /* Number of arguments in argv */
404 char *args; /* Space used by the args */
405 char *buf;
406 char *argv0;
407 const char *s;
408 size_t len;
409
410
411 if (line == NULL)
412 return;
413 for (; *line == ' '; ++line)
414 continue;
415 if (!*line)
416 return;
417
418 /* POSIX rule: MAKEFLAGS can hold a set of option letters without
419 * any blanks or dashes. */
420 for (s = line;; s++) {
421 if (*s == '\0') {
422 while (line != s)
423 posixParseOptLetter(*line++);
424 return;
425 }
426 if (strchr(OPTLETTERS, *s) == NULL)
427 break;
428 }
429 argv0 = Var_Value(".MAKE");
430 len = strlen(line) + strlen(argv0) + 2;
431 buf = emalloc(len);
432 (void)snprintf(buf, len, "%s %s", argv0, line);
433
434 argv = brk_string(buf, &argc, &args);
435 free(buf);
436 MainParseArgs(argc, argv);
437
438 free(args);
439 free(argv);
440 }
441
442 /* Add a :-separated path to a Lst of directories. */
443 static void
add_dirpath(Lst l,const char * n)444 add_dirpath(Lst l, const char *n)
445 {
446 const char *start;
447 const char *cp;
448
449 for (start = n;;) {
450 for (cp = start; *cp != '\0' && *cp != ':';)
451 cp++;
452 Dir_AddDiri(l, start, cp);
453 if (*cp == '\0')
454 break;
455 else
456 start= cp+1;
457 }
458 }
459
460 /*
461 * Get the name of this type of MACHINE from utsname so we can share an
462 * executable for similar machines. (i.e. m68k: amiga hp300, mac68k, sun3, ...)
463 *
464 * Note that MACHINE, MACHINE_ARCH and MACHINE_CPU are decided at
465 * run-time.
466 */
467 static char *
figure_out_MACHINE(void)468 figure_out_MACHINE(void)
469 {
470 char *r = getenv("MACHINE");
471 if (r == NULL) {
472 static struct utsname utsname;
473
474 if (uname(&utsname) == -1)
475 err(2, "uname");
476 r = utsname.machine;
477 }
478 return r;
479 }
480
481 static char *
figure_out_MACHINE_ARCH(void)482 figure_out_MACHINE_ARCH(void)
483 {
484 char *r = getenv("MACHINE_ARCH");
485 if (r == NULL) {
486 #ifndef MACHINE_ARCH
487 r = "unknown"; /* XXX: no uname -p yet */
488 #else
489 r = MACHINE_ARCH;
490 #endif
491 }
492 return r;
493 }
494 static char *
figure_out_MACHINE_CPU(void)495 figure_out_MACHINE_CPU(void)
496 {
497 char *r = getenv("MACHINE_CPU");
498 if (r == NULL) {
499 #if !defined(MACHINE_CPU) && ! defined(MACHINE_ARCH)
500 r = "unknown"; /* XXX: no uname -p yet */
501 #else
502 #if defined(MACHINE_CPU)
503 r = MACHINE_CPU;
504 #else
505 r = MACHINE_ARCH;
506 #endif
507 #endif
508 }
509 return r;
510 }
511
512 static char *
figure_out_CURDIR(void)513 figure_out_CURDIR(void)
514 {
515 char *dir, *cwd;
516 struct stat sa, sb;
517
518 /* curdir is cwd... */
519 cwd = getcwd(NULL, 0);
520 if (cwd == NULL)
521 err(2, "getcwd");
522
523 if (stat(cwd, &sa) == -1)
524 err(2, "%s", cwd);
525
526 /* ...but we can use the alias $PWD if we can prove it is the same
527 * directory */
528 if ((dir = getenv("PWD")) != NULL) {
529 if (stat(dir, &sb) == 0 && sa.st_ino == sb.st_ino &&
530 sa.st_dev == sb.st_dev) {
531 free(cwd);
532 return estrdup(dir);
533 }
534 }
535
536 return cwd;
537 }
538
539 static char *
chdir_verify_path(const char * path,struct dirs * d)540 chdir_verify_path(const char *path, struct dirs *d)
541 {
542 if (chdir(path) == 0) {
543 if (path[0] != '/')
544 return Str_concat(d->current, path, '/');
545 else
546 return estrdup(path);
547 }
548 return NULL;
549 }
550
551 static void
setup_CURDIR_OBJDIR(struct dirs * d)552 setup_CURDIR_OBJDIR(struct dirs *d)
553 {
554 char *path;
555
556 d->current = figure_out_CURDIR();
557 /*
558 * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
559 * exists, change into it and build there.
560 *
561 * Once things are initted,
562 * have to add the original directory to the search path,
563 * and modify the paths for the Makefiles appropriately. The
564 * current directory is also placed as a variable for make scripts.
565 */
566 if ((path = getenv("MAKEOBJDIR")) == NULL) {
567 path = _PATH_OBJDIR;
568 }
569 d->object = chdir_verify_path(path, d);
570 if (d->object == NULL)
571 d->object = d->current;
572 }
573
574 /*
575 * if the VPATH variable is defined, add its contents to the search path.
576 * Uses the same format as the PATH env variable, i.e.,
577 * <directory>:<directory>:<directory>...
578 */
579 static void
setup_VPATH(void)580 setup_VPATH(void)
581 {
582 if (Var_Value("VPATH") != NULL) {
583 char *vpath;
584
585 vpath = Var_Subst("${VPATH}", NULL, false);
586 add_dirpath(defaultPath, vpath);
587 (void)free(vpath);
588 }
589 }
590
591 static void
read_makefile_list(Lst mk,struct dirs * d)592 read_makefile_list(Lst mk, struct dirs *d)
593 {
594 LstNode ln;
595 ln = Lst_Find(mk, ReadMakefile, d);
596 if (ln != NULL)
597 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
598 }
599
600 static void
read_all_make_rules(bool noBuiltins,bool read_depend,Lst makefiles,struct dirs * d)601 read_all_make_rules(bool noBuiltins, bool read_depend,
602 Lst makefiles, struct dirs *d)
603 {
604 /*
605 * Read in the built-in rules first, followed by the specified
606 * makefile(s), or the default Makefile or makefile, in that order.
607 */
608 if (!noBuiltins) {
609 LIST sysMkPath; /* Path of sys.mk */
610
611 Lst_Init(&sysMkPath);
612 Dir_Expand(_PATH_DEFSYSMK, systemIncludePath, &sysMkPath);
613 if (Lst_IsEmpty(&sysMkPath))
614 Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
615
616 read_makefile_list(&sysMkPath, d);
617 }
618
619 if (!Lst_IsEmpty(makefiles)) {
620 read_makefile_list(makefiles, d);
621 } else if (!ReadMakefile("makefile", d))
622 (void)ReadMakefile("Makefile", d);
623
624 /* read a .depend file, if it exists, and we're not building depend */
625
626 if (read_depend)
627 (void)ReadMakefile(".depend", d);
628 Parse_End();
629 }
630
631 static void
run_node(GNode * gn,bool * has_errors,bool * out_of_date)632 run_node(GNode *gn, bool *has_errors, bool *out_of_date)
633 {
634 LIST l;
635
636 Lst_Init(&l);
637 Lst_AtEnd(&l, gn);
638 engine_run_list(&l, has_errors, out_of_date);
639 Lst_Destroy(&l, NOFREE);
640 }
641
642 int main(int, char **);
643
644 int
main(int argc,char ** argv)645 main(int argc, char **argv)
646 {
647 static LIST targs; /* target nodes to create */
648 bool outOfDate = false; /* false if all targets up to date */
649 bool errored = false; /* true if errors occurred */
650 char *machine = figure_out_MACHINE();
651 char *machine_arch = figure_out_MACHINE_ARCH();
652 char *machine_cpu = figure_out_MACHINE_CPU();
653 const char *syspath = _PATH_DEFSYSPATH;
654 char *p;
655 static struct dirs d;
656 bool read_depend = true;/* false if we don't want to read .depend */
657
658 MainParseChdir(argc, argv);
659 setup_CURDIR_OBJDIR(&d);
660
661 esetenv("PWD", d.object);
662 unsetenv("CDPATH");
663
664 Static_Lst_Init(create);
665 Static_Lst_Init(&makefiles);
666 Static_Lst_Init(&varstoprint);
667 Static_Lst_Init(&targs);
668 Static_Lst_Init(&special);
669
670 beSilent = false; /* Print commands as executed */
671 ignoreErrors = false; /* Pay attention to non-zero returns */
672 noExecute = false; /* Execute all commands */
673 keepgoing = false; /* Stop on error */
674 allPrecious = false; /* Remove targets when interrupted */
675 queryFlag = false; /* This is not just a check-run */
676 noBuiltins = false; /* Read the built-in rules */
677 touchFlag = false; /* Actually update targets */
678 debug = 0; /* No debug verbosity, please. */
679
680 optj = DEFMAXJOBS;
681 compatMake = false; /* No compat mode */
682
683
684 /*
685 * Initialize all external modules.
686 */
687 Init();
688
689 if (d.object != d.current)
690 Dir_AddDir(defaultPath, d.current);
691 Var_Set(".CURDIR", d.current);
692 Var_Set(".OBJDIR", d.object);
693 Parse_setcurdir(d.current);
694 Targ_setdirs(d.current, d.object);
695
696 /*
697 * Initialize various variables.
698 * MAKE also gets this name, for compatibility
699 * .MAKEFLAGS gets set to the empty string just in case.
700 * MFLAGS also gets initialized empty, for compatibility.
701 */
702 Var_Set("MAKE", argv[0]);
703 Var_Set(".MAKE", argv[0]);
704 Var_Set(MAKEFLAGS, "");
705 Var_Set("MFLAGS", "");
706 Var_Set("MACHINE", machine);
707 Var_Set("MACHINE_ARCH", machine_arch);
708 Var_Set("MACHINE_CPU", machine_cpu);
709
710 /*
711 * First snag any flags out of the MAKEFLAGS environment variable.
712 */
713 Main_ParseArgLine(getenv("MAKEFLAGS"));
714
715 basedirectory = getenv("MAKEBASEDIRECTORY");
716 if (basedirectory == NULL)
717 setenv("MAKEBASEDIRECTORY", d.current, 0);
718
719 MainParseArgs(argc, argv);
720
721 /*
722 * Be compatible if user did not specify -j
723 */
724 if (!forceJobs)
725 compatMake = true;
726
727 /* And set up everything for sub-makes */
728 Var_AddCmdline(MAKEFLAGS);
729
730
731 /*
732 * Set up the .TARGETS variable to contain the list of targets to be
733 * created. If none specified, make the variable empty -- the parser
734 * will fill the thing in with the default or .MAIN target.
735 */
736 if (!Lst_IsEmpty(create)) {
737 LstNode ln;
738
739 for (ln = Lst_First(create); ln != NULL; ln = Lst_Adv(ln)) {
740 char *name = Lst_Datum(ln);
741
742 if (strcmp(name, "depend") == 0)
743 read_depend = false;
744
745 Var_Append(".TARGETS", name);
746 }
747 } else
748 Var_Set(".TARGETS", "");
749
750
751 /*
752 * If no user-supplied system path was given (through the -m option)
753 * add the directories from the DEFSYSPATH (more than one may be given
754 * as dir1:...:dirn) to the system include path.
755 */
756 if (Lst_IsEmpty(systemIncludePath))
757 add_dirpath(systemIncludePath, syspath);
758
759 read_all_make_rules(noBuiltins, read_depend, &makefiles, &d);
760
761 if (compatMake)
762 optj = 1;
763
764 Var_Append("MFLAGS", Var_Value(MAKEFLAGS));
765
766 /* Install all the flags into the MAKEFLAGS env variable. */
767 if (((p = Var_Value(MAKEFLAGS)) != NULL) && *p)
768 esetenv("MAKEFLAGS", p);
769
770 setup_VPATH();
771
772 process_suffixes_after_makefile_is_read();
773
774 if (dumpData) {
775 dump_data();
776 exit(0);
777 }
778
779 /* Print the initial graph, if the user requested it. */
780 if (DEBUG(GRAPH1))
781 dump_data();
782
783 /* Print the values of any variables requested by the user. */
784 if (!Lst_IsEmpty(&varstoprint)) {
785 LstNode ln;
786
787 for (ln = Lst_First(&varstoprint); ln != NULL;
788 ln = Lst_Adv(ln)) {
789 char *value = Var_Value(Lst_Datum(ln));
790
791 printf("%s\n", value ? value : "");
792 }
793 } else {
794 /* Have now read the entire graph and need to make a list
795 * of targets to create. If none was given on the command
796 * line, we consult the parsing module to find the main
797 * target(s) to create. */
798 if (Lst_IsEmpty(create))
799 Parse_MainName(&targs);
800 else
801 Targ_FindList(&targs, create);
802
803 choose_engine(compatMake);
804 Job_Init(optj);
805 if (!queryFlag && node_is_real(begin_node))
806 run_node(begin_node, &errored, &outOfDate);
807
808 if (!errored)
809 engine_run_list(&targs, &errored, &outOfDate);
810
811 if (!queryFlag && !errored && node_is_real(end_node))
812 run_node(end_node, &errored, &outOfDate);
813 }
814
815 /* print the graph now it's been processed if the user requested it */
816 if (DEBUG(GRAPH2))
817 post_mortem();
818
819 /* Note that we only hit this code if -k is used, otherwise we
820 * exited early in case of errors. */
821 if (errored)
822 Fatal("Errors while building");
823
824 if (queryFlag && outOfDate)
825 return 1;
826 else
827 return 0;
828 }
829
830 struct unreadable {
831 char *fname;
832 int errcode;
833 };
834
835 void
dump_unreadable(void)836 dump_unreadable(void)
837 {
838 struct unreadable *u;
839
840 if (Lst_IsEmpty(&unreadable))
841 return;
842
843 fprintf(stderr, "Makefile(s) that couldn't be read:\n");
844
845 while ((u = Lst_Pop(&unreadable))) {
846 fprintf(stderr, "\t%s: %s\n", u->fname, strerror(u->errcode));
847 free(u->fname);
848 free(u);
849 }
850 }
851
852 static FILE *
open_makefile(const char * fname)853 open_makefile(const char *fname)
854 {
855 FILE *stream;
856 struct unreadable *u;
857
858 stream = fopen(fname, "r");
859 if (stream != NULL)
860 return stream;
861
862 if (errno != ENOENT) {
863 u = emalloc(sizeof *u);
864 u->fname = estrdup(fname);
865 u->errcode = errno;
866 Lst_AtEnd(&unreadable, u);
867 }
868
869 return NULL;
870 }
871
872 /*-
873 * ReadMakefile --
874 * Open and parse the given makefile.
875 *
876 * Results:
877 * true if ok. false if couldn't open file.
878 *
879 * Side Effects:
880 * lots
881 */
882 static bool
ReadMakefile(void * p,void * q)883 ReadMakefile(void *p, void *q)
884 {
885 const char *fname = p; /* makefile to read */
886 struct dirs *d = q;
887 FILE *stream;
888 char *name;
889
890 if (!strcmp(fname, "-")) {
891 Var_Set("MAKEFILE", "");
892 Parse_File(estrdup("(stdin)"), stdin);
893 } else {
894 if ((stream = open_makefile(fname)) != NULL)
895 goto found;
896 /* if we've chdir'd, rebuild the path name */
897 if (d->current != d->object && *fname != '/') {
898 char *path;
899
900 path = Str_concat(d->current, fname, '/');
901 if ((stream = open_makefile(path)) == NULL)
902 free(path);
903 else {
904 fname = path;
905 goto found;
906 }
907 }
908 /* look in -I and system include directories. */
909 name = Dir_FindFile(fname, userIncludePath);
910 if (!name)
911 name = Dir_FindFile(fname, systemIncludePath);
912 if (!name)
913 return false;
914 /* do not try to open a file we already have, so that
915 * dump_unreadable() yields non-confusing results.
916 */
917 if (strcmp(name, fname) == 0)
918 return false;
919 if ((stream = open_makefile(name)) == NULL)
920 return false;
921 fname = name;
922 /*
923 * set the MAKEFILE variable desired by System V fans -- the
924 * placement of the setting here means it gets set to the last
925 * makefile specified, as it is set by SysV make.
926 */
927 found: Var_Set("MAKEFILE", fname);
928 Parse_File(fname, stream);
929 }
930 return true;
931 }
932
933
934 /*
935 * usage --
936 * exit with usage message
937 */
938 static void
usage(void)939 usage(void)
940 {
941 (void)fprintf(stderr,
942 "usage: make [-BeiknpqrSst] [-C directory] [-D variable] [-d flags] [-f mk]\n\
943 [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
944 [NAME=value ...] [target ...]\n");
945 exit(2);
946 }
947
948
949