diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 152 |
1 files changed, 83 insertions, 69 deletions
@@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.641 2025/03/31 14:35:22 riastradh Exp $ */ +/* $NetBSD: main.c,v 1.659 2025/06/13 05:41:36 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -104,11 +104,14 @@ #include "make.h" #include "dir.h" #include "job.h" +#ifdef USE_META +# include "meta.h" +#endif #include "pathnames.h" #include "trace.h" /* "@(#)main.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: main.c,v 1.641 2025/03/31 14:35:22 riastradh Exp $"); +MAKE_RCSID("$NetBSD: main.c,v 1.659 2025/06/13 05:41:36 rillig Exp $"); #if defined(MAKE_NATIVE) __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 " "The Regents of the University of California. " @@ -127,8 +130,9 @@ bool deleteOnError; /* .DELETE_ON_ERROR: set */ static int maxJobTokens; /* -j argument */ static bool enterFlagObj; /* -w and objdir != srcdir */ +static bool bogusJflag; /* -J invalid */ -static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */ +static int tokenPoolReader = -1, tokenPoolWriter = -1; bool doing_depend; /* Set while reading .depend */ static bool jobsRunning; /* true if the jobs might be running */ static const char *tracefile; @@ -361,7 +365,8 @@ MainParseArgChdir(const char *argvalue) exit(2); /* Not 1 so -q can distinguish error */ } if (getcwd(curdir, MAXPATHLEN) == NULL) { - (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); + (void)fprintf(stderr, "%s: getcwd: %s\n", + progname, strerror(errno)); exit(2); } if (!IsRelativePath(argvalue) && @@ -377,17 +382,19 @@ static void MainParseArgJobsInternal(const char *argvalue) { char end; - if (sscanf(argvalue, "%d,%d%c", &jp_0, &jp_1, &end) != 2) { + if (sscanf(argvalue, "%d,%d%c", + &tokenPoolReader, &tokenPoolWriter, &end) != 2) { (void)fprintf(stderr, - "%s: internal error -- J option malformed (%s)\n", - progname, argvalue); - usage(); + "%s: error: invalid internal option " + "\"-J %s\" in \"%s\"\n", + progname, argvalue, curdir); + exit(2); } - if ((fcntl(jp_0, F_GETFD, 0) < 0) || - (fcntl(jp_1, F_GETFD, 0) < 0)) { - jp_0 = -1; - jp_1 = -1; - opts.compatMake = true; + if ((fcntl(tokenPoolReader, F_GETFD, 0) < 0) || + (fcntl(tokenPoolWriter, F_GETFD, 0) < 0)) { + tokenPoolReader = -1; + tokenPoolWriter = -1; + bogusJflag = true; } else { Global_Append(MAKEFLAGS, "-J"); Global_Append(MAKEFLAGS, argvalue); @@ -708,7 +715,9 @@ Main_ParseArgLine(const char *line) return; } free(buf); + EvalStack_PushMakeflags(line); MainParseArgs((int)words.len, words.words); + EvalStack_Pop(); Words_Free(words); } @@ -738,7 +747,7 @@ Main_SetObjdir(bool writable, const char *fmt, ...) return false; if ((writable && access(path, W_OK) != 0) || chdir(path) != 0) { - (void)fprintf(stderr, "%s: warning: %s: %s.\n", + (void)fprintf(stderr, "%s: warning: %s: %s\n", progname, path, strerror(errno)); /* Allow debugging how we got here - not always obvious */ if (GetBooleanExpr("${MAKE_DEBUG_OBJDIR_CHECK_WRITABLE}", @@ -828,7 +837,7 @@ MakeMode(void) } static void -PrintVar(const char *varname, bool expandVars) +PrintVariable(const char *varname, bool expandVars) { if (strchr(varname, '$') != NULL) { char *evalue = Var_Subst(varname, SCOPE_GLOBAL, VARE_EVAL); @@ -872,7 +881,7 @@ GetBooleanExpr(const char *expr, bool fallback) } static void -doPrintVars(void) +PrintVariables(void) { StringListNode *ln; bool expandVars; @@ -885,49 +894,33 @@ doPrintVars(void) expandVars = GetBooleanExpr("${.MAKE.EXPAND_VARIABLES}", false); - for (ln = opts.variables.first; ln != NULL; ln = ln->next) { - const char *varname = ln->datum; - PrintVar(varname, expandVars); - } + for (ln = opts.variables.first; ln != NULL; ln = ln->next) + PrintVariable(ln->datum, expandVars); } static bool -runTargets(void) +MakeTargets(void) { - GNodeList targs = LST_INIT; /* target nodes to create */ + GNodeList targets = LST_INIT; bool outOfDate; /* false if all targets up to date */ - /* - * Have now read the entire graph and need to make a list of - * targets to create. If none was given on the command line, - * we consult the parsing module to find the main target(s) - * to create. - */ if (Lst_IsEmpty(&opts.create)) - Parse_MainName(&targs); + Parse_MainName(&targets); else - Targ_FindList(&targs, &opts.create); + Targ_FindList(&targets, &opts.create); if (!opts.compatMake) { - /* - * Initialize job module before traversing the graph - * now that any .BEGIN and .END targets have been read. - * This is done only if the -q flag wasn't given - * (to prevent the .BEGIN from being executed should - * it exist). - */ if (!opts.query) { Job_Init(); jobsRunning = true; } - /* Traverse the graph, checking on all the targets */ - outOfDate = Make_Run(&targs); + outOfDate = Make_MakeParallel(&targets); } else { - Compat_MakeAll(&targs); + Compat_MakeAll(&targets); outOfDate = false; } - Lst_Done(&targs); /* Don't free the targets themselves. */ + Lst_Done(&targets); /* Don't free the targets themselves. */ return outOfDate; } @@ -958,7 +951,7 @@ InitRandom(void) struct timeval tv; gettimeofday(&tv, NULL); - srandom((unsigned int)(tv.tv_sec + tv.tv_usec)); + srandom((unsigned)(tv.tv_sec + tv.tv_usec)); } static const char * @@ -999,9 +992,9 @@ InitVarMachineArch(void) const int mib[2] = { CTL_HW, HW_MACHINE_ARCH }; size_t len = sizeof machine_arch_buf; - if (sysctl(mib, (unsigned int)__arraycount(mib), + if (sysctl(mib, (unsigned)__arraycount(mib), machine_arch_buf, &len, NULL, 0) < 0) { - (void)fprintf(stderr, "%s: sysctl failed (%s).\n", + (void)fprintf(stderr, "%s: sysctl: %s\n", progname, strerror(errno)); exit(2); } @@ -1225,6 +1218,30 @@ InitMaxJobs(void) char *value; int n; + if (bogusJflag && !opts.compatMake) { + opts.compatMake = true; + Parse_Error(PARSE_WARNING, + "internal option \"-J\" in \"%s\" " + "refers to unopened file descriptors; " + "falling back to compat mode.\n" + "\t" + "To run the target even in -n mode, " + "add the .MAKE pseudo-source to the target.\n" + "\t" + "To run the target in default mode only, " + "add a ${:D make} marker to a target's command. " + "(This marker expression expands to an empty string.)\n" + "\t" + "To make the sub-make run in compat mode, add -B to " + "its invocation.\n" + "\t" + "To make the sub-make independent from the parent make, " + "unset the MAKEFLAGS environment variable in the " + "target's commands.", + curdir); + PrintStackTrace(true); + return; + } if (forceJobs || opts.compatMake || !Var_Exists(SCOPE_GLOBAL, ".MAKE.JOBS")) return; @@ -1345,7 +1362,7 @@ main_Init(int argc, char **argv) UnlimitFiles(); if (uname(&utsname) == -1) { - (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, + (void)fprintf(stderr, "%s: uname: %s\n", progname, strerror(errno)); exit(2); } @@ -1353,7 +1370,7 @@ main_Init(int argc, char **argv) machine = InitVarMachine(&utsname); machine_arch = InitVarMachineArch(); - myPid = getpid(); /* remember this for vFork() */ + myPid = getpid(); /* Just in case MAKEOBJDIR wants us to do something tricky. */ Targ_Init(); @@ -1439,25 +1456,25 @@ main_Init(int argc, char **argv) #endif Dir_Init(); + if (getcwd(curdir, MAXPATHLEN) == NULL) { + (void)fprintf(stderr, "%s: getcwd: %s\n", + progname, strerror(errno)); + exit(2); + } + { char *makeflags = explode(getenv("MAKEFLAGS")); Main_ParseArgLine(makeflags); free(makeflags); } - if (getcwd(curdir, MAXPATHLEN) == NULL) { - (void)fprintf(stderr, "%s: getcwd: %s.\n", - progname, strerror(errno)); - exit(2); - } - MainParseArgs(argc, argv); if (opts.enterFlag) printf("%s: Entering directory `%s'\n", progname, curdir); if (stat(curdir, &sa) == -1) { - (void)fprintf(stderr, "%s: %s: %s.\n", + (void)fprintf(stderr, "%s: stat %s: %s\n", progname, curdir, strerror(errno)); exit(2); } @@ -1538,9 +1555,10 @@ main_PrepareMaking(void) opts.compatMake = true; if (!opts.compatMake) - Job_ServerStart(maxJobTokens, jp_0, jp_1); + TokenPool_Init(maxJobTokens, tokenPoolReader, tokenPoolWriter); DEBUG5(JOB, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n", - jp_0, jp_1, opts.maxJobs, maxJobTokens, opts.compatMake ? 1 : 0); + tokenPoolReader, tokenPoolWriter, opts.maxJobs, maxJobTokens, + opts.compatMake ? 1 : 0); if (opts.printVars == PVM_NONE) Main_ExportMAKEFLAGS(true); /* initial export */ @@ -1564,20 +1582,17 @@ main_PrepareMaking(void) } /* - * Make the targets. - * If the -v or -V options are given, print variables instead. + * Make the targets, or print variables. * Return whether any of the targets is out-of-date. */ static bool main_Run(void) { if (opts.printVars != PVM_NONE) { - /* print the values of any variables requested by the user */ - doPrintVars(); + PrintVariables(); return false; - } else { - return runTargets(); - } + } else + return MakeTargets(); } /* Clean up after making the targets. */ @@ -1620,9 +1635,8 @@ main_CleanUp(void) #endif } -/* Determine the exit code. */ static int -main_Exit(bool outOfDate) +main_ExitCode(bool outOfDate) { if ((opts.strict && main_errors > 0) || parseErrors > 0) return 2; /* Not 1 so -q can distinguish error */ @@ -1639,7 +1653,7 @@ main(int argc, char **argv) main_PrepareMaking(); outOfDate = main_Run(); main_CleanUp(); - return main_Exit(outOfDate); + return main_ExitCode(outOfDate); } /* @@ -1798,6 +1812,7 @@ Cmd_Exec(const char *cmd, char **error) } Var_ReexportVars(SCOPE_GLOBAL); + Var_ExportStackTrace(NULL, cmd); switch (cpid = FORK_FUNCTION()) { case 0: @@ -2002,7 +2017,7 @@ execDie(const char *func, const char *arg) char msg[1024]; int len; - len = snprintf(msg, sizeof(msg), "%s: %s(%s) failed (%s)\n", + len = snprintf(msg, sizeof(msg), "%s: %s(%s): %s\n", progname, func, arg, strerror(errno)); write_all(STDERR_FILENO, msg, (size_t)len); _exit(1); @@ -2218,7 +2233,7 @@ mkTempFile(const char *pattern, char *tfile, size_t tfile_sz) int fd; if (pattern == NULL) - pattern = TMPPAT; + pattern = "makeXXXXXX"; if (tmpdir == NULL) tmpdir = getTmpdir(); if (tfile == NULL) { @@ -2232,8 +2247,7 @@ mkTempFile(const char *pattern, char *tfile, size_t tfile_sz) snprintf(tfile, tfile_sz, "%s%s", tmpdir, pattern); if ((fd = mkstemp(tfile)) < 0) - Punt("Could not create temporary file %s: %s", tfile, - strerror(errno)); + Punt("mkstemp %s: %s", tfile, strerror(errno)); if (tfile == tbuf) unlink(tfile); /* we just want the descriptor */ |
