https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110710

peter0x44 at disroot dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |peter0x44 at disroot dot org

--- Comment #7 from peter0x44 at disroot dot org ---
The way make works is it prefers using an sh.exe if it finds it on the PATH.

https://git.savannah.gnu.org/cgit/make.git/tree/src/variable.c#n1637
(see variable.c of GNU make)

Otherwise, cmd.exe is used. This is probably why many people don't notice, as
most "mingw" environments do have this. But "mingw" does not imply "has an
sh.exe shell". You can totally add gcc to your cmd.exe PATH and use it fine,
and you can also write Makefiles with GNU Make that expect to use cmd.exe to
execute their build rules.

If GCC's generated temporary Makefiles expect to run under a "posix sh" always,
I believe they should have on the first line:

SHELL = /bin/sh

For a workaround, I would recommend busybox-w32. It's what w64devkit uses.
You can just put it on your PATH and see if it solves that issue.

It's what w64devkit uses, and I have used `-flto=auto` with it successfully
before.

As for actually reviewing this issue in the generated Makefiles, there are a
few approaches that can be used.

One of them it to utilize a "polyglot test" to tell which shell the build rules
are being executed under.

Something like:

SHELLTYPE := posix
ifeq ($(shell echo "test", "test"))
    SHELLTYPE := cmd
endif

This works because cmd.exe's echo command writes quotes.
under cmd.exe echo "test" will write:
"test"
and under a posix:
test (without quotes)

Then, the Makefile can later do something like:
ifeq (posix, $(SHELLTYPE))
    gcc whatever.c 2>/dev/null
else
    gcc whatever.c 2>NUL
endif

Now, this is an enormous HACK, but it worked okay in some cases, for me.
I implemented it in a different Makefile generating project here:
https://github.com/premake/premake-core/pull/2039

But is probably a terrible idea for GCC, since I believe ifeq is a GNU Make
extension. So is $(shell), afaik. I'm only presenting this option for
completeness.

I think the better solution for this case would be for --host=*-w64-mingw32,
write out Makefiles with:

SHELL = cmd
and then proceed to use all the cmd.exe shell equivalents, like 2>NUL, move
instead of mv, etc.

I've spent quite a bit of time before thinking and exploring this particular
"problem space", so it's just my analysis here. Unfortunately, I think there
are no "nice" ways to solve this problem.

Reply via email to