summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c152
1 files changed, 83 insertions, 69 deletions
diff --git a/main.c b/main.c
index 3f0da61caf1d..d020ba85f16b 100644
--- a/main.c
+++ b/main.c
@@ -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 */