GNU Make avoids calling the shell for commands that don't require any
shell functionality it knows about. This is how GNU Make works on all
platforms, and the Windows port doesn't change that. So if you don't
have ls.exe or ls.bat or ls.cmd somewhere on Path, the above is
expected, regardless of the value of SHELL in the Makefile. (You can
see from the error message that it tried to invoke 'ls'; the shell is
nowhere in the call it shows that failed.)
To trigger the use of a shell, you need to use some feature on the
command line that needs a shell. For example, redirection or some
fancy quoting.
I have since discovered [this thread](
https://lists.gnu.org/archive/html/make-w32/2020-05/msg00001.html), the very previous thread on this mailing list, working through the exact same problem. I'm happy that there is a workaround, but this seems to me like undocumented behavior. It is not mentioned anywhere in the [pages](
https://www.gnu.org/software/make/manual/html_node/Execution.html#Execution) on Recipe Execution. One might argue that the parenthetical statement "(In practice,
make
may
take shortcuts that do not affect the results.)" implies this behavior, but I think we can see that this behavior _does_ affect the results. At the very least, I think this behavior should be explicitly documented. Perhaps a footnote?
My preference would be to have some other workaround that doesn't require me to modify every recipe line, e.g. a special variable `.FORCE_SHELL`.
> - I can see that `ComSpec` is set in my default environment. In PowerShell, I can read it as `$env:ComSpec
> ` or `$env:COMSPEC`, but in a Makefile, it is only available as `${ComSpec}`. If I remove and re-add the
> variable under the name `$env:COMSPEC`, it becomes available in the Makefile as `${COMSPEC}`, but I
> still get the same error from the `ls` recipe.
I'm not sure I understand why you think this is a problem.
Environment variables are case-insensitive on MS-Windows, so why does
it matter whether you have ComSpec or COMSPEC?