如何停止 MinGW 和 MSYS 从错误的命令行给出的路径名称

在 Windows 上,我使用 CodeSourcery 的交叉编译器套件交叉编译一个用于 ARM/Linux 的程序。我使用 MinGW MSYS 作为我的命令解释器,它经常会破坏我的路径和路径名。例如,为了构建我的程序,我调用

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

当然,我希望将 /usr/lib/myrpath逐字插入到 myprogram可执行文件中——我正在编译的 ARM Linux 目标不使用 MinGW 或 MSYS。但最终的结果是这样的:

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

这不是我想要的。如果我直接在 cmd.exe 命令行上调用 GCC,我将在可执行文件中获得正确的 rpath。如果在 MSYS 命令行上调用 GCC,就会得到错误的 rpath。如果我使用从 cmd.exe 命令行运行 make 的 Makefile 调用 GCC,我仍然会得到一个错误的 rpath (!)

你知道我该怎么摆脱这种烦人的行为吗?

37504 次浏览

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.

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.

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/".

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

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:

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