[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [MiNT] g++ problem with archives & linking
On Thu, 2008-02-21 at 23:03 +0100, Vincent Rivière wrote:
> Alan Hourihane wrote:
> > this works fine on Linux, even with using -static or without.
>
> First of all, run the gcc link command using -v in order to see the ld
> command line:
>
> $ m68k-atari-mint-gcc -o main libtest.a -v
> Using built-in specs.
> Target: m68k-atari-mint
> Configured with: ../gcc-4.2.3-mint-20080217/configure
> --target=m68k-atari-mint --prefix=/usr/local/cross-mint
> --enable-languages=c,c++ --disable-nls --disable-libstdcxx-pch
> Thread model: single
> gcc version 4.2.3 (MiNT 20080217)
>
> /usr/local/cross-mint/lib/gcc/m68k-atari-mint/4.2.3/../../../../m68k-atari-mint/bin/ld.exe
> -o main
> /usr/local/cross-mint/lib/gcc/m68k-atari-mint/4.2.3/../../../../m68k-atari-mint/lib/crt0.o
> -L/usr/local/cross-mint/lib/gcc/m68k-atari-mint/4.2.3
> -L/usr/local/cross-mint/lib/gcc/m68k-atari-mint/4.2.3/../../../../m68k-atari-mint/lib
> libtest.a -lgcc -lc -lgcc
> /usr/local/cross-mint/lib/gcc/m68k-atari-mint/4.2.3/../../../../m68k-atari-mint/lib/libc.a(main.o):main.o:(.text+0x312):
> undefined reference to `_main'
> /usr/local/cross-mint/lib/gcc/m68k-atari-mint/4.2.3/../../../../m68k-atari-mint/lib/libc.a(main.o):main.o:(.text+0x61e):
> undefined reference to `_main'
>
>
> The input files are (the order is important):
> /usr/local/cross-mint/m68k-atari-mint/lib/crt0.o
> libtest.a
> -lgcc #/usr/local/cross-mint/lib/gcc/m68k-atari-mint/4.2.3/libgcc.a
> -lc #/usr/local/cross-mint/m68k-atari-mint/lib/libc.a
> -lgcc #/usr/local/cross-mint/lib/gcc/m68k-atari-mint/4.2.3/libgcc.a
>
> The key to the explanation is that ld searches for undefined symbols in
> the next input files, but not in the previously unused input files.
>
> The linker begins by linking the first file (crt0.o) and it tries to
> resolve the externals.
>
> $ m68k-atari-mint-nm -u /usr/local/cross-mint/m68k-atari-mint/lib/crt0.o
> U ___Ident_gem
> U ___Ident_gnulib
> U ___Ident_socketlib
> U __acc_main
> U __app
> U __base
> U __crtinit
> U __heapbase
> U __stksize
>
> We see that crt0.o has several undefined externals (notably __crtinit)
> but no reference to the _main symbol.
>
> Then the linker looks to libtest.a. It contains none of the required
> externals (only a useless _main symbol), so it is totally skipped.
>
> Same skip for libgcc.a (the first one)
>
> Then it looks to libc.a (the MiNTLib). The symbol __crtinit is resolved,
> but a new unresolved external for _main is generated.
>
> Then it looks to libgcc.a (second time). Most symbols are now resolved,
> but not _main.
>
> There are no more input files.
>
> So no definition of _main is found after the reference, it is a link error.
>
> A trick is to provide the linker a reference to _main before the definition:
>
> $ m68k-atari-mint-gcc -o main -lc libtest.a # That works !
>
>
> I tried your testcase with Cygwin, and like in Linux, it works fine
> without any trick from the user.
> How ? The explanation is in Cygwin's file crt0.c:
> http://cygwin.com/cgi-bin/cvsweb.cgi/~checkout~/src/winsup/cygwin/crt0.c?rev=1.4&content-type=text/plain&cvsroot=src
> The startup code calls cygwin_crt0() (the equivalent of our MiNTLib
> _crtinit() with the main function as a parameter. So the startup code
> has a reference to main(). So the main() function provided by the user
> is always linked, even if it is in a library.
>
> It would be easy to do get the same behavior with the MiNTLib: we just
> have to add a "main" parameter to _crtinit()
>
> However, I don't know if such a behavior should be assumed to be a
> standard...
Ah, thanks for the solution Vincent. I'm going to modify my MiNTlib to
do this.
Alan.