MSYS2区分大小写并包含在XP上

MSYS2 case sensitivity and includes on XP?

本文关键字:XP 包含 大小写 MSYS2      更新时间:2023-10-16

我正试图用MSYS2(msys2-base-i686-20160205.tar.xz)在XP上编译一个项目。其中一个包含的文件如下:

/z/path/to/libA/Include/A/B/String.h

这个文件,反过来,在它的第34行:

#include <string.h>

这个文件已经存在,比如说:

Z:/msys32/mingw32/i686-w64-mingw32/include/string.h

其中Z:驱动器也是我的代码所在的位置。在我的g++编译行中,我首先得到了-I Z:/msys32/mingw32/i686-w64-mingw32/include,经过大量包含之后,得到了-I /z/path/to/libA/Include/A/B。然而,当我尝试编译时,编译失败,这与String.h有关。

因此,我通过在g++命令行添加-v -E(到"预处理阶段后停止")并更改为-o File.e来检查一位,并可以在生成的File.e:中看到这一点

...
# 34 "Z:/path/to/libA/Include/A/B/String.h" 2
# 1 "Z:/path/to/libA/Include/A/B/string.h" 1
# 35 "Z:/path/to/libA/Include/A/B/String.h" 2
...

据我所知,预处理器来到Z:/path/to/libA/Include/A/B/String.h的第34行,看到#include <string.h>,开始在当前目录中查找string.h,并找到它,即使它不以这样的名称存在!?事实上,如果我从MSYS2bash外壳中这样做:

$ find Z:/path/to/libA/Include/A/B/ -name 'string.h'

不返回任何内容(而找到了大写的String.h);但是,如果我强制使用非大写或大写名称的列表:

$ ls -la Z:/path/to/libA/Include/A/B/String.h
-rw-r--r-- 1 User None 2885 May 31 09:45 Z:/path/to/libA/Include/A/B/String.h
$ ls -la Z:/path/to/libA/Include/A/B/string.h
-rw-r--r-- 1 User None 2885 May 31 09:45 Z:/path/to/libA/Include/A/B/string.h

那么它们都被报告为存在?!

我猜这就是"混淆"g++的原因,因为它被阻止在系统路径的其他地方/中查找string.h(微小字母)。从那以后,我发现Git windows区分大小写的文件名没有得到正确处理,并且:

  • https://cygwin.com/cygwin-ug-net/using-specialnames.html

虽然NTFS(和一些远程文件系统)支持区分大小写,但从Windows XP开始的NT内核默认情况下不支持它。相反,您必须调整注册表设置并重新启动。因此,Cygwin不支持区分大小写,除非您更改注册表值
如果您真的想在Cygwin中区分大小写,您可以通过将注册表值
HKLMSYSTEMCurrentControlSetControlSession Managerkernelobcaseinsensitive
设置为0来打开它,然后重新启动机器。

。。。我做到了,但我仍然有同样的问题;不确定这是否是因为我在MSYS2上使用了MINGW(而不是Cygwin);或者因为像Enable case sensitive behavior with Windows XP and Interix Subsystem或SFU这样的资源引用了HKEY_LOCAL_MACHINESystemCurrentControlSetControlSession ManagerKernelObCaseInsensitive(注意,大写);然而,我已经有了这些密钥(我只是将其设置为0,然后重新启动),它们带有极小的字母,就像在cygwin.com链接中一样。此外,经过重新启动后的测试,这也没有帮助。

虽然我如何使MinGW对包含的头文件名区分大小写表明这可能无法解决——但我能做些什么来解决这个问题,并说服g++从系统位置读取string.h吗?我试过在不同的机器上构建相同的库,Windows 7或8远程桌面,使用相同的MingW版本-所以应该可以做一些事情…

-I Z:/msys32/mingw32/i686-w64-mingw32/include添加到命令行的开头不起作用,因为该目录已经在GCC的系统包含目录列表中。我不知道为什么,但这是GCC的行为记录。

最好的解决方案是重命名该库中的头文件,并重命名所有尝试使用它的include。或者,将-I /z/path/to/libA/Include/#include <A/B/String.h>一起使用。#include指令中的文件夹名称将确保包含库标头而不是系统标头。