Linker trouble

Adam Jackson ajax at redhat.com
Fri Mar 26 15:16:58 UTC 2010


On Fri, 2010-03-26 at 06:38 +0100, Lubomir Rintel wrote:
> Hi,
> 
> I'm wondering if anyone could enlighten me about why does --as-needed
> make a difference here? (let alone the order in which -lGL appears).

Because order matters.

Linker arguments are positional.  Object files are walked left to right
along the command line, and are added to the link in order.  Archive
members are added to the link output if and only if a symbol in that
archive member satisfies a reference to a symbol mentioned earlier in
the link.  --as-needed extends this behaviour to DSOs, such that
libraries will only be added to the link if they satisfy a symbol
reference from an earlier object.

So in your first link line:

> [lkundrak at localhost VirtualBox-3.1.6_OSE]$ g++ -Wl,--as-needed \
> >         -o out/linux.x86/release/obj/VBoxTestOGL/VBoxTestOGL \
> >         out/linux.x86/release/obj/VBoxTestOGL/generic/OpenGLTestApp.o \
> >         -L/usr/X11R6/lib -L/usr/lib \
> >         -lGL \
> >         obj/lib/VBoxOGLhostspuload.a obj/bin/VBoxOGLhostcrutil.so obj/lib/VBoxOGL2D.a \
> >         obj/bin/VBoxRT.so obj/bin/VBoxRT.so obj/lib/VBoxREM.so obj/bin/VBoxVMM.so \
> >         -lXcursor -lXext -lX11 \
> >         obj/lib/VBoxCOM.a obj/bin/VBoxXPCOM.so \
> >         /usr/lib/libQtCore.so /usr/lib/libQtGui.so /usr/lib/libQtOpenGL.so

OpenGLTestApp.o is added.  libGL is looked at, but not added, since the
first .o (presumably) doesn't mention any symbol defined in libGL.
Later you add the VBoxOGL2D.a archive; VBoxGLSupportInfo.o provides some
symbol that one of the earlier objects needs, but adds references to
symbols that happen to be defined in libGL.  At no point later do you
mention libGL again. [1] Therefore:

> /usr/bin/ld: obj/lib/VBoxOGL2D.a(VBoxGLSupportInfo.o): undefined reference to symbol 'glGetString'

Whereas:

> [lkundrak at localhost VirtualBox-3.1.6_OSE]$ g++ -Wl,--as-needed \
> >         -o out/linux.x86/release/obj/VBoxTestOGL/VBoxTestOGL \
> >         out/linux.x86/release/obj/VBoxTestOGL/generic/OpenGLTestApp.o \
> >         -L/usr/X11R6/lib -L/usr/lib \
> >         obj/lib/VBoxOGLhostspuload.a obj/bin/VBoxOGLhostcrutil.so obj/lib/VBoxOGL2D.a \
> >         -lGL \
> >         obj/bin/VBoxRT.so obj/bin/VBoxRT.so obj/lib/VBoxREM.so obj/bin/VBoxVMM.so \
> >         -lXcursor -lXext -lX11 \
> >         obj/lib/VBoxCOM.a obj/bin/VBoxXPCOM.so \
> >         /usr/lib/libQtCore.so /usr/lib/libQtGui.so /usr/lib/libQtOpenGL.so

Here you link libGL _after_ an archive that requires it, so it's
included.  And:

> [lkundrak at localhost VirtualBox-3.1.6_OSE]$ g++ \
> >         -o out/linux.x86/release/obj/VBoxTestOGL/VBoxTestOGL \
> >         out/linux.x86/release/obj/VBoxTestOGL/generic/OpenGLTestApp.o \
> >         -L/usr/X11R6/lib -L/usr/lib \
> >         -lGL \
> >         obj/lib/VBoxOGLhostspuload.a obj/bin/VBoxOGLhostcrutil.so obj/lib/VBoxOGL2D.a \
> >         obj/bin/VBoxRT.so obj/bin/VBoxRT.so obj/lib/VBoxREM.so obj/bin/VBoxVMM.so \
> >         -lXcursor -lXext -lX11 \
> >         obj/lib/VBoxCOM.a obj/bin/VBoxXPCOM.so \
> >         /usr/lib/libQtCore.so /usr/lib/libQtGui.so /usr/lib/libQtOpenGL.so

Here you link without --as-needed, so a DT_NEEDED note for libGL is
emitted unconditionally; therefore, by the time you get to VBoxOGL2D.a,
libGL is included in the link already.

[1] - The new linker behaviour in F13 does change things.  Recall that
the default used to be "--add-needed", which has since been renamed
--copy-dt-needed-entries.  What this means is, when producing a dynamic
object as output, any DT_NEEDED entries in dynamic libraries mentioned
on the link line will be copied into the output.  The last library in
that link line, libQtOpenGL.so, almost certainly has a DT_NEEDED entry
for libGL.so already.  So, when doing --copy-dt-needed-entries, that
link line would have worked: the first mention of -lGL would have been
skipped over, but then it would have been included since libQtOpenGL had
a DT_NEEDED for it.  Now, in F13, since --no-copy-dt-needed-entries is
the default, this doesn't happen; DT_NEEDED entries are only emitted for
things you really declare that you need.  This is desirable; it allows
libraries to change the libraries they themselves depend on, without
necessarily requiring applications to also be recompiled.

- ajax
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
Url : http://lists.fedoraproject.org/pipermail/devel/attachments/20100326/3392caf1/attachment.bin 


More information about the devel mailing list