How to stop MinGW and MSYS from mangling path names given at the command line
Asked Answered
L

6

108

On Windows, I'm cross-compiling a program for ARM/Linux using CodeSourcery's cross-compiler suite. I use MinGW MSYS as my command interpreter, and very often it will mangle my paths and pathnames. For example, to build my program, I invoke

arm-none-linux-gnueabi-gcc.exe -Wall -g \
    -Wl,--dynamic-linker=/usr/lib/myrpath/ld-linux.so.3 \
    -Wl,-rpath=/usr/lib/myrpath \
    -I../targetsysroot/usr/include \
    myprogram.c -o myprogram

Of course, I want /usr/lib/myrpath inserted verbatim into the myprogram executable - the ARM Linux target I'm compiling for doesn't use MinGW or MSYS. But here's what ends up going into it:

...
0x0000000f (RPATH)            Library rpath: [C:/MinGW/msys/1.0/lib/myrpath]
...

Not exactly what I wanted. If I invoke GCC on the cmd.exe command line directly, I get the right rpath in the executable. If I invoke GCC on the MSYS command line, I get the mangled rpath. If I invoke GCC with a Makefile that is run with make from the cmd.exe command line, I still get a mangled rpath (!)

Any ideas how I might turn off this annoying behavior?

Libbey answered 30/8, 2011 at 21:37 Comment(1)
See also MSYS docs that explain the path conversion, and how to control what gets converted (especially the MSYS2_ARG_CONV_EXCL/MSYS2_ENV_CONV_EXCL for fine-grained control, but it doesn't mention total MSYS_NO_PATHCONV switch, so dear reader in the future - do a bit of research to see if it's compatible to your env)Ops
G
79

I just discovered a neat trick to avoid MSYS/MinGW translating the paths for you.

If you use double-slash to start the path, then MSYS won't translate the path to DOS format. So in OP's example, the -rpath switch should be specified like this:

-Wl,-rpath=//usr/lib/myrpath

All Unix/Linux tools seem to handle such spurious slashes without any problem, so even though your binary's rpath will start with //usr/... I think the loader will do the right thing.

Gourami answered 7/1, 2013 at 3:58 Comment(4)
It doesn't work for me but -rpath="//usr\lib\myrpath" does (with quotes and backslashes for path )Boondoggle
This only works when the thing with a / is actually a path.Splutter
i needed this to mount //var/run/docker.sock for Docker for Win + msys (git bash)Philology
how can I make this this work if the path is in a variable? -rpath=$myvar where content of myvar is /usr/lib/myrpath ? Need the script to work both on windows and linuxDilator
P
153

There is a way to suppress the path translation by setting MSYS_NO_PATHCONV=1 in Windows Git MSys or MSYS2_ARG_CONV_EXCL="*" in MSYS2.

Alternatively, you can set the variable only temporarily just for that command by putting the assignment just before the command itself:

MSYS_NO_PATHCONV=1 arm-none-linux-gnueabi-gcc.exe -Wall -g \
    -Wl,--dynamic-linker=/usr/lib/myrpath/ld-linux.so.3 \
    -Wl,-rpath=/usr/lib/myrpath \
    -I../targetsysroot/usr/include \
    myprogram.c -o myprogram
Pleuro answered 20/12, 2015 at 22:16 Comment(13)
This is incorrect. This was only added in Git for Window's fork of MSYS runtime and the MSYS_NO_PATHCONV variable is not recognized by the upstream version of MSYS: not 1.0, not MSYS2, not 32 nor 64 bit variants.Entopic
This is pretty great. I wish it was always available. Thanks for pointing it out.Calends
MSYS2_ARG_CONV_EXC="*" is accepted by the upstream MSYS2 and does the same though. It's documented sourceforge.net/p/msys2/wiki/Porting hereHarmaning
@Phyx: Based on the URL given, the environment variable would be MSYS2_ARG_CONV_EXCL versus MSYS2_ARG_CONV_EXC mentioned in your comment.Dragon
This worked for me when using git-bash and the command gpg-connect-agent "/bye" being misinterpreted and causing gpg agent to log: "C:/Program Files/Git/bye ERR 67109139 Unknown IPC command <GPG Agent>"Fuqua
@Dragon You are right: it is indeed MSYS2_ARG_CONV_EXCL. Thanks for this as it was driving me mad, trying to do a docker cpSpaceman
The only working way to use with "VBoxManage guestproperty set </some/string/with/slashes>" with msys-git bash. Double-slash(es) trick didn't work in this case, although worked in many others, non-vbox.Belloc
I normally run stuff inside windows terminal or conemu. I have tried setting these as env vars but it does nothing. Is there a way to do this outside the msys2 terminal?Cantara
Watch out if you're using MSYS2_ARG_CONV_EXCL="*" in a bash shell and you have globbing enabled! bash will expand the wildcard character to the contents of my current folder; just echo $MSYS2_ARG_CONV_EXCL to see if it is set corrrectly. Use set -f to disable globbing otherwise.Opalopalesce
Notice this will mess up commands in the bash such as npm. In Windows bash simply use npm.cmd if you've done MSYS_NO_PATHCONV=1 (e.g: npm.cmd -i @aspnet/signalr)Discursive
Just for summarizing: in Windows 10 with Git Bash, add a system variable MSYS_NO_PATHCONV with value 1. BUT that will make npm to stop working, (see workaround in comment above) so maybe better just use the double // method.Camporee
Yay for this! I was having hassled with mingw32-make and docker. The makefile called docker and the normal windows style path is inserted, but the it all breaks (although it isn't clear why). If you force the msys2 style /d/project/ style, then docker gets unhappy (I assume because it expects a Windows path from windows). I was able to manually run the exact command in the windows shell and it worked, but using make it broke. I can now run make MSYS2_ARG_CONV_EXCL="*" in this particular case and docker is happy with the path input.Fennelflower
MSYS2_ARG_CONV_EXCL="*" works in Git Bash as well as MSYS2.Ramiroramjet
G
79

I just discovered a neat trick to avoid MSYS/MinGW translating the paths for you.

If you use double-slash to start the path, then MSYS won't translate the path to DOS format. So in OP's example, the -rpath switch should be specified like this:

-Wl,-rpath=//usr/lib/myrpath

All Unix/Linux tools seem to handle such spurious slashes without any problem, so even though your binary's rpath will start with //usr/... I think the loader will do the right thing.

Gourami answered 7/1, 2013 at 3:58 Comment(4)
It doesn't work for me but -rpath="//usr\lib\myrpath" does (with quotes and backslashes for path )Boondoggle
This only works when the thing with a / is actually a path.Splutter
i needed this to mount //var/run/docker.sock for Docker for Win + msys (git bash)Philology
how can I make this this work if the path is in a variable? -rpath=$myvar where content of myvar is /usr/lib/myrpath ? Need the script to work both on windows and linuxDilator
S
10

I don't think there's a way to switch this off. MSYS is a fork of an old Cygwin version with a number of tweaks aimed at improved Windows integration, whereby the automatic POSIX path translation when invoking native Windows programs is arguably the most significant. The trouble with that is that it isn't always possible to tell whether an argument is a path or something else, or whether, as in this case, it is in fact a path that nevertheless shouldn't be translated. The translation is guided by a set of heuristics.

You could try using MinGW make instead of MSYS make (yes, they're different things), which is a native Windows build of make without POSIX path support and conversion. Install with mingw-get install mingw32-make and invoke as mingw32-make.

Or you could try Cygwin, ideally with a Cygwin build of the toolchain.

Sonnie answered 31/8, 2011 at 5:7 Comment(4)
Thanks - that link (the heuristics) helped me to 'fake out' mingw and get my path through unmolested.Libbey
WRONG! There is a way to switch if OFF. https://mcmap.net/q/35901/-how-to-stop-mingw-and-msys-from-mangling-path-names-given-at-the-command-linePleuro
The link to 'heuristics' is dead, but I believe you can now use this one from MSYS as it explains how to control the path conversion.Ops
Also, this answer was about the original MSYS, whereas the successor MSYS2 keeps up to date with current Cygwin, but still with similar modifications.Sonnie
C
10

Indeed, in the original MSYS project provided by MinGW.org, there is no way to disable the Posix path conversion.

That's why I made a little fork of the msys-core runtime which supports the MSYS_NO_PATHCONV flag introduced with the Git for Windows fork. In that way, you may use MSYS_NO_PATHCONV environment variable as in the Git for Windows but in the original MinGW/MSYS.

So in summary, to disable this Posix path convesion:

Contusion answered 4/1, 2021 at 21:46 Comment(3)
MSYS_NO_PATHCONV=1 did not work for me in Git for Windows.Midlothian
@Midlothian Try using export MSYS_NO_PATHCONV=1 or prepending MSYS_NO_PATHCONV=1 to the program you're running. If you're piping into that program, it must come after the pipe.Argonaut
This seems to be the most thorough answer around. Thanks! +1 for the explanatory history.Mylan
N
7

export MSYS_NO_PATHCONV=1 was necessary in my case on git-bash on windows (as noted by dx_over_dt above. )

Nationalist answered 1/4, 2022 at 18:40 Comment(0)
H
3

Unfortunately putting two forward slashes for this example doesn't work as expected.

rsync -rvztn --delete --exclude="/application/logs/" ...

I want 'rsync' to exclude files only at /application/logs which is at the top level, hence the leading forward slash. Adding two forward slashes will not cause it to exclude this directory. I have to resort to the less accurate --exclude="application/logs/".

Handsomely answered 19/12, 2015 at 5:12 Comment(1)
for my much simpler case of e.g. ssh [...] '/usr/bin/sh -c date' I found it works to escape the leading slash with a backslash: ssh [...] '\/usr/bin/sh -c date'. Is that an option for you? (I found that various things can lead mingw to not convert paths, including having quotes in the same string: '/usr/bin/sh -c "date"' worked just fine out of the box!)Buford

© 2022 - 2024 — McMap. All rights reserved.