Re: How to choose the shell?

John Freeman <[email protected]> Sat, 4 Sep 2021 11:33:01 -0500
Newsgroups gmane.comp.gnu.make.windows
Message-ID <CANm+4TWC3Md5w0QaHV+aL0=JVUMKALvf8CwZkL5sVo04ArLbew@mail.gmail.com>
--000000000000dad32f05cb2df83c
Content-Type: text/plain; charset="UTF-8"

On Sat, Sep 4, 2021 at 10:46 AM Eli Zaretskii <[email protected]> wrote:

> 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?
>

I was under the (correct) impression that environment variables are
case-insensitive on Windows, but I went through this extra trouble just to
prove that case-sensitivity was not a factor in this behavior that deviates
from the [documented behavior](
https://www.gnu.org/software/make/manual/html_node/Choosing-the-Shell.html#Choosing-the-Shell).
The documentation says it will use the shell passed as `COMSPEC`, but it
didn't. We now both realize that it might have if it actually "invok[ed] a
new sub-shell for each line of the recipe" like it [said it would](
https://www.gnu.org/software/make/manual/html_node/Execution.html#Execution
).

--000000000000dad32f05cb2df83c
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr">On Sat, Sep 4, 2021 at 10:46 AM Eli Zaret=
skii &lt;<a href=3D"mailto:[email protected]">[email protected]</a>&gt; wrote:<br></d=
iv><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex">
GNU Make avoids calling the shell for commands that don&#39;t require any<b=
r>
shell functionality it knows about.=C2=A0 This is how GNU Make works on all=
<br>
platforms, and the Windows port doesn&#39;t change that.=C2=A0 So if you do=
n&#39;t<br>
have ls.exe or ls.bat or ls.cmd somewhere on Path, the above is<br>
expected, regardless of the value of SHELL in the Makefile.=C2=A0 (You can<=
br>
see from the error message that it tried to invoke &#39;ls&#39;; the shell =
is<br>
nowhere in the call it shows that failed.)<br>
<br>
To trigger the use of a shell, you need to use some feature on the<br>
command line that needs a shell.=C2=A0 For example, redirection or some<br>
fancy quoting.<br></blockquote><div><br></div><div>I have since discovered =
[this thread](<a href=3D"https://lists.gnu.org/archive/html/make-w32/2020-0=
5/msg00001.html">https://lists.gnu.org/archive/html/make-w32/2020-05/msg000=
01.html</a>), the very previous thread on this mailing list, working throug=
h the exact same problem. I&#39;m happy that there is a workaround, but thi=
s seems to me like undocumented behavior. It is not mentioned anywhere in t=
he [pages](<a href=3D"https://www.gnu.org/software/make/manual/html_node/Ex=
ecution.html#Execution">https://www.gnu.org/software/make/manual/html_node/=
Execution.html#Execution</a>) on Recipe Execution. One might argue that the=
 parenthetical statement &quot;(In practice, <code>make</code> may
take shortcuts that do not affect the results.)&quot; implies this behavior=
, but I think we can see that this behavior _does_ affect the results. At t=
he very least, I think this behavior should be explicitly documented. Perha=
ps a footnote?<br></div><div><br></div><div>My preference would be to have =
some other workaround that doesn&#39;t require me to modify every recipe li=
ne, e.g. a special variable `.FORCE_SHELL`.<br></div><div>=C2=A0<br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex">
&gt; - I can see that `ComSpec` is set in my default environment. In PowerS=
hell, I can read it as `$env:ComSpec<br>
&gt; ` or `$env:COMSPEC`, but in a Makefile, it is only available as `${Com=
Spec}`. If I remove and re-add the<br>
&gt; variable under the name `$env:COMSPEC`, it becomes available in the Ma=
kefile as `${COMSPEC}`, but I<br>
&gt; still get the same error from the `ls` recipe.<br>
<br>
I&#39;m not sure I understand why you think this is a problem.<br>
Environment variables are case-insensitive on MS-Windows, so why does<br>
it matter whether you have ComSpec or COMSPEC?<br></blockquote><div><br></d=
iv><div>I was under the (correct) impression that environment variables are=
 case-insensitive on Windows, but I went through this extra trouble just to=
 prove that case-sensitivity was not a factor in this behavior that deviate=
s from the [documented behavior](<a href=3D"https://www.gnu.org/software/ma=
ke/manual/html_node/Choosing-the-Shell.html#Choosing-the-Shell">https://www=
.gnu.org/software/make/manual/html_node/Choosing-the-Shell.html#Choosing-th=
e-Shell</a>). The documentation says it will use the shell passed as `COMSP=
EC`, but it didn&#39;t. We now both realize that it might have if it actual=
ly &quot;invok[ed] a new sub-shell for each line of the recipe&quot; like i=
t [said it would](<a href=3D"https://www.gnu.org/software/make/manual/html_=
node/Execution.html#Execution">https://www.gnu.org/software/make/manual/htm=
l_node/Execution.html#Execution</a>).</div></div></div>

--000000000000dad32f05cb2df83c--