Dynamic linking again
Andre Pang
ozone@algorithm.com.au
Wed, 4 Sep 2002 16:02:43 +1000
On Mon, Sep 02, 2002 at 03:16:37 +0100, Simon Marlow wrote:
> > ghc -optl-export-dynamic -ldl -L/usr/lib/ghc-5.04/ -lHSrts
> > -lHSlang \
> > TestDLink.o -o TestDLink
> >
> > since doing
> >
> > ghc -optl-export-dynamic -ldl -package rst -package lang \
> > TestDLink.o -o TestDLink
> >
> > gives:
> > /usr/lib/ghc-5.04/libHSrts.a(RtsAPIDeprec.o): In function
> > `rts_mkAddr':
> > RtsAPIDeprec.o(.text+0x14): undefined reference to `Addr_Azh_con_info'
> > /usr/lib/ghc-5.04/libHSrts.a(RtsAPIDeprec.o): In function
> > `rts_getAddr':
> > RtsAPIDeprec.o(.text+0x2d): undefined reference to `Addr_Azh_con_info'
> > RtsAPIDeprec.o(.text+0x35): undefined reference to
> > `Addr_Azh_static_info'
> > collect2: ld returned 1 exit status
>
> I'm not sure exactly what's going here. RtsAPIDeprec.o does refer to
> Addr_Azh_con_info, which is defined in the Addr module in the lang
> package. However, RtsAPIDeprec normally isn't linked in, because
> nothing refers to anything in it.
RtsAPIDeprec.o is in libHSrts.a (as the error message says).
Therefore using libHSrts.a means that you'll get all of
RtsAPIDeprec.o along with it, and therefore need to resolve all
its unresolved symbols.
I think I also understand why using -package doesn't work. I'll
paste in two (cropped) gcc lines below; the first line is when
you use the "-lHSrts -lHSlang" options (which works), and the
second is when you use "-package rts -package -lang" (which
doesn't work):
... -L/usr/lib/ghc-5.04 -L/usr/lib/gcc-lib/i386-linux/3.2 -L/usr/lib/gcc-lib/i386-linux/3.2/../../.. Main.o -ldl -lHSlang -lHSlang_cbits -lHShaskell98 -lHSbase -lHSbase_cbits -lHSrts -lgmp -lm -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i386-linux/3.2/crtend.o /usr/lib/gcc-lib/i386-linux/3.2/../../../crtn.o
... -L/usr/lib/ghc-5.04/ -L/usr/lib/ghc-5.04 -L/usr/lib/gcc-lib/i386-linux/3.2 -L/usr/lib/gcc-lib/i386-linux/3.2/../../.. /usr/lib/ghc-5.04/HSbase.o Main.o -ldl -lHSrts -lHSlang -lHShaskell98 -lHSbase -lHSbase_cbits -lHSrts -lgmp -lm -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i386-linux/3.2/crtend.o /usr/lib/gcc-lib/i386-linux/3.2/../../../crtn.o
.. so the only real difference between the line which works and
the line which doesn't work is:
* line which works has /usr/lib/ghc-5.04/HSbase.o
* line which works has an extra -lHSrts flag
It turns out that the pedant linker needs to see the -lHSrts flag
before -lHSlang. This is a bit odd, since the HSlang library is
the one which has the required "Addr_Azh_con_info" symbol. Of
course, ld(1) says:
-( archives -)
--start-group archives --end-group
The archives should be a list of archive files. They may be
either explicit file names, or -l options.
The specified archives are searched repeatedly until no new
undefined references are created. Normally, an archive is
searched only once in the order that it is specified on the
command line. If a symbol in that archive is needed to
resolve an undefined symbol referred to by an object in an
archive that appears later on the command line, the linker
would not be able to resolve that reference. By grouping
the archives, they all be searched repeatedly until all
possible references are resolved.
Using this option has a significant performance cost. It
is best to use it only when there are unavoidable circular
references between two or more archives.
I'd classify this as an ld problem, but we still have to work
around it.
Aaaaanyway, using either "-package lang -package rts" or
"-package rts -package lang" doesn't affect the order of the -l
options, so we probably have to whack it in there manually.
--
#ozone/algorithm <ozone@algorithm.com.au> - trust.in.love.to.save