Opened 18 years ago

Closed 18 years ago

Last modified 6 years ago

#2502 closed defect (fixed)

Linker error when compiling minimal ScummVM

Reported by: eriktorbjorn Owned by: fingolfin
Priority: normal Component: Port: Linux
Version: Keywords:
Cc: Game:

Description

While looking at a BS2 bug a while ago, I tried to compile a minimal version with only the BS2 engine included. At the time I had trouble building it, but since someone else helped me diagnose the bug, I didn't look any further into it.

Now I decided to try again, using the most recent SVN snapshot. This is the configure command I used:

./configure --disable-scumm --disable-simon --disable-sky --disable-sword1 --disable-queen --disable-saga --disable-gob --disable-kyra --disable-mt32emu --disable-scalers --disable-hq-scalers --disable-mad --disable-flac --disable-fluidsynth --disable-nasm

Which for me meant I ended up with the following features:

Engines: Broken Sword 2 (w/ mpeg2 cutscenes)

Backend... sdl Looking for sdl-config... /usr/bin/sdl-config

Compiling seemed to go well, all the way to the final linking, which produced the following output, which I'm not sure quite how to interpret:

g++ backends/sdl/events.o backends/sdl/graphics.o backends/sdl/sdl.o base/libbase.a engines/sword2/libsword2.a gui/libgui.a graphics/libgraphics.a sound/libsound.a backends/libbackends.a common/libcommon.a
-lvorbisfile -lvorbis -logg -lasound -lz -lmpeg2 -L/usr/lib -lSDL -lpthread -o scummvm backends/libbackends.a(alsa.o): In function `MidiDriver_ALSA::close()':backends/midi/alsa.cpp:137: undefined reference to `MidiDriver_MPU401::close()' backends/libbackends.a(alsa.o): In function `MidiDriver_ALSA':backends/midi/alsa.cpp:77: undefined reference to `MidiDriver_MPU401::MidiDriver_MPU401()' :backends/midi/alsa.cpp:77: undefined reference to `MidiDriver_MPU401::MidiDriver_MPU401()' backends/libbackends.a(alsa.o):(.gnu.linkonce.r._ZTI15MidiDriver_ALSA[typeinfo for MidiDriver_ALSA]+0x8): undefined reference to `typeinfo for MidiDriver_MPU401' backends/libbackends.a(alsa.o):(.gnu.linkonce.r._ZTV15MidiDriver_ALSA[vtable for MidiDriver_ALSA]+0x1c): undefined reference to `MidiDriver_MPU401::property(int, unsigned int)' backends/libbackends.a(alsa.o):(.gnu.linkonce.r._ZTV15MidiDriver_ALSA[vtable for MidiDriver_ALSA]+0x30): undefined reference to `MidiDriver_MPU401::setTimerCallback(void*, void (*)(void*))' backends/libbackends.a(alsa.o):(.gnu.linkonce.r._ZTV15MidiDriver_ALSA[vtable for MidiDriver_ALSA]+0x38): undefined reference to `MidiDriver_MPU401::allocateChannel()' backends/libbackends.a(alsa.o): In function `~MidiDriver_MPU401':./sound/mpu401.h:71: undefined reference to `vtable for MidiDriver_MPU401' :./sound/mpu401.h:71: undefined reference to `vtable for MidiDriver_MPU401' backends/libbackends.a(null.o): In function `MidiDriver_NULL':backends/midi/null.cpp:26: undefined reference to `MidiDriver_MPU401::MidiDriver_MPU401()' backends/libbackends.a(null.o):(.gnu.linkonce.r._ZTV15MidiDriver_NULL[vtable for MidiDriver_NULL]+0x14): undefined reference to `MidiDriver_MPU401::close()' backends/libbackends.a(null.o):(.gnu.linkonce.r._ZTV15MidiDriver_NULL[vtable for MidiDriver_NULL]+0x1c): undefined reference to `MidiDriver_MPU401::property(int, unsigned int)' backends/libbackends.a(null.o):(.gnu.linkonce.r._ZTV15MidiDriver_NULL[vtable for MidiDriver_NULL]+0x30): undefined reference to `MidiDriver_MPU401::setTimerCallback(void*, void (*)(void*))' backends/libbackends.a(null.o):(.gnu.linkonce.r._ZTV15MidiDriver_NULL[vtable for MidiDriver_NULL]+0x38): undefined reference to `MidiDriver_MPU401::allocateChannel()' backends/libbackends.a(null.o):(.gnu.linkonce.r._ZTI15MidiDriver_NULL[typeinfo for MidiDriver_NULL]+0x8): undefined reference to `typeinfo for MidiDriver_MPU401' backends/libbackends.a(null.o): In function `~MidiDriver_MPU401':./sound/mpu401.h:71: undefined reference to `vtable for MidiDriver_MPU401' :./sound/mpu401.h:71: undefined reference to `vtable for MidiDriver_MPU401' backends/libbackends.a(seq.o): In function `MidiDriver_SEQ::close()':backends/midi/seq.cpp:97: undefined reference to `MidiDriver_MPU401::close()' backends/libbackends.a(seq.o): In function `MidiDriver_SEQ':backends/midi/seq.cpp:56: undefined reference to `MidiDriver_MPU401::MidiDriver_MPU401()' :backends/midi/seq.cpp:56: undefined reference to `MidiDriver_MPU401::MidiDriver_MPU401()' backends/libbackends.a(seq.o):(.gnu.linkonce.r._ZTI14MidiDriver_SEQ[typeinfo for MidiDriver_SEQ]+0x8): undefined reference to `typeinfo for MidiDriver_MPU401' backends/libbackends.a(seq.o):(.gnu.linkonce.r._ZTV14MidiDriver_SEQ[vtable for MidiDriver_SEQ]+0x1c): undefined reference to `MidiDriver_MPU401::property(int, unsigned int)' backends/libbackends.a(seq.o):(.gnu.linkonce.r._ZTV14MidiDriver_SEQ[vtable for MidiDriver_SEQ]+0x30): undefined reference to `MidiDriver_MPU401::setTimerCallback(void*, void (*)(void*))' backends/libbackends.a(seq.o):(.gnu.linkonce.r._ZTV14MidiDriver_SEQ[vtable for MidiDriver_SEQ]+0x38): undefined reference to `MidiDriver_MPU401::allocateChannel()' backends/libbackends.a(seq.o): In function `~MidiDriver_MPU401':./sound/mpu401.h:71: undefined reference to `vtable for MidiDriver_MPU401' :./sound/mpu401.h:71: undefined reference to `vtable for MidiDriver_MPU401' collect2: ld returned 1 exit status make: *** [scummvm] Error 1

Ticket imported from: #1435221. Ticket imported from: bugs/2502.

Attachments (2)

config.h (737 bytes ) - added by eriktorbjorn 18 years ago.
Generated config.h
config.mak (908 bytes ) - added by eriktorbjorn 18 years ago.
Generated config.mak

Download all attachments as: .zip

Change History (9)

by eriktorbjorn, 18 years ago

Attachment: config.h added

Generated config.h

by eriktorbjorn, 18 years ago

Attachment: config.mak added

Generated config.mak

comment:1 by eriktorbjorn, 18 years ago

I forgot to say:

g++ identifies itself as "g++ (GCC) 4.0.3 20060212 (prerelease) (Debian 4.0.2-9)"

ld identified itself as "GNU ld version 2.16.91 20060118 Debian GNU/Linux"

comment:2 by fingolfin, 18 years ago

I can reproduce the problem. Roughly said, this happens: "backends" (which contains the MIDI drivers) is linked in after "sound" (which contains MidiDriver_MPU401). Due to the way Unix linkers, this causes problems if nothing else references to the parts of "sound" which are required by "backends".

So the first natural idea is to swap the link order of "backends" and "sound". But this doesn't really solve the issue, because "sound" also refers to the MIDI code in backends (via MidiDriver::createMidi)... so this is a circular reference.

To break the circle, we need to move some code. E.g. we could move the functionality MidiDriver::createMidi to a new source file in backends/midi/. Or we could move all the MIDI drivers to a new sound/midi/drivers directory (and move the various sound/midi*.* files to sound/midi/).

comment:3 by sev-, 18 years ago

Yes, I faced exactly the same situation when built ScummVM for Nokia 770 which doesn't have sequencer, so I had to use null MIDI driver for it. Since of use of virtual functions there, null driver couldn't get all methods and compiler spitted similiar errors. I resolved it by moving null.cpp to sound/ directory, but did not commit it as it is very hackish solution.

comment:4 by cyxx, 18 years ago

I had the same problem while working on the queen module.

At the time, I "fixed" it by using the GNU ld specific option --whole-archive. Not the nicest solution, but as a workaround, it worked nicely.

comment:5 by fingolfin, 18 years ago

I fixed this for now by moving null.cpp to sound/ (like Eugene suggested). While this is hackish, it is portable, and actually does make some sense -- all other files in backends/midi constitute drivers that only work on certain system (which is why they belong into backends/), the only exception was null.cpp (which obviously "works" everywhere)... :-). Of course it's still somewhat arbitrary, but it works.

comment:6 by fingolfin, 18 years ago

Owner: set to fingolfin
Resolution: fixed
Status: newclosed

comment:7 by digitall, 6 years ago

Component: Port: Linux
Note: See TracTickets for help on using tickets.