I'm building some generated code that creates insanely long names that tripped the 260 character limit on Windows. I attempted to specify paths using the \?\ prefix (https://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath ) and it worked on clean builds, but causes various tools to fail when the output already exists. Example:
C:\TEMP>echo "int main(){return 0;}" > test.cpp
C:\TEMP>g++ test.cpp -c -o \?\C:\TEMP\test.o
C:\TEMP>g++ test.cpp -c -o \?\C:\TEMP\test.o
Assembler messages:
Fatal error: can't create \test.o: No such file or directory
C:\TEMP>g++ test.cpp -o \?\C:\TEMP\blah.exe
C:\TEMP>g++ test.cpp -o \?\C:\TEMP\blah.exe
C:/MinGW/bin/../lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot open output file \blah.exe: No such file or directory
collect2.exe: error: ld returned 1 exit status
Anyone know what's causing this and if there is a workaround? Here's the config for my MinGW-W64 installation:
C:\TEMP>g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=C:/MinGW/bin/../libexec/gcc/x86_64-w64-mingw32/4.9.2/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-4.9.2/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw492/x86_64-492-win32-seh-rt_v3-rev1/mingw64 --with-gxx-include-dir=/mingw64/x86_64-w64-mingw32/include/c++ --enable-shared --enable-static --disable-multilib --enable-languages=ada,c,c++,fortran,objc,obj-c++,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-isl-version-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --with-cloog=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='x86_64-win32-seh-rev1, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/c/mingw492/x86_64-492-win32-seh-rt_v3-rev1/mingw64/opt/include -I/c/mingw492/prerequisites/x86_64-zlib-static/include -I/c/mingw492/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/c/mingw492/x86_64-492-win32-seh-rt_v3-rev1/mingw64/opt/include -I/c/mingw492/prerequisites/x86_64-zlib-static/include -I/c/mingw492/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS= LDFLAGS='-pipe -L/c/mingw492/x86_64-492-win32-seh-rt_v3-rev1/mingw64/opt/lib -L/c/mingw492/prerequisites/x86_64-zlib-static/lib -L/c/mingw492/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: win32
gcc version 4.9.2 (x86_64-win32-seh-rev1, Built by MinGW-W64 project)
There is no 260 character limit on Windows. There was indeed one in Windows 95 due to FAT32 limitations. But ever since NT4 with NTFS (That's 20 years ago!), Windows supports at least 64KB paths. Their real mistake was to invent that awful \\?\ trick for unlocking the new capability, presumably to prevent a buffer overflow in one of their old applications.
The real fix is not to try using the \\?\ prefix in your program. Instead, the real fix would be to silently insert that prefix inside mingw file I/O libraries. This way, every time a program opens a file the standard way, it just works, whatever the pathname length.
I've done that in my MSVC Library eXtension, and suddenly all my programs were magically able to access illimited paths.
I've long thought about contributing that fix to MinGW, but I'm afraid of the effort that would be needed to find all the places that need to be changed. If anybody has good experience with the low level file I/O sources in mingw, I'd be happy to discuss with him about what precisely needs to be done.
Last edit: Jean-Francois LARVOIRE 2017-09-29