How do I use mingw and msys2 shells?

Hello,

I have successfully installed msys2 via choco install -y msys2 and it is installed to C:\tools\msys64 but I am unsure of the way to invoke the mingw and msys2 shells in order to run its commands such as installing packages using pacman and using them.

I have tried to use C:\tools\msys64\usr\bin\bash -lc 'COMMAND' but i hit fatal error - cygheap base mismatch detected.. Is this the correct way and that I should try and fix this error?

Thank you for the help!

2 Likes

Starting off by saying I barely know what I’m talking about here, anyone feel free to come correct me.

It seems that trying to launch the MSYS2 bash from inside Travis’ provided git bash does not work, because they are both cygwin based and use different versions of the dll (or something like that, basically you’re loading a cygwin environment when you’re already inside one, and it doesn’t work).

I have had luck by running bash -lc '...' from powershell. So basically I just include a powershell script in my repo and run it with powershell -executionpolicy bypass -file script.ps1. All it does is install some additional MSYS2 dependencies and run make.

1 Like

I did this like:

/c/tools/msys64/msys2_shell.cmd -defterm -mingw64 -no-start -full-path -here -c 'COMMAND'

and it seemed to work. (There are other unrelated errors, though.)

UPDATE: The above does not reload PATH from the Registry after Chocolatey has modified it during package installation. To do this interactively from a Git Bash window you’d need to run RefreshEnv.cmd beforehand, like:

cmd.exe //C "RefreshEnv.cmd & C:/tools/msys64/msys2_shell.cmd" -defterm -mingw64 -no-start -full-path -here -c "COMMAND"

However, I encountered issues when setting the above to a wrapper $shell environment variable for my job. The following eventually worked:

- export shell="cmd.exe //C RefreshEnv.cmd & C:/tools/msys64/msys2_shell.cmd -defterm -mingw64 -no-start -full-path -here -c"
- $shell COMMAND

But if your command needs arguments, that won’t work either. You’ll then need:

- export shell="cmd.exe //C RefreshEnv.cmd & C:/tools/msys64/msys2_shell.cmd -defterm -mingw64 -no-start -full-path -here -c \$\* --"
- $shell COMMAND ARG1 ARG2 ...

Final version working here.

1 Like

@tanzislam Does your solution work when the arguments need to be quoted? I am currently attempting the same thing but one of the arguments is "(progn (ccl:rebuild-ccl :full t) (ccl:quit))" and this seems to cause the shell to behave oddly.

@phoe I didn’t need it for my use case, and it most likely wouldn’t work as-is. It will be difficult to make it work as you’re fighting against the expansion behaviors of 2 (or 3, depending on how you count) different shells (Git Bash, cmd.exe, and MSYS2’s Bash), so I suppose an easier way would be to prepare a wrapper script around your command/arguments/redirections/pipelines/etc. and run that instead.

@tanzislam This is exactly the way I have worked around it - by dumping the quoted command to a file and invoking that instead. Thanks.

@phoe This may be a problem with msys2_shell.cmd acting on any metacharacters in the last part of the command string (the bit that it is supposed to pass on to Bash). The latest commit in my pull request should fix it.

There’s now official guidance on using MinGW and MSYS2: