如何阻止MinGW和MSYS在命令行中输入路径名称时进行修改

102

在 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!

有没有任何想法如何关闭这个烦人的行为?


请参阅MSYS文档,其中解释了路径转换的方法,以及如何控制转换的内容(特别是MSYS2_ARG_CONV_EXCL/MSYS2_ENV_CONV_EXCL用于细粒度控制,但没有提到完全的MSYS_NO_PATHCONV开关,所以亲爱的读者们,在未来,请进行一些研究,看看它是否与您的环境兼容)。 - quetzalcoatl
6个回答

150

有一种方法可以通过在Windows Git MSys中设置MSYS_NO_PATHCONV=1或在{{link2:MSYS2中设置MSYS2_ARG_CONV_EXCL="*"来禁止路径转换。

另外,您可以仅暂时地为该命令设置变量,方法是将赋值放在命令之前:

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

23
这是不正确的。这个只是在Git for Windows的MSYS runtime分支中添加的,而且MSYS_NO_PATHCONV变量不被上游版本的MSYS所识别:不管是1.0版还是MSYS2、32位或64位变体。 - Václav Slavík
1
这很棒。我希望它总是可用的。感谢您指出它。 - xer0x
2
@Phyx:根据给定的URL,环境变量应该是MSYS2_ARG_CONV_EXCL,而不是您评论中提到的MSYS2_ARG_CONV_EXC。 - kbulgrien
3
当使用git-bash时,命令gpg-connect-agent "/bye"被误解并导致gpg代理记录以下日志时,我采用了以下方法解决了这个问题: "C:/Program Files/Git/bye ERR 67109139 Unknown IPC command <GPG Agent>" - Shannon
5
请注意,这会影响到bash中的命令,例如 npm。 在Windows bash中,如果你已经执行了 MSYS_NO_PATHCONV=1,只需使用 npm.cmd 即可(例如:npm.cmd -i @aspnet/signalr)。 - diegosasw
显示剩余8条评论

79

我刚刚发现一个避免MSYS/MinGW为您翻译路径的好技巧。

如果您使用双斜杠来启动路径,则MSYS将不会将路径转换为DOS格式。因此,在OP的示例中,-rpath开关应该像这样指定:

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

所有Unix/Linux工具似乎都可以处理此类多余的斜杠,因此即使您的二进制rpath以//usr/... 开头,我认为加载程序也会做正确的事情。


9
对我来说不起作用,但-rpath="//usr\lib\myrpath"可以(路径需要带引号和反斜杠)。 - Emmanuel Caradec
10
只有当带有“/”的东西实际上是一个路径时,这个功能才有效。 - jpaugh
我需要这个来为Docker for Win + msys (git bash)挂载/var/run/docker.sock。 - jamey graham
如果路径是一个变量,我该如何让它工作? -rpath=$myvar,其中 myvar 的内容为 /usr/lib/myrpath?需要使脚本在 Windows 和 Linux 上都能正常工作。 - YK1

10
我认为没有关闭这个功能的方法。MSYS是旧版Cygwin的分支,经过了许多针对Windows集成改进的调整,其中自动转换本地Windows程序调用时的POSIX路径翻译可能是最重要的。问题在于,并不总是能够确定参数是路径还是其他内容,或者是否像在这种情况下一样,它实际上是一个不应该被翻译的路径。翻译是由一组启发式算法指导的set of heuristics
你可以尝试使用MinGW make代替MSYS make(是的,它们是不同的东西),这是一个没有POSIX路径支持和转换的本地Windows版本的make。使用mingw-get install mingw32-make进行安装,并作为mingw32-make调用。
或者你可以尝试Cygwin,最好使用工具链的Cygwin版本。

2
谢谢,那个链接(启发式算法)帮助我“欺骗”了mingw,使我的路径顺利通过,没有遭到破坏。 - Ted Middleton
4
错误!有一种方法可以关闭它。https://dev59.com/zGw05IYBdhLWcg3wahNN#34386471 - Igor Mukhin
链接到'heuristics'已失效,但我相信你现在可以使用这个来自MSYS的链接,因为它解释了如何控制路径转换。 - quetzalcoatl
此外,这个答案是关于原始的MSYS,而继任者MSYS2则与当前的Cygwin保持同步,但仍有类似的修改。 - ak2

8

确实,在由MinGW.org提供的原始MSYS项目中,没有办法禁用Posix路径转换

这就是为什么我制作了一个小的msys-core运行时的分支,支持Git for WindowsMSYS_NO_PATHCONV标志。通过这种方式,您可以在原始的MinGW/MSYS中使用 MSYS_NO_PATHCONV 环境变量,就像在Git for Windows中一样。

因此,要禁用此Posix路径转换:


1
MSYS_NO_PATHCONV=1在Git for Windows中对我没有起作用。 - qntm
1
@qntm 尝试使用 export MSYS_NO_PATHCONV=1 或在运行程序之前添加 MSYS_NO_PATHCONV=1。如果你正在将数据流导入该程序,则应在导入数据流命令之后执行。 - dx_over_dt
这似乎是最详尽的答案。谢谢! +1 为解释性历史。 - spechter

6
在我的情况下,在Windows上的git-bash中需要使用export MSYS_NO_PATHCONV=1(如dx_over_dt所述)。

3

很遗憾,对于这个例子来说,使用两个正斜杠并不能达到预期的效果。

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

我希望 'rsync' 只排除顶层目录下的 /application/logs 文件,因此需要在前面加上一个正斜杠。添加两个正斜杠并不会导致它排除这个目录。我只能采用不够准确的方式 --exclude="application/logs/"


对于我更简单的情况,例如 ssh [...] '/usr/bin/sh -c date',我发现用反斜杠转义前导斜杠可以正常工作:ssh [...] '\/usr/bin/sh -c date'。这对你来说是一个选项吗?(我发现各种事情都可能导致mingw不转换路径,包括在同一字符串中有引号:'/usr/bin/sh -c "date"'可以直接使用!) - SvenS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接