Search code examples
c++windows-xpcase-sensitiveinclude-pathmsys2

MSYS2 case sensitivity and includes on XP?


I am trying to compile a project on XP with MSYS2 (msys2-base-i686-20160205.tar.xz). One of the files included is like:

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

This file, in turn, does in its line 34:

#include <string.h>

This file already exists as, say:

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

... where the Z: drive is also the location of my code. On my g++ compile line, I have -I Z:/msys32/mingw32/i686-w64-mingw32/include first, and after a lot of includes, -I /z/path/to/libA/Include/A/B. However, when I try to compile, the compilation fails, related to String.h.

So, I inspected a bit by adding -v -E (to "stop after the preprocessing stage") and changing to -o File.e at the g++ command line, and can see this in the resulting 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
...

As I understand this, the preprocessor comes to line 34 of Z:/path/to/libA/Include/A/B/String.h, sees the #include <string.h>, starts looking for string.h at the current directory - and finds it, even if it doesn't exist under such name!? Indeed, if I do from the MSYS2 bash shell:

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

... nothing is returned (while String.h, capitalized, is found); however, if I force a list with either the non-capitalized or the capitalized name:

$ 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

... then they are both reported as existing?!

I'm guessing this is what "confuses" g++, in the sense of it being prevented from looking for string.h (miniscule letters) elsewhere/in the system path. Since, I've found Git-windows case sensitive file names not handled properly and:

While NTFS (and some remote filesystems) support case-sensitivity, the NT kernel starting with Windows XP does not support it by default. Rather, you have to tweak a registry setting and reboot. For that reason, case-sensitivity can not be supported by Cygwin, unless you change that registry value.
If you really want case-sensitivity in Cygwin, you can switch it on by setting the registry value
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\kernel\obcaseinsensitive
to 0 and reboot the machine.

... and I did this, but I still have the same problem; not sure if this is because I use MINGW on MSYS2 (not Cygwin); or because resources like Enable case sensitive behavior with Windows XP and Interix Subsystem or SFU refer to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel\ObCaseInsensitive (note, capitalized); however, I already had these keys (I just set it to 0, and rebooted), and they were with miniscule letters, like in the cygwin.com link. Also, tested after reboot, this didn't help either.

While How can I make MinGW case-sensitive for included header file names indicates this may not be possible to solve - is there anything I can do to resolve this problem, and to persuade g++ to read the string.h from the system location? I've tried building the same library on a different machine, Windows 7 or 8 remote desktop, with the same MingW version where it worked - so something should be possible to do...


Solution

  • Adding -I Z:/msys32/mingw32/i686-w64-mingw32/include to the beginning of your command line did not work because that directory is already in GCC's list of system include directories. I'm not sure why, but that is documented behavior of GCC.

    The best solution is to rename the header file in that library and rename all the includes that try to use it. Alternatively, use -I /z/path/to/libA/Include/ along with #include <A/B/String.h>. The folder names in the #include directive will make sure that the library header is included instead of the system header.