I found a Windows32 issue in $(shell): with an MSYS2/Cygwin binary, a literal "
inside single quotes can deadlock make.
Minimal reproducer:
_ := $(shell grep '"' Makefile)
With GNU Make 4.4.1 (ezwinports, Built for Windows32), SHELL set to
Git-for-Windows sh.exe, and grep from Git-for-Windows/MSYS2, running make hangs
indefinitely.
This should be a trivial self-search, but grep never receives the file argument
and waits on stdin instead.
The apparent cause is:
1. construct_command_argv_internal() takes
grep '"' Makefile
on the fast path and builds argv = {"grep", "\"", "Makefile"}.
2. make_command_line() then prepares a CreateProcess command line using MSVCRT
quoting rules, so the literal " becomes \".
3. MSYS2/Cygwin programs do not parse CreateProcess command lines with MSVCRT
rules; they treat \" as a backslash plus the start of a quoted string, so the
file path is absorbed into the previous argument.
At that point grep sees no file operands, falls back to stdin, and the pipe
deadlocks.
This looks like a design limitation in the Windows fast path: it assumes
MSVCRT-compatible argv parsing, but that assumption is false for a significant
class of Windows executables.
Suggested fix: on WINDOWS32, if the fast path sees a literal " inside a
single-quoted string, fall back to the slow path and invoke via $(SHELL). That
should be low-cost and avoids the runtime-specific quoting mismatch.
Suggested diff below. I wrote it from source reading rather than from a local
clone; the context in src/job.c should still be unique.
--- a/src/job.c
+++ b/src/job.c
@@ in construct_command_argv_internal(), inside the if (instring) block @@
else if (instring == '"' && strncmp (p, "\\\"", 2) == 0)
*ap++ = *++p;
#endif
+#ifdef WINDOWS32
+ else if (instring == '\'' && *p == '"')
+ goto slow;
+#endif
else
*ap++ = *p;
}
Environment:
Make: GNU Make 4.4.1, Built for Windows32 (ezwinports)
Shell: Git-for-Windows sh.exe
grep: Git-for-Windows grep.exe (msys-2.0.dll)
OS: Windows 10/11
I am not planning to sign the FSF Copyright Assignment for this one-time
contribution. The diff above is only a suggested fix direction; please feel
free to reimplement it independently if you agree with the approach.