Menu

#2155 WSL: cannot bootstrap configuration during bare metal GCC build

WSL
unread
nobody
Bug
none
Unknown
False
2015-01-30
2014-01-02
No

Observed while creating an experimental mingw32-gcc-4.8.2 cross-compiler build, on an effectively bare metal Linux host; this is a distinct regression from the former configuration-time behaviour of mingwrt-3.x and w32api-3.x:

$ ../../mingw-wsl/configure --prefix=/home/keith/mingw32 --build=x86_64-unknown-linux-gnu --host=mingw32
checking build system type... x86_64-unknown-linux-gnu
checking host system type... i386-pc-mingw32
checking target system type... i386-pc-mingw32
checking for mingw32-gcc... mingw32-gcc
checking whether the C compiler works... no
configure: error: in `/home/keith/src/mingw/gcc-build/cross-lib':
configure: error: C compiler cannot create executables
See `config.log' for more details

The issue here is that there is a circular dependency between WSL and GCC: having begun by installing the WSL headers, (i.e. simply copying them from the source), into /home/keith/mingw32, configuring, building and installing mingw32-binutils, (configured --with-sysroot=/home/keith/mingw32), we then get stuck on the GCC build. This requires a two stage build:

  1. Configure, (again --with-sysroot=/home/keith/mingw32), then make all-gcc and make install-gcc

  2. Configure and make the host specific libraries, using the stage 1 compiler installed by make install-gcc, before completing the make and make install of GCC itself.

Now, stage 1 completes successfully, but stage 2 cannot even be started: that requires configuration of WSL, which in turn requires a completed stage 2 GCC build. Circular dependency stalemate: GCC cannot create executables until the stage 2 build has been completed; WSL cannot be configured until GCC is able to create executables; the stage 2 GCC build, which allows it to do so, cannot be started until WSL has been configured, built, and installed.

We must have a mechanism for configuring, building, and installing WSL, using no more than the stage 1 GCC: mingwrt-3.x and w32api-3.x supported this; WSL does not!

Related

Issues: #2156
Issues: #2168
Issues: #2174
Issues: #2175
Issues: #2177

Discussion

  • Thorsten Otto

    Thorsten Otto - 2014-01-19

    Hi,

    i recently tried to setup a cross-compiler on linux using gcc-4.8.1, and apparently struggled upon similar problems. I first tried to re-introduce the GCC_NO_EXECUTABLES autoconf macro from w32api-3.x (which seems to work), but then noticed the check for types, libraries and functions in the script,
    all testing functionality that is supposed to be supplied by that package (already noticed in Ticket #2156

    Removing those checks, and using AC_CHECK_TOOL instead of AC_PROG_CC, yields a configure script that does not need to create executables. This should do for now, as long as no script needs the definition of EXEEXT.

    The other problem about the missing libgcc during stage 1 can probably be fixed by
    - passing -static-libgcc when creating a dll
    - creating dummy libgcc.a and libgcc_eh.a
    - make mingwm10.dll depend on the startupfile and (at least) the default winapi libraries (kernel32 etc).

    I also added an explicit -no-pthread switch, because i noticed that when configuring gcc for posix threads, it always passes -lpthread by default when building dlls, but maybe this should only be done when configure finds out the compiler does understand that switch.

    (BTW. i am not sure whether always adding -lpthread is a good idea, that will make every dll/exe depend on libpthread even if no threads are used; on linux this switch is only added when explicitely requested)

    With those changes applied, the dll could be build, but then i found out about some other problems:
    - in the math library, some functions (like fabsf and sqrtf) were missing. This was due to the fact that the Makefile assumed that all math functions can be compiled by passing -DFUNCTION and just compiling the main source file, but thats not true in those cases. I fixed this by compiling the corresponding *{f,l}.c file instead, which already exist anyway except for a few cases.
    - the llround function(s) were missing
    - all the complex functions were missing, because $(wildcard src/libcrt/complex/*.c) expands to nothing when not building in the source tree (VPATH does not help in this case)
    - src/libcrt/ctype/{qnan,arithchk}.c do not belong to the library, those are only test programs. I only removed from them the list, but maybe it would be better to move the sources to the test directory.

    PS.: in the clean rule, it would be better to check for srcdir != . before
    doing rm -rf src/

    PS.: the attached patch already contains the patch from Ticket #2151

    PS.: after applying the patch, config.h.in is no longer needed and can be removed

    PS.: i'm new to this forum, so feel free to blame me if i did something wrong in posting this.

     

    Last edit: Thorsten Otto 2014-01-19
  • Thorsten Otto

    Thorsten Otto - 2014-01-19

    (some hours later)

    There is another circular dependency involving libpthread, but it is not the fault of WSL. libpthread requires a C++ compiler, which requires libgomp, which needs a libpthread...

    Looks like it will be very tricky to bootstrap a cross-compiler.

     
  • Keith Marshall

    Keith Marshall - 2014-01-21

    Thanks for confirming my findings, Thorsten. FYI, I'd already committed my own patches for [#2151] and [#2156], so your patch will not apply cleanly.

    I did consider the AC_PATH_TOOL option, as an alternative to AC_PROG_CC, to avoid the "cannot create executables" problem, but instead I opted for

    m4_define([_AC_COMPILER_EXEEXT])
    

    as a temporary one-liner in (a new) aclocal.m4, and I also temporarily eliminated (i.e. disabled) all dependencies on mingwm10.dll from the default WSL build, (as a pre-emptive approach to addressing [#2168], for which I now also have a more elegant proposed solution). With this work around in place, I can successfully build and install all of WSL, except for mingwm10.dll, (which isn't needed for the cross compiler anyway), and progress to the stage 2 GCC build, (which also delivers a working cross g++).

    For the record, I configured GCC thus:

    $ ./config.status --version
    config.status
    configured by ../gcc-4.8.2/configure, generated by GNU Autoconf 2.64,
      with options " '--prefix=/home/keith/mingw32' '--target=mingw32'
     '--with-sysroot=/home/keith/mingw32' '--with-dwarf2'
     '--disable-sjlj-exceptions' '--disable-nls' '--disable-multilib'
     '--enable-threads' 'target_alias=mingw32'
     '--enable-languages=c,c++,fortran,lto'"
    
     

    Related

    Issues: #2151
    Issues: #2156
    Issues: #2168

  • Keith Marshall

    Keith Marshall - 2014-01-21

    Thorsten,

    in the math library, some functions (like fabsf and sqrtf) were missing.

    Many math functions are provided by MSVCRT.DLL; any extras which we provide are in libmingwex.a; (fabsf and sqrtf are there, for me, as are fabsl and sqrtl, using the Makefile as is).

    Our libm.a is a (mostly) empty stub, to satisfy foreign makefiles which specify it as a linking requirement.

    This was due to the fact that the Makefile assumed that all math functions can be compiled by passing -DFUNCTION and just compiling the main source file, but thats not true in those cases

    WJFFM, without any changes, except for...

    the llround function(s) were missing

    these, because there are no declared dependencies to pull them in, and...

    all the complex functions were missing

    these, because of the bogus wildcard expansion, as you've noted; (see [#2174]).

     

    Related

    Issues: #2174


    Last edit: Keith Marshall 2014-01-21
  • Thorsten Otto

    Thorsten Otto - 2014-01-22

    FYI, I'd already committed my own patches for [#2151] and [#2156], so your
    patch will not apply cleanly.

    I already thought this might happen ;) Sorry for that. Please let me know if i can help supplying a patch that will apply, with your changes already in place.

    but instead I opted for

    m4_define([_AC_COMPILER_EXEEXT])

    as a temporary one-liner in (a new) aclocal.m4,

    Might work too, but i would suggest to put it in configure.ac instead.

    Our libm.a is a (mostly) empty stub, to satisfy foreign makefiles which >specify it as a linking requirement.

    I noticed that. "math library" was of course unclear, i was talking about libmingwex.a in this case.

    WJFFM, without any changes

    I might have been wrong for sqrtf, but without the patch i get:

    $ ~/mingw32/bin/i686-pc-mingw32-nm -A libmingwex.a | grep ' T ' | grep fabs
    libmingwex.a:fabs.o:00000000 T _fabs
    libmingwex.a:fabsf.o:00000000 T _fabs
    libmingwex.a:fabsl.o:00000000 T _fabs
    

    so the objects are there, but they just all export fabs (without suffix)

    With some grepping and sorting, i got:

    4,5c4,5
    < libmingwex.a:acoshf.o T _acoshf
    < libmingwex.a:acoshl.o T _acoshl
    ---
    > libmingwex.a:acoshf.o T _acosh
    > libmingwex.a:acoshl.o T _acosh
    6a7
    > libmingwex.a:arithchk.o T _main
    16,17c17,18
    < libmingwex.a:atanhf.o T _atanhf
    < libmingwex.a:atanhl.o T _atanhl
    ---
    > libmingwex.a:atanhf.o T _atanh
    > libmingwex.a:atanhl.o T _atanh
    22,45d22
    < libmingwex.a:cabs.o T _cabs
    < libmingwex.a:cabsf.o T _cabsf
    < libmingwex.a:cabsl.o T _cabsl
    < libmingwex.a:cacos.o T _cacos
    < libmingwex.a:cacosf.o T _cacosf
    < libmingwex.a:cacosh.o T _cacosh
    < libmingwex.a:cacoshf.o T _cacoshf
    < libmingwex.a:cacoshl.o T _cacoshl
    < libmingwex.a:cacosl.o T _cacosl
    < libmingwex.a:carg.o T _carg
    < libmingwex.a:cargf.o T _cargf
    < libmingwex.a:cargl.o T _cargl
    < libmingwex.a:casin.o T _casin
    < libmingwex.a:casinf.o T _casinf
    < libmingwex.a:casinh.o T _casinh
    < libmingwex.a:casinhf.o T _casinhf
    < libmingwex.a:casinhl.o T _casinhl
    < libmingwex.a:casinl.o T _casinl
    < libmingwex.a:catan.o T _catan
    < libmingwex.a:catanf.o T _catanf
    < libmingwex.a:catanh.o T _catanh
    < libmingwex.a:catanhf.o T _catanhf
    < libmingwex.a:catanhl.o T _catanhl
    < libmingwex.a:catanl.o T _catanl
    49,54d25
    < libmingwex.a:ccos.o T _ccos
    < libmingwex.a:ccosf.o T _ccosf
    < libmingwex.a:ccosh.o T _ccosh
    < libmingwex.a:ccoshf.o T _ccoshf
    < libmingwex.a:ccoshl.o T _ccoshl
    < libmingwex.a:ccosl.o T _ccosl
    57,65d27
    < libmingwex.a:cexp.o T _cexp
    < libmingwex.a:cexpf.o T _cexpf
    < libmingwex.a:cexpl.o T _cexpl
    < libmingwex.a:cimag.o T _cimag
    < libmingwex.a:cimagf.o T _cimagf
    < libmingwex.a:cimagl.o T _cimagl
    < libmingwex.a:clog.o T _clog
    < libmingwex.a:clogf.o T _clogf
    < libmingwex.a:clogl.o T _clogl
    73,96d34
    < libmingwex.a:cpow.o T _cpow
    < libmingwex.a:cpowf.o T _cpowf
    < libmingwex.a:cpowl.o T _cpowl
    < libmingwex.a:cproj.o T _cproj
    < libmingwex.a:cprojf.o T _cprojf
    < libmingwex.a:cprojl.o T _cprojl
    < libmingwex.a:creal.o T _creal
    < libmingwex.a:crealf.o T _crealf
    < libmingwex.a:creall.o T _creall
    < libmingwex.a:csin.o T _csin
    < libmingwex.a:csinf.o T _csinf
    < libmingwex.a:csinh.o T _csinh
    < libmingwex.a:csinhf.o T _csinhf
    < libmingwex.a:csinhl.o T _csinhl
    < libmingwex.a:csinl.o T _csinl
    < libmingwex.a:csqrt.o T _csqrt
    < libmingwex.a:csqrtf.o T _csqrtf
    < libmingwex.a:csqrtl.o T _csqrtl
    < libmingwex.a:ctan.o T _ctan
    < libmingwex.a:ctanf.o T _ctanf
    < libmingwex.a:ctanh.o T _ctanh
    < libmingwex.a:ctanhf.o T _ctanhf
    < libmingwex.a:ctanhl.o T _ctanhl
    < libmingwex.a:ctanl.o T _ctanl
    117,118c55,56
    < libmingwex.a:expm1f.o T _expm1f
    < libmingwex.a:expm1l.o T _expm1l
    ---
    > libmingwex.a:expm1f.o T _expm1
    > libmingwex.a:expm1l.o T _expm1
    120,121c58,59
    < libmingwex.a:fabsf.o T _fabsf
    < libmingwex.a:fabsl.o T _fabsl
    ---
    > libmingwex.a:fabsf.o T _fabs
    > libmingwex.a:fabsl.o T _fabs
    123,124c61,62
    < libmingwex.a:fdimf.o T _fdimf
    < libmingwex.a:fdiml.o T _fdiml
    ---
    > libmingwex.a:fdimf.o T _fdim
    > libmingwex.a:fdiml.o T _fdim
    142,143c80,81
    < libmingwex.a:fmaxf.o T _fmaxf
    < libmingwex.a:fmaxl.o T _fmaxl
    ---
    > libmingwex.a:fmaxf.o T _fmax
    > libmingwex.a:fmaxl.o T _fmax
    145,146c83,84
    < libmingwex.a:fminf.o T _fminf
    < libmingwex.a:fminl.o T _fminl
    ---
    > libmingwex.a:fminf.o T _fmin
    > libmingwex.a:fminl.o T _fmin
    151,152c89,90
    < libmingwex.a:fp_constsf.o T _nanf
    < libmingwex.a:fp_constsl.o T _nanl
    ---
    > libmingwex.a:fp_constsf.o T _nan
    > libmingwex.a:fp_constsl.o T _nan
    154,155c92,93
    < libmingwex.a:fpclassifyf.o T ___fpclassifyf
    < libmingwex.a:fpclassifyl.o T ___fpclassifyl
    ---
    > libmingwex.a:fpclassifyf.o T ___fpclassify
    > libmingwex.a:fpclassifyl.o T ___fpclassify
    173a112,113
    > libmingwex.a:glob.o T ___mingw_glob
    > libmingwex.a:glob.o T ___mingw_globfree
    190,193c130,133
    < libmingwex.a:isnanf.o T ___isnanf
    < libmingwex.a:isnanf.o T _isnanf
    < libmingwex.a:isnanl.o T ___isnanl
    < libmingwex.a:isnanl.o T _isnanl
    ---
    > libmingwex.a:isnanf.o T ___isnan
    > libmingwex.a:isnanf.o T _isnan
    > libmingwex.a:isnanl.o T ___isnan
    > libmingwex.a:isnanl.o T _isnan
    204,208c144,145
    < libmingwex.a:llrintf.o T _llrintf
    < libmingwex.a:llrintl.o T _llrintl
    < libmingwex.a:llround.o T _llround
    < libmingwex.a:llroundf.o T _llroundf
    < libmingwex.a:llroundl.o T _llroundl
    ---
    > libmingwex.a:llrintf.o T _llrint
    > libmingwex.a:llrintl.o T _llrint
    220,221c157,158
    < libmingwex.a:logbf.o T _logbf
    < libmingwex.a:logbl.o T _logbl
    ---
    > libmingwex.a:logbf.o T _logb
    > libmingwex.a:logbl.o T _logb
    225,226c162,163
    < libmingwex.a:lrintf.o T _lrintf
    < libmingwex.a:lrintl.o T _lrintl
    ---
    > libmingwex.a:lrintf.o T _lrint
    > libmingwex.a:lrintl.o T _lrint
    228,229c165,166
    < libmingwex.a:lroundf.o T _lroundf
    < libmingwex.a:lroundl.o T _lroundl
    ---
    > libmingwex.a:lroundf.o T _lround
    > libmingwex.a:lroundl.o T _lround
    234a172
    > libmingwex.a:membarrier.o T ___mingworg_MemoryBarrier
    264c202
    < libmingwex.a:nexttowardf.o T _nexttowardf
    ---
    > libmingwex.a:nexttowardf.o T _nexttoward
    265a204
    > libmingwex.a:pow.o T _pow
    271a211
    > libmingwex.a:qnan.o T _main
    279,280c219,220
    < libmingwex.a:rintf.o T _rintf
    < libmingwex.a:rintl.o T _rintl
    ---
    > libmingwex.a:rintf.o T _rint
    > libmingwex.a:rintl.o T _rint
    282,283c222,223
    < libmingwex.a:roundf.o T _roundf
    < libmingwex.a:roundl.o T _roundl
    ---
    > libmingwex.a:roundf.o T _round
    > libmingwex.a:roundl.o T _round
    296,299c236,239
    < libmingwex.a:signbitf.o T ___signbitf
    < libmingwex.a:signbitf.o T _signbitf
    < libmingwex.a:signbitl.o T ___signbitl
    < libmingwex.a:signbitl.o T _signbitl
    ---
    > libmingwex.a:signbitf.o T ___signbit
    > libmingwex.a:signbitf.o T _signbit
    > libmingwex.a:signbitl.o T ___signbit
    > libmingwex.a:signbitl.o T _signbit
    342,343c282,283
    < libmingwex.a:truncf.o T _truncf
    < libmingwex.a:truncl.o T _truncl
    ---
    > libmingwex.a:truncf.o T _trunc
    > libmingwex.a:truncl.o T _trunc
    

    where '<' refers to a downloaded libmingwex.a (from w32api 3.17 i think), and '>' refers to the library just built.

    Note especially the '_main' entries from qnan.o and arithchk.o, which should definitely not be there.

    Thanks for your reply.

     

    Related

    Issues: #2151
    Issues: #2156

  • Keith Marshall

    Keith Marshall - 2014-01-22

    ... I opted for

    m4_define([_AC_COMPILER_EXEEXT])
    

    as a temporary one-liner in (a new) aclocal.m4,

    Might work too, ...

    It does.

    ... but i would suggest to put it in configure.ac instead.

    No, that would be a bad idea. Firstly, as it is it's a temporary hack, so it's much easier to keep it in a separate file, which is not tracked. Secondly, the more elegantly derived solution will require additional autoconf macros, which are more appropriately defined in aclocal.m4; this would then become a new tracked file.

     
  • Keith Marshall

    Keith Marshall - 2014-01-22
    $ ~/mingw32/bin/i686-pc-mingw32-nm -A libmingwex.a | grep ' T ' | grep fabs
    libmingwex.a:fabs.o:00000000 T _fabs
    libmingwex.a:fabsf.o:00000000 T _fabs
    libmingwex.a:fabsl.o:00000000 T _fabs
    

    so the objects are there, but they just all export fabs (without suffix)

    I don't know what has gone awry with your build, but I am not seeing this; for me, it works just fine:

    $ mingw32-nm -A libmingwex.a | grep 'T.*fabs'
    libmingwex.a:fabs.o:00000000 T _fabs
    libmingwex.a:fabsf.o:00000000 T _fabsf
    libmingwex.a:fabsl.o:00000000 T _fabsl
    

    Note especially the '_main' entries from qnan.o and arithchk.o, which should definitely not be there.

    Yes, I'm seeing them too:

    $ mingw32-nm -A libmingwex.a | grep 'T.*main'
    libmingwex.a:qnan.o:00000000 T _main
    libmingwex.a:arithchk.o:00000000 T _main
    libmingwex.a:remainder.o:00000000 T _remainder
    libmingwex.a:remainderf.o:00000000 T _remainderf
    libmingwex.a:remainderl.o:00000000 T _remainderl
    
    $ mingw32-nm -A libmingwex.a | grep qnan
    libmingwex.a:qnan.o:00000000 b .bss
    libmingwex.a:qnan.o:00000000 d .data
    libmingwex.a:qnan.o:00000000 N .debug_abbrev
    libmingwex.a:qnan.o:00000000 N .debug_aranges
    libmingwex.a:qnan.o:00000000 N .debug_info
    libmingwex.a:qnan.o:00000000 N .debug_line
    libmingwex.a:qnan.o:00000000 N .debug_loc
    libmingwex.a:qnan.o:00000000 N .debug_ranges
    libmingwex.a:qnan.o:00000000 r .eh_frame
    libmingwex.a:qnan.o:00000000 T _main
    libmingwex.a:qnan.o:         U ___main
    libmingwex.a:qnan.o:         U _printf
    libmingwex.a:qnan.o:00000000 r .rdata
    libmingwex.a:qnan.o:00000000 r .rdata$zzz
    libmingwex.a:qnan.o:00000000 t .text
    libmingwex.a:qnan.o:00000000 t .text.startup
    
    $ mingw32-nm -A libmingwex.a | grep arithchk
    libmingwex.a:arithchk.o:00000000 b .bss
    libmingwex.a:arithchk.o:00000000 b _dalign
    libmingwex.a:arithchk.o:00000000 d .data
    libmingwex.a:arithchk.o:00000000 N .debug_abbrev
    libmingwex.a:arithchk.o:00000000 N .debug_aranges
    libmingwex.a:arithchk.o:00000000 N .debug_info
    libmingwex.a:arithchk.o:00000000 N .debug_line
    libmingwex.a:arithchk.o:00000000 N .debug_loc
    libmingwex.a:arithchk.o:00000000 N .debug_ranges
    libmingwex.a:arithchk.o:00000000 r .eh_frame
    libmingwex.a:arithchk.o:00000000 D _emptyfmt
    libmingwex.a:arithchk.o:         U _fprintf
    libmingwex.a:arithchk.o:         U _fwrite
    libmingwex.a:arithchk.o:         U __imp___iob
    libmingwex.a:arithchk.o:00000000 T _main
    libmingwex.a:arithchk.o:         U ___main
    libmingwex.a:arithchk.o:00000000 r .rdata
    libmingwex.a:arithchk.o:00000000 r .rdata$zzz
    libmingwex.a:arithchk.o:00000000 t .text
    libmingwex.a:arithchk.o:00000000 t .text.startup
    

    I agree that these are definitely incorrect, and would merit a separate bug report.

     
  • Thorsten Otto

    Thorsten Otto - 2014-01-23

    I don't know what has gone awry with your build, but I am not seeing this; >for me, it works just fine:

    Hm, i'm not sure. The Makefile.in reads:

    SRCDIR := src/libcrt/math
    $(SRCDIR)/%f.o: $(SRCDIR)/%.c
        $(MKDIR_P) $(@D)
        $(CC) -c -D FUNCTION=$(@F:.o=) $(CPPFLAGS) $(ALL_CFLAGS) -o $@ $<
    
    $(SRCDIR)/%l.o: $(SRCDIR)/%.c
        $(MKDIR_P) $(@D)
        $(CC) -c -D FUNCTION=$(@F:.o=) $(CPPFLAGS) $(ALL_CFLAGS) -o $@ $<
    

    So the build did what it says, and compiled fabs.c 3 times. But unlike some other sources, fabs.c does not compile to different versions depending on FUNCTION being defined. My patch changed the pattern rules to

    $(SRCDIR)/%f.o: $(SRCDIR)/%f.c
    

    and

    $(SRCDIR)/%l.o: $(SRCDIR)/%l.c
    

    and added asinhf.c and asinhl.c, the only 2 files that were missing.
    Were you building in the source tree? Maybe that makes a difference,
    src/libcrt/math/fabs.c of course is only found via VPATH.
    The only other reason i can think of is due to different versions of make we are using (mine is 3.82, Built for x86_64-unknown-linux-gnu)
    IMHO the pattern rules were just wrong.

    Firstly, as it is it's a temporary hack, so it's much easier to keep it in a >separate file,

    Ah, ok, I thought you wanted to keep it like that. As long as there are no executables build in this tree, there is actually not much reason to put more effort in this.