Fixing --as-needed problems - Example 1

sparky at pld-linux.org sparky at pld-linux.org
Sun Aug 6 19:31:19 CEST 2006


WARNING: Way of disabling --as-needed in spec changed from:
 %define no_build_with_as_needed 1
to more generic one:
 %define filterout_ld -Wl,--as-needed

but, DON'T USE IT ! Fix spec instead.
Why ? Because it's very stupid. If something fails to build normally
it's a sign --as-needed did well it's job and disabled unneeded
libraries.

Here goes a little example, xmoto:

With -Wl,--as-needed enabled it stops on something like this:

==========================================================================
x86_64-pld-linux-g++ -DNOMMGR -Wall -DGAMEDATADIR=\"/usr/share/xmoto\"  -mfpmath=sse -ggdb -O2 -ftree-vectorize -ftree-vectorizer-verbose=1 -march=athlon64 -mmmx -msse -msse2 -m3dnow  -s -Wl,--as-needed -Wl,-s  -o xmoto-edit  BuiltInFont.o Image.o LevelSrc.o VApp.o VBezier.o VDraw.o VDrawText.o VFileIO.o VMath.o VTexture.o VXml.o tim.o tim_io_stdio.o tim_jpeg.o tim_memory_crt.o tim_png.o tinystr.o tinyxml.o tinyxmlerror.o tinyxmlparser.o md5.o md5file.o FileCompression.o SwapEndian.o DBuffer.o CRCHash.o Theme.o WWW.o Editor.o EditorMain.o EditorData.o EditorLog.o Packager.o -lGL -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lbz2 -lz -lpng -ljpeg
VApp.o: In function `vapp::App::getRealTime()':
src/VApp.cpp:287: undefined reference to `SDL_GetTicks'
VApp.o: In function `vapp::App::getTime()':
src/VApp.cpp:284: undefined reference to `SDL_GetTicks'
[... bunch of SDL functions ...]
Editor.o: In function `vapp::EditorApp::viewDrawGrid()':
src/Editor.cpp:777: undefined reference to `SDL_GetMouseState'
Editor.o:src/Editor.cpp:46: more undefined references to `SDL_GetMouseState' follow
EditorMain.o: In function `main':
src/EditorMain.cpp:59: undefined reference to `SDL_Quit'
collect2: ld returned 1 exit status
make[1]: *** [xmoto-edit] Error 1
==========================================================================


So let's try to find some of missing symbols:

[sparky at th-chroot SPECS]$ grep SDL_GetMouseState /usr/lib64/libSDL*
Binary file /usr/lib64/libSDL-1.2.so.0 matches
Binary file /usr/lib64/libSDL-1.2.so.0.11.0 matches
Binary file /usr/lib64/libSDL.so matches

they are in -lSDL, but binary does not link with -lSDL;
edit Makefile by hand and add -lSDL at the same place as -lSDL_mixer is:
LIBS = -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lbz2 -lz -lpng -ljpeg

What we get after running make in build tree:

==========================================================================
x86_64-pld-linux-g++ -DNOMMGR -Wall -DGAMEDATADIR=\"/usr/share/xmoto\"  -mfpmath=sse -ggdb -O2 -ftree-vectorize -ftree-vectorizer-verbose=1 -march=athlon64 -mmmx -msse -msse2 -m3dnow  -s -Wl,--as-needed -Wl,-s  -o xmoto-edit  BuiltInFont.o Image.o LevelSrc.o VApp.o VBezier.o VDraw.o VDrawText.o VFileIO.o VMath.o VTexture.o VXml.o tim.o tim_io_stdio.o tim_jpeg.o tim_memory_crt.o tim_png.o tinystr.o tinyxml.o tinyxmlerror.o tinyxmlparser.o md5.o md5file.o FileCompression.o SwapEndian.o DBuffer.o CRCHash.o Theme.o WWW.o Editor.o EditorMain.o EditorData.o EditorLog.o Packager.o  -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lbz2 -lz -lpng -ljpeg 
VApp.o: In function `vapp::App::grabScreen()':
src/VApp.cpp:667: undefined reference to `glReadBuffer'
src/VApp.cpp:671: undefined reference to `glReadPixels'
[...]
src/Editor.cpp:1280: undefined reference to `glEnable'
src/Editor.cpp:1288: undefined reference to `glDisable'
collect2: ld returned 1 exit status
==========================================================================

Same thing:

[sparky at th-chroot xmoto-0.2.0]$ grep glEnableClientState /usr/lib64/lib*
Binary file /usr/lib64/libGL.so matches
Binary file /usr/lib64/libGL.so.1 matches
Binary file /usr/lib64/libGL.so.1.2 matches

LIBS = -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lGL -lbz2 -lz -lpng -ljpeg

But take a look at spec file, -lGL thing was fixed there already:

%{__make} \
	GL_LIBS="-lGL"

Anyway, lets run make, and what we get ?

==========================================================================
x86_64-pld-linux-g++ -DNOMMGR -Wall -DGAMEDATADIR=\"/usr/share/xmoto\"  -mfpmath=sse -ggdb -O2 -ftree-vectorize -ftree-vectorizer-verbose=1 -march=athlon64 -mmmx -msse -msse2 -m3dnow  -s -Wl,--as-needed -Wl,-s  -o xmoto-edit  BuiltInFont.o Image.o LevelSrc.o VApp.o VBezier.o VDraw.o VDrawText.o VFileIO.o VMath.o VTexture.o VXml.o tim.o tim_io_stdio.o tim_jpeg.o tim_memory_crt.o tim_png.o tinystr.o tinyxml.o tinyxmlerror.o tinyxmlparser.o md5.o md5file.o FileCompression.o SwapEndian.o DBuffer.o CRCHash.o Theme.o WWW.o Editor.o EditorMain.o EditorData.o EditorLog.o Packager.o  -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lGL -lbz2 -lz -lpng -ljpeg 
make[1]: Leaving directory `/home/users/sparky/rpm/BUILD/xmoto-0.2.0'
==========================================================================

It worked !


But why was it working without --as-needed ?
Answer is realy easy: libSDL is required by SDL_mixer:

[sparky at th-chroot xmoto-0.2.0]$ ldd /usr/lib64/libSDL_mixer-1.2.so.0.2.4 | grep SDL
        libSDL-1.2.so.0 => /usr/lib64/libSDL-1.2.so.0 (0x00002ab425307000)

but xmoto-edit contains no SDL_mixer symbols, that's why xmoto-edit
wasn't linked with SDL_mixer, and nothing provided SDL library


Can you see now why was it so stupid to disable --as-needed ? It worked
just perfectly !



Finally, fix for this may be:
%configure \
	LIBS="-lSDL -lGL"

or patching configure.in
and the result is:

Wrote: /home/users/sparky/rpm/RPMS/xmoto-0.2.0-2.x86_64.rpm

I hope this little example will help you.

-- 
 ____  Sparky{PI] -- Przemyslaw _  ___  _  _  ........... LANG...Pl..Ca..Es..En
/____) ___  ___  _ _ || Iskra  |  | _ \| |  | : WWW........ppcrcd.pld-linux.org
\____\| -_)'___| ||^'||//\\// <   |  _/| |  | : JID......sparky<at>jabberes.org
(____/||   (_-_|_||  ||\\ ||   |_ |_|  |_| _| : Mail....sparky<at>pld-linux.org


More information about the pld-devel-en mailing list