> 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).

Reply via email to