cmdliner icon indicating copy to clipboard operation
cmdliner copied to clipboard

Add `.exe` extension to cmdliner tool on Windows

Open MisterDA opened this issue 1 month ago • 13 comments

This fixes new build failures reported in #233:

cmdliner.2.0.0:

ocaml build.ml cma
ocaml build.ml cmxa
ocaml build.ml natexe
_build/src/tool/cmdliner generic-completion bash > _build/src/tool/bash-completion.sh
_build/src/tool/cmdliner tool-completion bash cmdliner > _build/src/tool/bash-cmdliner.sh
_build/src/tool/cmdliner generic-completion zsh > _build/src/tool/zsh-completion.sh
_build/src/tool/cmdliner tool-completion zsh cmdliner > _build/src/tool/zsh-cmdliner.sh
_build/src/tool/cmdliner install tool-manpages _build/src/tool/cmdliner _build/src/tool/man
'"_build\src\tool\cmdliner"' is not recognized as an internal or external command,
operable program or batch file.
""_build\src\tool\cmdliner" "--__complete" "--__complete=" > "C:\Users\misterda\AppData\Local\opam\.cygwin\root\tmp\cmd9740adstdout"": exited with 1
make: *** [Makefile:80: build-man] Error 123

cmdliner.2.1.0:

ocaml build.ml cma
ocaml build.ml cmxa
ocaml build.ml natexe
_build/src/tool/cmdliner generic-completion bash > _build/src/tool/bash-completion.sh
_build/src/tool/cmdliner tool-completion bash cmdliner > _build/src/tool/bash-cmdliner.sh
_build/src/tool/cmdliner generic-completion zsh > _build/src/tool/zsh-completion.sh
_build/src/tool/cmdliner tool-completion zsh cmdliner > _build/src/tool/zsh-cmdliner.sh
_build/src/tool/cmdliner generic-completion pwsh > _build/src/tool/pwsh-completion.ps1
_build/src/tool/cmdliner tool-completion pwsh cmdliner > _build/src/tool/pwsh-cmdliner.ps1
_build/src/tool/cmdliner install tool-manpages _build/src/tool/cmdliner _build/src/tool/man
'"_build\src\tool\cmdliner"' is not recognized as an internal or external command,
operable program or batch file.
""_build\src\tool\cmdliner" "--__complete" "--__complete=" > "C:\Users\misterda\AppData\Local\opam\.cygwin\root\tmp\cmd735a8astdout"": exited with 1
make: *** [Makefile:83: build-man] Error 123

I would enjoy a patch release with this fix.

MisterDA avatar Nov 26 '25 09:11 MisterDA

Do you understand why the extension matters?

nojb avatar Nov 26 '25 10:11 nojb

The cmd uses the registry to associate loaders with file types. See assoc and ftype.

> assoc .exe
.exe=exefile
> ftype exefile
exefile="%1" %*

There's also the PATHEXT environment variable that comes into play.

PATHEXT is used to start a program, batch file or script without explicitly specifying its suffix in cmd.exe or its start command.

.com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc

So if the file ends in .exe and PATHEXT contains .exe then the executable can be started in cmd without specifying the extension, but the real filename still need to have it, otherwise the cmd doesn't know it's an executable.

It's a bit vague…

MisterDA avatar Nov 26 '25 11:11 MisterDA

@MisterDA just to rule out something in your environment, can you try reproducing by calling the command in question directly from cmd.exe ? (ie execute cmd.exe /C ""_build\src\tool\cmdliner ...."" in cmd.exe)

nojb avatar Nov 26 '25 16:11 nojb

@MisterDA just to rule out something in your environment, can you try reproducing by calling the command in question directly from cmd.exe ? (ie execute cmd.exe /C ""_build\src\tool\cmdliner ...."" in cmd.exe)

Same error. I do have clink 1.9.2 installed on my cmd.

The error seems to be repeatable on any executable, though:

> cat main.c
#include <stdio.h>
int main(void) {
  printf("Hello, world!\n");
  return 0;
}
> cl -nologo -W4 -O2 main.c
main.c
> .\main.exe
Hello, world!
> mv .\main.exe .\main
> .\main
'.\main' is not recognized as an internal or external command,
operable program or batch file.

MisterDA avatar Nov 26 '25 17:11 MisterDA

Do you get the error with all commands? eg cmd.exe /C ""foo\bar"" where foo/bar.exe exists?

nojb avatar Nov 26 '25 20:11 nojb

Do you get the error with all commands? eg cmd.exe /C ""foo\bar"" where foo/bar.exe exists?

If test\main.exe exists, calling it both with and without .exe succeeds, because .exe is in PATHEXT.

> cmd.exe /C ""test\main.exe""
Hello, world!
> cmd.exe /C ""test\main""
Hello, world!

MisterDA avatar Nov 27 '25 09:11 MisterDA

because .exe is in PATHEXT.

Sorry, but is it the case that the executable _build\src\tool\cmdliner does not have the .exe extension on disk?

(Sorry for all the questions, but I cannot test locally right now.)

nojb avatar Nov 27 '25 09:11 nojb

Sorry, but is it the case that the executable _build\src\tool\cmdliner does not have the .exe extension on disk?

Yes! and my patch adds the .exe.

> git checkout v2.1.0
HEAD is now at dbd9b51 Restore OCaml 4.08 compatibility
> git clean -fdX
Removing _build/
> opam switch system-msvc
> C:\Users\misterda\AppData\Local\opam\.cygwin\root\bin\make.exe all -j1
ocaml build.ml cma
ocaml build.ml cmxa
ocaml build.ml natexe
_build/src/tool/cmdliner generic-completion bash > _build/src/tool/bash-completion.sh
_build/src/tool/cmdliner tool-completion bash cmdliner > _build/src/tool/bash-cmdliner.sh
_build/src/tool/cmdliner generic-completion zsh > _build/src/tool/zsh-completion.sh
_build/src/tool/cmdliner tool-completion zsh cmdliner > _build/src/tool/zsh-cmdliner.sh
_build/src/tool/cmdliner generic-completion pwsh > _build/src/tool/pwsh-completion.ps1
_build/src/tool/cmdliner tool-completion pwsh cmdliner > _build/src/tool/pwsh-cmdliner.ps1
_build/src/tool/cmdliner install tool-manpages _build/src/tool/cmdliner _build/src/tool/man
'"_build\src\tool\cmdliner"' is not recognized as an internal or external command,
operable program or batch file.
""_build\src\tool\cmdliner" "--__complete" "--__complete=" > "C:\Users\misterda\AppData\Local\Temp\cmd344836stdout"": exited with 1
make: *** [Makefile:83: build-man] Error 123
> dir _build\src\tool\
 Volume in drive C has no label.
 Volume Serial Number is 669D-C810

 Directory of C:\Users\misterda\Tarides\cmdliner\_build\src\tool

11/27/2025  09:19 AM    <DIR>          .
11/27/2025  09:19 AM    <DIR>          ..
11/27/2025  09:19 AM               133 bash-cmdliner.sh
11/27/2025  09:19 AM             2,774 bash-completion.sh
11/27/2025  09:19 AM         1,924,096 cmdliner
11/27/2025  09:19 AM               835 cmdliner_data.cmi
11/27/2025  09:19 AM            35,077 cmdliner_data.cmt
11/27/2025  09:19 AM            24,564 cmdliner_data.cmx
11/27/2025  09:19 AM            11,227 cmdliner_data.ml
11/27/2025  09:19 AM            28,546 cmdliner_data.obj
11/27/2025  09:19 AM            12,121 cmdliner_main.cmi
11/27/2025  09:19 AM           301,683 cmdliner_main.cmt
11/27/2025  09:19 AM             4,427 cmdliner_main.cmx
11/27/2025  09:19 AM            26,333 cmdliner_main.ml
11/27/2025  09:19 AM           114,333 cmdliner_main.obj
11/27/2025  09:19 AM                96 pwsh-cmdliner.ps1
11/27/2025  09:19 AM             5,547 pwsh-completion.ps1
11/27/2025  09:19 AM                63 zsh-cmdliner.sh
11/27/2025  09:19 AM             2,748 zsh-completion.sh
              17 File(s)      2,494,603 bytes
               2 Dir(s)  10,358,571,008 bytes free
> mklink _build\src\tool\cmdliner.exe cmdliner
symbolic link created for _build\src\tool\cmdliner.exe <<===>> cmdliner
> C:\Users\misterda\AppData\Local\opam\.cygwin\root\bin\make.exe all -j1
ocaml build.ml cma
ocaml build.ml cmxa
ocaml build.ml natexe
_build/src/tool/cmdliner generic-completion bash > _build/src/tool/bash-completion.sh
_build/src/tool/cmdliner tool-completion bash cmdliner > _build/src/tool/bash-cmdliner.sh
_build/src/tool/cmdliner generic-completion zsh > _build/src/tool/zsh-completion.sh
_build/src/tool/cmdliner tool-completion zsh cmdliner > _build/src/tool/zsh-cmdliner.sh
_build/src/tool/cmdliner generic-completion pwsh > _build/src/tool/pwsh-completion.ps1
_build/src/tool/cmdliner tool-completion pwsh cmdliner > _build/src/tool/pwsh-cmdliner.ps1
_build/src/tool/cmdliner install tool-manpages _build/src/tool/cmdliner _build/src/tool/man
Writing _build/src/tool/man\man1\cmdliner.1
Writing _build/src/tool/man\man1\cmdliner-generic-completion.1
Writing _build/src/tool/man\man1\cmdliner-install.1
Writing _build/src/tool/man\man1\cmdliner-install-generic-completion.1
Writing _build/src/tool/man\man1\cmdliner-install-tool-completion.1
Writing _build/src/tool/man\man1\cmdliner-install-tool-manpages.1
Writing _build/src/tool/man\man1\cmdliner-install-tool-support.1
Writing _build/src/tool/man\man1\cmdliner-tool-commands.1
Writing _build/src/tool/man\man1\cmdliner-tool-completion.1
ocaml build.ml cmxs

but I confirm that this only happens with a system-msvc switch and not with a system-mingw switch. With mingw, _build/src/tool/cmdliner.exe gets the .exe extension!

MisterDA avatar Nov 27 '25 09:11 MisterDA

With mingw, _build/src/tool/cmdliner.exe gets the .exe extension!

Just to make sure I understand: this means that the executable on disk has the .exe extension, or that Sys.command manages to execute the executable despite it not having the .exe extension?

nojb avatar Nov 27 '25 09:11 nojb

With system-mingw the executable on disk has the .exe extension, with system-msvc the executable on disk doesn't have the extension.

MisterDA avatar Nov 27 '25 10:11 MisterDA

With system-mingw the executable on disk has the .exe extension, with system-msvc the executable on disk doesn't have the extension.

I see. This is because gcc (from mingw-w64) automatically adds this extension, but cl does not. The fix is to always add the extension in the build system (when under Windows):

https://github.com/dbuenzli/cmdliner/blob/dbd9b51cb6dd4af6de11229f68a36cf455ae301e/build.ml#L145-L149

nojb avatar Nov 27 '25 10:11 nojb

This is because gcc (from mingw-w64) automatically adds this extension, but cl does not. The fix is to always add the extension in the build system (when under Windows):

I take that as an approval for this patch ;)

MisterDA avatar Nov 27 '25 11:11 MisterDA

This is because gcc (from mingw-w64) automatically adds this extension, but cl does not. The fix is to always add the extension in the build system (when under Windows):

I take that as an approval for this patch ;)

Indeed! (Sorry, I hadn't looked at the patch :))

nojb avatar Nov 27 '25 12:11 nojb