tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

make: warn about fallback from parallel to compat mode



Currently, the following make target is broken in parallel mode:

broken-target:
	${MAKEDIRTARGET} subdir subdir-target1 subdir-target2

The reason is that the target (indirectly) runs a sub-make, but the
sub-make does not coordinate the number of running jobs with the main
make process. This may lead to more than the desired jobs running in
parallel, or to only a single job.

The cause for this is that the target is neither marked with ".MAKE" nor
does one of its unexpanded commands contain the magic word "make" or the
expression "${MAKE}".

The attached patch warns about cases like this. The warning is quite
verbose, but I didn't manage to make it shorter without sacrificing
understandability.

Thoughts, alternatives, remarks?
--- a/unit-tests/opt-jobs-internal.mk	(revision a2a46556f54bcbb82223a222a5bb71b1fa358893)
+++ b/unit-tests/opt-jobs-internal.mk	(date 1747017944715)
@@ -21,7 +21,7 @@
 	@mode=parallel
 	@echo ${.TARGET}: mode=$${mode:-compat}
 
-# expect: make: error: invalid internal option "-J garbage"
+# expect: make: error: invalid internal option "-J garbage" in <curdir>
 direct-syntax: .PHONY
 	@${MAKE} -f ${MAKEFILE} -J garbage unexpected-target || :
 

--- a/unit-tests/opt-jobs-internal.exp	(revision a2a46556f54bcbb82223a222a5bb71b1fa358893)
+++ b/unit-tests/opt-jobs-internal.exp	(date 1747017944705)
@@ -1,8 +1,17 @@
 direct: mode=parallel
-make: error: invalid internal option "-J garbage"
+make: error: invalid internal option "-J garbage" in <curdir>
+make: warning: internal option "-J 31,32" in <curdir> refers to an unopened file descriptor; falling back to compat mode.
+	If the target is supposed to recurse even with -n, add the .MAKE pseudo-source to the target.
+	Otherwise, add a ${:D make} marker to a command from the target. This marker expands to an empty string but has the side effect of passing the file descriptors to the sub-make.
 direct-open: mode=compat
+make: warning: internal option "-J 15,16" in <curdir> refers to an unopened file descriptor; falling back to compat mode.
+	If the target is supposed to recurse even with -n, add the .MAKE pseudo-source to the target.
+	Otherwise, add a ${:D make} marker to a command from the target. This marker expands to an empty string but has the side effect of passing the file descriptors to the sub-make.
 indirect-open: mode=compat
 indirect-expr: mode=parallel
+make: warning: internal option "-J 15,16" in <curdir> refers to an unopened file descriptor; falling back to compat mode.
+	If the target is supposed to recurse even with -n, add the .MAKE pseudo-source to the target.
+	Otherwise, add a ${:D make} marker to a command from the target. This marker expands to an empty string but has the side effect of passing the file descriptors to the sub-make.
 indirect-comment: mode=compat
 indirect-silent-comment: mode=parallel
 indirect-expr-empty: mode=parallel

--- a/main.c	(revision a2a46556f54bcbb82223a222a5bb71b1fa358893)
+++ b/main.c	(date 1747074889583)
@@ -379,8 +379,8 @@
 	if (sscanf(argvalue, "%d,%d%c",
 	    &tokenPoolReader, &tokenPoolWriter, &end) != 2) {
 		(void)fprintf(stderr,
-		    "%s: error: invalid internal option \"-J %s\"\n",
-		    progname, argvalue);
+		    "%s: error: invalid internal option \"-J %s\" in %s\n",
+		    progname, argvalue, curdir);
 		exit(2);
 	}
 	if ((fcntl(tokenPoolReader, F_GETFD, 0) < 0) ||
@@ -388,6 +388,20 @@
 		tokenPoolReader = -1;
 		tokenPoolWriter = -1;
 		opts.compatMake = true;
+		(void)fprintf(stderr,
+		    "%s: warning: internal option \"-J %s\" in %s "
+		    "refers to an unopened file descriptor; "
+		    "falling back to compat mode.\n"
+		    "\t"
+		    "If the target is supposed to recurse even with -n, "
+		    "add the .MAKE pseudo-source to the target.\n"
+		    "\t"
+		    "Otherwise, add a ${:D make} marker to a command "
+		    "from the target. "
+		    "This marker expands to an empty string but has the "
+		    "side effect of passing the file descriptors to the "
+		    "sub-make.\n",
+		    progname, argvalue, curdir);
 	} else {
 		Global_Append(MAKEFLAGS, "-J");
 		Global_Append(MAKEFLAGS, argvalue);
@@ -1421,18 +1435,18 @@
 #endif
 	Dir_Init();
 
-	{
-		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);
 	}
 
+	{
+		char *makeflags = explode(getenv("MAKEFLAGS"));
+		Main_ParseArgLine(makeflags);
+		free(makeflags);
+	}
+
 	MainParseArgs(argc, argv);
 
 	if (opts.enterFlag)


Home | Main Index | Thread Index | Old Index