> From: 张 天夫 <[email protected]> > Date: Sat, 4 Apr 2026 06:35:47 +0000 > > 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.
Thanks for the analysis. The root cause here is that the native Windows port of GNU Make doesn't support Cygwin and MSYS2 ports of Bash, precisely because they interpret the command line differently. If you need to use Bash from Make (as opposed to the Windows-native cmd.exe), I suggest that you use Cygwin or MSYS2 build of Make as well. > 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. That's the assumption, indeed, and there was never the intent to support Cygwin/MSYS2 shell from the native port of Make. At the time, there were a couple of ports of Bash which used the MS runtime, and those are the ones the native port of Make supports. (They are by now all but extinct, unfortunately: crash and burn or don't work at all on modern versions of Windows, due to the tricks they played to implement fork/exec.) > 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. Thanks, but I don't want to do this, because it basically makes the fast path much slower when a double quote is inside single-quoted string. This is a step in the wrong direction, because the fast path should be preferred. Once again, if using the Cygwin or MSYS2 Bash is required, my recommendation is to use the Cygwin/MSYS2 port of Make. You will have much fewer potential compatibility problems that way, because native programs and Cygwin/MSYS2 programs are subtly incompatible (they use very different runtime libraries).
