Bug 45749

Summary: Response file unwrapped between collect2.exe and ld.exe
Product: gcc Reporter: Ted <bogus2>
Component: driverAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: ben.combrink, bogus2, costas.argyris, gcc-bugs, rwild, wojciech.makuch
Priority: P3    
Version: 4.5.0   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86030
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107007
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71850
Host: Target: mingw32
Build: Known to work:
Known to fail: Last reconfirmed: 2022-01-01 00:00:00
Attachments: output of collect2.exe @file --verbose -debug

Description Ted 2010-09-22 16:28:08 UTC
When compiling on MinGW under cmd.exe it's necessary to use @FILE to work around the 32k limit on arguments when linking a large number of objects.

Unfortunately for some reason collect2.exe does not forward the file to ld.exe but instead appears to send its contents as arguments to CreateProcess() leading to the error:

collect2: CreateProcess: No such file or directory

Which is the typically unhelpful way for Windows to report this problem and something that led me on a 4 day goose-chase looking for the "missing" file or directory.

Really if I tell collect2 to use a response file it's absolutely essential it uses it internally or else finds some other way around the 32k barrier (like piping to stdin).
Comment 1 Andrew Pinski 2010-09-22 16:41:51 UTC
I totally thought this was fixed in 4.5.0 when support was added because of LTO.
Comment 2 Andrew Pinski 2010-09-22 16:42:28 UTC
Can you provide the output of the -v command when you get that error?  Also what version of ld are you using?
Comment 3 Ted 2010-09-22 16:57:55 UTC
Created attachment 21862 [details]
output of collect2.exe @file --verbose -debug

Attached --verbose -debug output of collect2

Also:
D:\SpringTest\debug\rts\builds\default>collect2 -v
collect2 version 4.5.0 (x86 MinGW)
C:\MinGW32\bin/ld.exe -v
GNU ld (GNU Binutils) 2.20.51.20100613

I believe this bug affects 4.5.1 as well because I've been fighting this bug for days and I've been through numerous official and TDM builds which all seemed affected by this or related issues.
Comment 4 Ted 2010-09-22 17:16:51 UTC
btw, I can confirm the arguments passed to ld are 33491 characters long so this is definitely over the 32k mark
Comment 5 Andrew Pinski 2010-09-22 17:42:35 UTC
See the code in collect_execute:
  if (HAVE_GNU_LD && at_file_supplied && argv[0] != NULL)
    {
      /* If using @file arguments, create a temporary file and put the
         contents of argv into it.  Then change argv to an array corresponding
         to a single argument @FILE, where FILE is the temporary filename.  */


So maybe HAVE_GNU_LD is not true when it should be.
Comment 6 Richard Biener 2010-09-22 19:57:16 UTC
(In reply to comment #5)
> See the code in collect_execute:
>   if (HAVE_GNU_LD && at_file_supplied && argv[0] != NULL)
>     {
>       /* If using @file arguments, create a temporary file and put the
>          contents of argv into it.  Then change argv to an array corresponding
>          to a single argument @FILE, where FILE is the temporary filename.  */
> 
> 
> So maybe HAVE_GNU_LD is not true when it should be.

Or collect2 is not invoked with a response file.
Comment 7 Richard Biener 2010-09-22 19:59:44 UTC
Btw, on i?86-linux I see

/* Define if using GNU as. */
#ifndef USED_FOR_TARGET
#define HAVE_GNU_AS 0
#endif


/* Define if using GNU ld. */
#ifndef USED_FOR_TARGET
#define HAVE_GNU_LD 0
#endif


in auto-host.h ...
Comment 8 Ted 2010-09-22 20:10:08 UTC
> Or collect2 is not invoked with a response file.
That's not the case. g++.exe is correctly passing the response file to collect2.exe which I've verified through debugging output and running collect2.exe by hand. 

Comment 9 Ted 2010-09-22 20:16:16 UTC
There's sections in configure and configure.ac that set HAVE_GNU_LD in confdefs.h. My hunch is neither the official builds or the TDM builds are enabling it (there's a --with-gnu-ld flag but it looks like it also sniffs the output ld -v). I've added a report to the TDM bug tracker to determine if this is the issue.

https://sourceforge.net/tracker/?func=detail&aid=3073600&group_id=200665&atid=974439
Comment 10 Andrew Pinski 2010-10-21 18:39:49 UTC
*** Bug 46113 has been marked as a duplicate of this bug. ***
Comment 11 Earnie 2013-02-08 17:58:03 UTC
So why is this doing the correct thing when supplying the --with-gnu-ld option versus the fact that we have GNU ld and the configure script discovers it?  It seems to me the bug would be in the configure process.
Comment 12 Orgad Shaneh 2018-07-03 07:05:08 UTC
I've noticed similar behavior with passing arguments to cc1plus and cc (GCC 8.1.0).

This short script demonstrates the bug:

#!/bin/sh
touch file.h
echo "-g -O0 -w -m32 -fexceptions -x c++-header -o file.gch -c file.h" > resp
seq -f '-IC:/Some/Very/Long/Path/With/Many/Components/%g' 1 1000 >> resp
g++ @resp
# g++.exe: error: CreateProcess: No such file or directory

g++ --verbose output:
Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\g++.exe
Target: i686-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/c/mingw810/i686-810-posix-dwarf-rt_v6-rev0/mingw32 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-sjlj-exceptions --with-dwarf2 --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=i686 --with-tune=generic --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-pkgversion='i686-posix-dwarf-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-posix-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-posix-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/i686-810-posix-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/i686-810-posix-dwarf-rt_v6-rev0/mingw32/opt/lib -L/c/mingw810/prerequisites/i686-zlib-static/lib -L/c/mingw810/prerequisites/i686-w64-mingw32-static/lib -Wl,--large-address-aware'
Thread model: posix
gcc version 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 
COLLECT_GCC_OPTIONS='-v' '-debug' '-g' '-O0' '-w' '-m32' '-fexceptions' '-o' 'file.gch' '-c' '-I' 'C:/Some/Very/Long/Path/With/Many/Components/1' '-I' 'C:/Some/Very/Long/Path/With/Many/Components/2' ... '-shared-libgcc' '-mtune=generic' '-march=i686'
 C:/MinGW/bin/../libexec/gcc/i686-w64-mingw32/8.1.0/cc1plus.exe -quiet -v -I C:/Some/Very/Long/Path/With/Many/Components/1 -I C:/Some/Very/Long/Path/With/Many/Components/2 ... C:/MinGW/bin/../lib/gcc/i686-w64-mingw32/8.1.0/ -D_REENTRANT file.h -quiet -dumpbase file.h -debug -m32 -mtune=generic -march=i686 -auxbase-strip file.gch -g -O0 -w -version -fexceptions -o F:\Temp\cc9pnz65.s --output-pch= file.gch
g++.exe: error: CreateProcess: No such file or directory
Comment 13 Andrew Pinski 2022-01-01 07:31:27 UTC
Let me try to fix this.
Comment 14 Jonathan Wakely 2022-09-22 10:00:03 UTC
(In reply to Ted from comment #0)
> collect2: CreateProcess: No such file or directory
> 
> Which is the typically unhelpful way for Windows to report this problem and
> something that led me on a 4 day goose-chase looking for the "missing" file
> or directory.

GCC is to blame here, not Windows. See PR 107007 for a suggestion how to improve it.
Comment 15 Andrew Pinski 2022-11-18 03:55:24 UTC
I am no longer working on this.