#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)
Change History (9)
by , 19 years ago
comment:1 by , 19 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 , 19 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 , 19 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 , 19 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 , 19 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 , 19 years ago
Owner: | set to |
---|---|
Resolution: | → fixed |
Status: | new → closed |
comment:7 by , 6 years ago
Component: | → Port: Linux |
---|
Generated config.h