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
Confirmed.
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
(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);
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.
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
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
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
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
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
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
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
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
(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
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
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
Newest patch to have collect2 build on windows is here: <http://gcc.gnu.org/ml/gcc-patches/ 2004-06/msg00846.html>.
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
Refreshed patch (with missing files) here: http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01172.html Danny
What is the status of this bug wrt. to the 4.0 branch? Is it fixed?
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.
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
Fixed on mainline.