Bug 14316 - collect2 doesnt build on windows hosts
Summary: collect2 doesnt build on windows hosts
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: bootstrap (show other bugs)
Version: 3.3.3
: P2 enhancement
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL:
Keywords: build, patch
Depends on:
Blocks:
 
Reported: 2004-02-27 02:07 UTC by Fabrice Gautier
Modified: 2005-04-03 16:53 UTC (History)
5 users (show)

See Also:
Host: i686-pc-mingw32
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-03-01 06:06:17


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fabrice Gautier 2004-02-27 02:07:16 UTC
collect2.c contains many unixism so that its impossible to build on win32 host.

mingw native compiler doesnt use collect2 but it would be usefull for cross-
compiler hosted on mingw.

There have been a few discussions and some patches to adress the issue. I'm 
just filling this bug to keep track of the issue.

Original Zack Weinberg patch and following discussion including DJ Delorie 
objections to the patch:
http://gcc.gnu.org/ml/gcc-patches/2003-01/msg02331.html
Mark Mitchell patch for csl-arm-branch (based on the above):
http://gcc.gnu.org/ml/gcc-patches/2003-12/msg01996.html

-- Thanks
Comment 1 Andrew Pinski 2004-02-27 02:52:47 UTC
Confirmed.
Comment 2 Eric Weddington 2004-03-13 06:43:57 UTC
What version / build were these patches by Zack and Mark applied to? Both fail 
to patch against 3.4-20040310.

Is there any hope for an updated patch against 3.4?

Thanks
Eric
Comment 3 Dave Murphy 2004-03-16 14:07:12 UTC
(In reply to comment #2)
> What version / build were these patches by Zack and Mark applied to? Both fail 
> to patch against 3.4-20040310.
> Is there any hope for an updated patch against 3.4?
> Thanks
> Eric

here's the patch I'm currently using for mingw compiler crosses, as I've applied to the current 3.4 snapshot.


--- collect2.c.orig	Fri Jan 23 23:35:54 2004
+++ collect2.c	Wed Feb 25 03:01:44 2004
@@ -144,6 +144,63 @@
 #define SCAN_LIBRARIES
 #endif
 
+#ifdef __MINGW32__
+/* We are being compiled with mingw32 as host, so we should prepare some
+   win32 replaces for pipe(), kill(getpid(),...) and vfork() + execv()
+*/
+#include <io.h>
+#include <fcntl.h>
+
+#define pipe(fildes) _pipe((fildes),1024*16,_O_BINARY)
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+int vfork_execv(char *cmdname, char **argv, int fdout);
+
+/* Helper function for vfork() + execv() replacement. */
+int vfork_execv(char *cmdname, char **argv, int fdout)
+{
+	STARTUPINFO SI;
+	PROCESS_INFORMATION PI;
+	char *params;
+	int plen = 0;
+	int i;
+	BOOL bRes;
+
+	/* Prepare one line with arguments */
+	for(i=0;argv[i];i++) plen += strlen(argv[i]) + 1;
+	plen++;
+	params = xmalloc(plen);
+	strcpy(params,argv[0]);
+	for(i=1;argv[i];i++)  strcat(strcat(params," "),argv[i]);
+
+	/* Prepare startup info -- for pipes redirection */
+	memset(&SI,0,sizeof(SI));
+	SI.cb = sizeof(SI);
+	SI.dwFlags = STARTF_USESTDHANDLES;
+	SI.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
+	SI.hStdOutput = (HANDLE)_get_osfhandle(fdout);
+	SI.hStdError  = GetStdHandle(STD_ERROR_HANDLE);
+
+	/* Create new process in same console, with redirected (piped) stdout */
+	bRes = CreateProcess(cmdname,params,
+		NULL,NULL,	/* Security attributes */
+		FALSE,		/* Handle inheritance */
+		0,			/* Flags -- default, in this console, etc */
+		NULL,		/* Invironment */
+		NULL,		/* CWD */
+		&SI,		/* Startup info */
+		&PI);		/* Process info */
+	if(!bRes) return -1;
+	CloseHandle(PI.hProcess);
+	CloseHandle(PI.hThread);
+	return 0;
+}
+
+/* END-OF-WIN32-SECTION */
+#endif
+
 #ifdef USE_COLLECT2
 int do_collecting = 1;
 #else
@@ -424,7 +481,11 @@
 #endif
 
   signal (signo, SIG_DFL);
+#ifndef __MINGW32__
   kill (getpid (), signo);
+#else
+  ExitProcess(signo);
+#endif
 }
 
 
@@ -2034,6 +2095,7 @@
   fflush (stderr);
 
   /* Spawn child nm on pipe.  */
+#ifndef __MINGW32__
   pid = vfork ();
   if (pid == -1)
     fatal_perror (VFORK_STRING);
@@ -2053,6 +2115,11 @@
       execv (nm_file_name, real_nm_argv);
       fatal_perror ("execv %s", nm_file_name);
     }
+#else
+  if(vfork_execv(nm_file_name, real_nm_argv, pipe_fd[1])) {
+      fatal_perror ("vfork+execv %s", nm_file_name);
+  }
+#endif
 
   /* Parent context from here on.  */
   int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
@@ -2463,6 +2530,7 @@
   fflush (stderr);
 
   /* Spawn child ldd on pipe.  */
+#ifndef __MINGW32__
   pid = vfork ();
   if (pid == -1)
     fatal_perror (VFORK_STRING);
@@ -2482,6 +2550,11 @@
       execv (ldd_file_name, real_ldd_argv);
       fatal_perror ("execv %s", ldd_file_name);
     }
+#else
+  if(vfork_execv(ldd_file_name, real_ldd_argv, pipe_fd[1])) {
+      fatal_perror ("vfork+execv %s", nm_file_name);
+  }
+#endif
 
   /* Parent context from here on.  */
   int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);







Comment 4 Eric Weddington 2004-03-17 15:06:50 UTC
The collect2 patch from Dave Murphy works (thanks!), but then there are 
additional errors in fixinc/fixincl.c due to POSIX stuff: pipe, fork, sleep, 
fcntl, wait, F_DUPFD, SIGQUIT, SIGALRM.

IIRC (from building the avr target), collect2 and fixincl are the only two 
places that need patching for building cross-compilers on a mingw32 host.
Comment 5 Ian Lance Taylor 2004-03-17 15:47:12 UTC
Subject: Re:  collect2 doesnt build on windows hosts

"eric at ecentral dot com" <gcc-bugzilla@gcc.gnu.org> writes:

> The collect2 patch from Dave Murphy works (thanks!), but then there are 
> additional errors in fixinc/fixincl.c due to POSIX stuff: pipe, fork, sleep, 
> fcntl, wait, F_DUPFD, SIGQUIT, SIGALRM.
> 
> IIRC (from building the avr target), collect2 and fixincl are the only two 
> places that need patching for building cross-compilers on a mingw32 host.

Perhaps the fixinc problem can be fixed by adding a case in
fixinc/mkfixinc.sh for mingw32?  There is already a case there for
msdosdjgpp.

I haven't looked at the code enough to see what it is really doing?

Ian
Comment 6 Eric Weddington 2004-03-17 17:04:16 UTC
The case for msdosdjgpp in fixinc/mkfixinc.sh is to "Choose one or two-process 
fix methodology.  Systems that cannot handle bi-directional pipes must use the 
two process method."

After that there's a case statement that checks "for special fix rules for 
particular targets" and lists a bunch of targets that don't do any fixing. The 
two targets I'm interested in, avr and m68k-elf, are not listed in this. I 
don't know whether they should be or not.

After this is when it builds fixinc, which it does for avr and m68k-elf. And 
fixinc is built with POSIX calls.

Eric
Comment 7 Ian Lance Taylor 2004-03-17 17:13:47 UTC
Subject: Re:  collect2 doesnt build on windows hosts

Note that the test for msdosdjgpp case is a test on the build machine,
not the target.  That is what matters here, since that is what affects
which calls are available when building and running fixinc.  What
happens if you add mingw to that case, along the lines of msdosdjgpp?
I haven't looked into it myself.

Ian
Comment 8 Eric Weddington 2004-03-17 17:49:03 UTC
Adding mingw to that case still fails. But it looks like due to the SIG* 
identifiers.

make output:
----------------------
/bin/sh ${srcdir}/mkfixinc.sh i386-pc-mingw32 avr-unknown-none)
constructing ../fixinc.sh for avr-unknown-none to run on i386-pc-mingw32
make TARGETS=twoprocess SHELL="/bin/sh" CC="gcc -mno-cygwin" CFLAGS=" -g -O2 -
DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-
prototypes -pedantic -Wno-long-long -Wno-error -DHAVE_CONFIG_H -
DGENERATOR_FILE -DSEPARATE_FIX_PROC" LDFLAGS="" 
LIBERTY="/cygdrive/e/avrdev/gcc/build/gcc/../libiberty/libiberty.a" install-bin
make[2]: Entering directory `/cygdrive/e/avrdev/gcc/build/gcc/fixinc'
/bin/sh ../../../gcc-3.4-20040310/gcc/fixinc/genfixes machname.h
No forbidden identifiers defined by this target
gcc -mno-cygwin -c -DIN_GCC -DHAVE_CONFIG_H -g -O2 -DIN_GCC -DCROSS_COMPILE -W -
Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-
long-long -Wno-error -DHAVE_CONFIG_H -DGENERATOR_FILE -DSEPARATE_FIX_PROC  -W -
Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-
long-long  -Wno-error -I. -I.. -I../../../gcc-3.4-20040310/gcc/fixinc -
I../../../gcc-3.4-20040310/gcc/fixinc/.. -I../../../gcc-3.4-
20040310/gcc/fixinc/../config -I../../../gcc-3.4-
20040310/gcc/fixinc/../../include ../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c
In file included from ../../../gcc-3.4-20040310/include/xregex.h:26,
                 from ../../../gcc-3.4-20040310/gcc/fixinc/fixlib.h:35,
                 from ../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c:24:
../../../gcc-3.4-20040310/include/xregex2.h:551: warning: ISO C90 does not 
support `static' or type qualifiers in parameter array declarators
In file included from ../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c:105:
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.x:76: warning: string length `552' 
is greater than the length `509' ISO C89 compilers are required to support
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.x:121: warning: string length 
`525' is greater than the length `509' ISO C89 compilers are required to support
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.x:165: warning: string length 
`808' is greater than the length `509' ISO C89 compilers are required to support
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.x:251: warning: string length 
`5139' is greater than the length `509' ISO C89 compilers are required to 
support
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.x:2119: warning: string length 
`729' is greater than the length `509' ISO C89 compilers are required to support
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.x:6120: warning: string length 
`575' is greater than the length `509' ISO C89 compilers are required to support
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c: In function `initialize':
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c:316: error: `SIGQUIT' undeclared 
(first use in this function)
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c:316: error: (Each undeclared 
identifier is reported only once
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c:316: error: for each function it 
appears in.)
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c:323: error: `SIGALRM' undeclared 
(first use in this function)
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c: In function `fix_with_system':
../../../gcc-3.4-20040310/gcc/fixinc/fixincl.c:903: warning: long int format, 
int arg (arg 3)
make[2]: *** [fixincl.o] Error 1
make[2]: Leaving directory `/cygdrive/e/avrdev/gcc/build/gcc/fixinc'
make[1]: *** [fixinc.sh] Error 2
make[1]: Leaving directory `/cygdrive/e/avrdev/gcc/build/gcc'
make: *** [all-gcc] Error 2
Comment 9 Zack Weinberg 2004-03-17 20:30:45 UTC
Subject: Re:  collect2 doesnt build on windows hosts


Cross compilers aren't supposed to build fixincl in the first place.
There's the real problem.

zw
Comment 10 Ian Lance Taylor 2004-03-17 20:39:32 UTC
Subject: Re:  collect2 doesnt build on windows hosts

"zack at codesourcery dot com" <gcc-bugzilla@gcc.gnu.org> writes:

> Cross compilers aren't supposed to build fixincl in the first place.
> There's the real problem.

I see code to disable building fixincl if build != host (unless
--with-sysroot is specified).  But I don't see any code to disable
building fixincl if build == host and host != target.  So it seems to
me that building a cross-compiler from mingw32 to something else, and
doing the build on mingw32, will cause this problem.

To me it seems reasonable to build fixincl whenever we have header
files to fix.  And that does include the case of host != target.
There have been times when I've needed it, such as when building for
the VxWorks target--I put a bunch of VxWorks fixes into fixincludes
back when I maintained it.

Ian
Comment 11 Zack Weinberg 2004-03-17 20:56:52 UTC
Subject: Re:  collect2 doesnt build on windows hosts

Ian Lance Taylor <ian@wasabisystems.com> writes:

> "zack at codesourcery dot com" <gcc-bugzilla@gcc.gnu.org> writes:
>
>> Cross compilers aren't supposed to build fixincl in the first place.
>> There's the real problem.
>
> I see code to disable building fixincl if build != host (unless
> --with-sysroot is specified).  But I don't see any code to disable
> building fixincl if build == host and host != target.  So it seems to
> me that building a cross-compiler from mingw32 to something else, and
> doing the build on mingw32, will cause this problem.

Huh.  This has changed since last I looked at it; fixincl used to be
built only if build == host == target.

> To me it seems reasonable to build fixincl whenever we have header
> files to fix.  And that does include the case of host != target.
> There have been times when I've needed it, such as when building for
> the VxWorks target--I put a bunch of VxWorks fixes into fixincludes
> back when I maintained it.

The original logic for not doing it when host != target was that the
header files might not be conveniently available and probably didn't
need fixing anyway -- consider newlib, which (used to) construct its
headers during the target library build, well after fixincludes runs.

I'm not trying to stop you making fixincl build and run on mingw, I'm
just pointing out that we didn't used to bother.

zw
Comment 12 Ian Lance Taylor 2004-03-18 20:23:05 UTC
I've written a patch to remove the vfork calls from collect2.  This is a partial
fix for this problem.  I think the libiberty parts are better--i.e., more
portable and easier to understand--than Zack's patch.  I'm waiting for approval
for the collect2 part.

http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01445.html
Comment 13 Eric Weddington 2004-03-19 21:49:04 UTC
(In reply to comment #10)
> Subject: Re:  collect2 doesnt build on windows hosts
> I see code to disable building fixincl if build != host (unless
> --with-sysroot is specified).  But I don't see any code to disable
> building fixincl if build == host and host != target.  So it seems to
> me that building a cross-compiler from mingw32 to something else, and
> doing the build on mingw32, will cause this problem.
> To me it seems reasonable to build fixincl whenever we have header
> files to fix.  <snip>
> Ian

How does one determine if there are header files to fix for a particular host 
and target? (and/or where does gcc determine this?)

Also, FYI, I can't test Ian's patch because it doesn't patch against a recent 
3.4 snapshot (20040310).

Thanks
Eric
Comment 14 Ian Lance Taylor 2004-03-19 22:50:22 UTC
Subject: Re:  collect2 doesnt build on windows hosts

> How does one determine if there are header files to fix for a particular host 
> and target? (and/or where does gcc determine this?)

To be pedantic, the host, as such, is irrelevant.  The header files
are for the target.  The fixincl program will run on the build system.

The fixincl program will be run on the header files in the directories
named by the Makefile variables SYSTEM_HEADER_DIR and
OTHER_FIXINCLUDES_DIRS.

On a native configuration, where host == target, SYSTEM_HEADER_DIR is
/usr/include.

On a cross configuration, where host != target:
  * if you configure with --with-sysroot, SYSTEM_HEADER_DIR is
    usr/include under the specified sysroot.
  * if you do not configure with --with-sysroot, SYSTEM_HEADER_DIR is,
    more or less, $(prefix)/$(target)/sys-include, or in other
    words something like /usr/local/avr/sys-include

I think OTHER_FIXINCLUDES_DIRS is always empty, but I suppose you
might specify it on the command line when you run make.

You can use --with-headers when you run configure to name a directory
containing header files for your target.  This is only supported when
configuring a cross-compiler.  If you do this, the configure process
will copy the header files to the $(target)/sys-include directory, and
later on fixincl will be run on them.

Ian
Comment 15 Eric Weddington 2004-03-20 00:14:34 UTC
Subject: Re:  collect2 doesnt build on windows hosts

On 19 Mar 2004 at 17:50, Ian Lance Taylor wrote:

> > How does one determine if there are header files to fix for a particular host
> > and target? (and/or where does gcc determine this?)
> 
> To be pedantic, the host, as such, is irrelevant.  The header files
> are for the target.  The fixincl program will run on the build system.
> 
> The fixincl program will be run on the header files in the directories
> named by the Makefile variables SYSTEM_HEADER_DIR and
> OTHER_FIXINCLUDES_DIRS.
> 
> On a native configuration, where host == target, SYSTEM_HEADER_DIR is
> /usr/include.
> 
> On a cross configuration, where host != target:
>   * if you configure with --with-sysroot, SYSTEM_HEADER_DIR is
>     usr/include under the specified sysroot.
>   * if you do not configure with --with-sysroot, SYSTEM_HEADER_DIR is,
>     more or less, $(prefix)/$(target)/sys-include, or in other
>     words something like /usr/local/avr/sys-include
> 
> I think OTHER_FIXINCLUDES_DIRS is always empty, but I suppose you
> might specify it on the command line when you run make.

Thanks for the great explanation! Is this also somewhere in the documentation 
(user or internals)? if not, it should be...

 
> You can use --with-headers when you run configure to name a directory
> containing header files for your target.  This is only supported when
> configuring a cross-compiler.  If you do this, the configure process
> will copy the header files to the $(target)/sys-include directory, and
> later on fixincl will be run on them.

Ok.
From the configure page 
<http://gcc.gnu.org/install/configure.html>:

--without-headers 
Tells GCC not use any target headers from a libc when building a cross 
compiler. When crossing to GNU/Linux, you need the headers so GCC can build the 
exception handling for libgcc. See _CrossGCC_ for more information on this 
option. 

The "_CrossGCC_" above is a link to the CrossGCC FAQ: 
<http://www.objsw.com/CrossGCC/>.

The CrossGCC FAQ says NOTHING (that I could find) about --without-headers.

So if I specify --without-headers, should GCC even be *building* fixincl? It 
currently does for target = m68k | avr.

OT: The CrossGCC FAQ hasn't been updated since December 3, 1999, and contains 
outdated and incomplete information.

Thanks,
Eric



Comment 16 Andrew Pinski 2004-06-18 04:28:58 UTC
Newest patch to have collect2 build on windows is here: <http://gcc.gnu.org/ml/gcc-patches/
2004-06/msg00846.html>.
Comment 17 Aaron W. LaFramboise 2004-10-14 01:07:25 UTC
What is the status on this bug?

With Danny Smith's proposed patch, what remains to be done before it can be
committed?

By the way, that patch appears to be incomplete; the source for three files
seems to be missing:
? include/pex-read.h
? libiberty/pexrd-generic.c
? libiberty/pexrd-unix.c
Comment 18 Danny Smith 2004-10-14 11:28:41 UTC
Refreshed patch (with missing files) here:
http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01172.html
Danny
Comment 19 Eric Weddington 2005-02-28 23:42:36 UTC
What is the status of this bug wrt. to the 4.0 branch? Is it fixed?
Comment 20 Aaron W. LaFramboise 2005-03-01 06:06:10 UTC
Nope.  Ian Lance Taylor or DJ Delorie must approve the libiberty portions of
this patch, or someone must suggest (and implement) an alternate implementation.
 I don't know why Ian Lance Taylor doesn't approve it, as he's the one who wrote it.

It might be more appropriate to fix this in a direct manner by simply having
#ifdef sections for Windows in collect2.c, which isn't that bad because:
1) The changes are actually rather minimal, mostly slight tweaks and using spawn
rather than fork.
2) The file already has much worse OS-specific code in it.
The trouble is that a global maintainer may still be disinclined to approve a
patch such as this; in a perfect world, this isn't the right way to fix this
problem.

I beleive there is actually a third implementation by Zack Weinberg, but DJ
Delorie has specific problems with it.  I beleive this implementation is used on
the csl-arm branch.

So, as I understand it, the situation is basically deadlocked until someone
suggests another way to fix this problem.

In the meantime, most of us who care about this issue have left the GCC process
behind and have been using one of these three fixes for years.
Comment 21 GCC Commits 2005-03-29 19:39:41 UTC
Subject: Bug 14316

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	ian@gcc.gnu.org	2005-03-29 19:39:36

Modified files:
	gcc            : ChangeLog collect2.c collect2.h tlink.c 

Log message:
	PR bootstrap/14316
	* collect2.c: Never include <vfork.h>.
	(VFORK_STRING, vfork): Don't define.
	(pid): Remove global variable.
	(handler): Call raise instead of kill (getpid(), ...).
	(collect_wait): Add pex parameter.  Change all callers.  Use
	pex_get_status rather than pwait.
	(do_wait): Add pex parameter.  Change all callers.
	(collect_execute): Return struct pex_obj * rather than void.  Use
	pex routines rather than pexecute.
	(fork_execute): Get pex_obj from collect_execute, and pass it to
	do_wait.
	(scan_prog_file): Use pex routines rather than pipe/vfork/exec.
	Only declare quit_handler if SIGQUIT is defined.
	(scan_libraries): Likewise.
	* collect2.h (collect_execute): Update declaration.
	(collect_wait): Update declaration.
	* tlink.c (tlink_execute): Get pex_obj from collect_execute, and
	pass it to collect_wait.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.8016&r2=2.8017
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/collect2.c.diff?cvsroot=gcc&r1=1.170&r2=1.171
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/collect2.h.diff?cvsroot=gcc&r1=1.10&r2=1.11
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tlink.c.diff?cvsroot=gcc&r1=1.59&r2=1.60

Comment 22 Ian Lance Taylor 2005-04-03 14:40:40 UTC
Fixed on mainline.