99

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ted Middleton
  • 6,859
  • 10
  • 51
  • 71
  • See also [MSYS docs](https://www.msys2.org/docs/filesystem-paths/#automatic-unix-windows-path-conversion) 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) – quetzalcoatl Jul 05 '23 at 08:52

6 Answers6

145

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
Mingye Wang
  • 1,107
  • 9
  • 32
Igor Mukhin
  • 15,014
  • 18
  • 52
  • 61
  • 22
    This is incorrect. This [was only added in Git for Window's fork of MSYS runtime](https://github.com/git-for-windows/msys2-runtime/pull/11) 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. – Václav Slavík Jan 17 '16 at 16:31
  • 1
    This is pretty great. I wish it was always available. Thanks for pointing it out. – xer0x Jan 27 '16 at 23:23
  • `MSYS2_ARG_CONV_EXC="*"` is accepted by the upstream MSYS2 and does the same though. It's documented https://sourceforge.net/p/msys2/wiki/Porting/ here – Phyx Oct 21 '16 at 06:35
  • 2
    @Phyx: Based on the URL given, the environment variable would be MSYS2_ARG_CONV_EXCL versus MSYS2_ARG_CONV_EXC mentioned in your comment. – kbulgrien Oct 28 '16 at 20:39
  • 3
    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 " – Shannon Feb 12 '17 at 20:15
  • @kbulgrien You are right: it is indeed `MSYS2_ARG_CONV_EXCL`. Thanks for this as it was driving me mad, trying to do a `docker cp` – ereOn Feb 23 '17 at 18:57
  • The only working way to use with "VBoxManage guestproperty set " with msys-git bash. Double-slash(es) trick didn't work in this case, although worked in many others, non-vbox. – yanot Mar 12 '18 at 16:38
  • 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? – AntonioCS Apr 11 '19 at 05:40
  • 1
    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. – SolarBear Aug 07 '19 at 14:32
  • 5
    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`) – diegosasw Nov 05 '19 at 12:11
  • 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. – drodsou May 04 '20 at 12:19
  • 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. – Duncan Drennan Nov 11 '21 at 13:40
  • `MSYS2_ARG_CONV_EXCL="*"` works in Git Bash as well as MSYS2. – AJM Jul 11 '23 at 12:26
78

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.

Gurjeet Singh
  • 2,635
  • 2
  • 27
  • 22
  • 9
    It doesn't work for me but -rpath="//usr\lib\myrpath" does (with quotes and backslashes for path ) – Emmanuel Caradec Apr 12 '13 at 10:50
  • 10
    This only works when the thing with a `/` is actually a path. – jpaugh Jul 07 '20 at 00:50
  • i needed this to mount //var/run/docker.sock for Docker for Win + msys (git bash) – jamey graham Jun 21 '21 at 17:51
  • 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 linux – YK1 Feb 20 '23 at 01:38
8

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:

SiZiOUS
  • 638
  • 1
  • 8
  • 9
  • 1
    `MSYS_NO_PATHCONV=1` did not work for me in Git for Windows. – qntm Mar 02 '21 at 18:19
  • 1
    @qntm 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. – dx_over_dt Jun 19 '21 at 21:07
  • This seems to be the most thorough answer around. Thanks! +1 for the explanatory history. – spechter Apr 20 '23 at 23:43
8

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.

ak2
  • 6,629
  • 31
  • 27
  • 2
    Thanks - that link (the heuristics) helped me to 'fake out' mingw and get my path through unmolested. – Ted Middleton Sep 24 '11 at 23:47
  • 4
    WRONG! There is a way to switch if OFF. http://stackoverflow.com/a/34386471/404615 – Igor Mukhin Dec 20 '15 at 22:18
  • The link to 'heuristics' is dead, but I believe you can now use [this one from MSYS](https://www.msys2.org/docs/filesystem-paths/#automatic-unix-windows-path-conversion) as it explains how to control the path conversion. – quetzalcoatl Jul 05 '23 at 08:48
  • Also, this answer was about the original MSYS, whereas the successor MSYS2 keeps up to date with current Cygwin, but still with similar modifications. – ak2 Jul 05 '23 at 14:19
6

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

David Harvey
  • 71
  • 1
  • 4
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/".

Steven
  • 99
  • 1
  • 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!) – SvenS Aug 25 '22 at 12:27