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