[quake2] revamped build system
Asfand Yar Qazi
email at asfandyar.cjb.net
Sun Sep 19 13:07:37 EDT 2004
> On Sep 18, 2004, at 2:40 PM, tom fogal wrote:
>> Hey all, I was trying to redo the build system in a (at least what I
>> feel to be) better way, and I just can't get things to link correctly.
>> I was hoping someone here has more quake2 or unix lore and could help
>> me out.
>> sdlquake2 builds with a line like the following:
>> gcc -Wall -pipe -Dstricmp=strcasecmp -DQMAX -g
>> -DLINUX_VERSION='"3.21+rCVS Debug"' -o debugi386/sdlquake2
>> debugi386/client/cl_cin.o debugi386/client/cl_ents.o
>> debugi386/client/cl_fx.o debugi386/client/cl_input.o
>> debugi386/client/cl_inv.o debugi386/client/cl_main.o
>> debugi386/client/cl_parse.o debugi386/client/cl_pred.o
>> debugi386/client/cl_tent.o debugi386/client/cl_scrn.o
>> debugi386/client/cl_view.o debugi386/client/cl_newfx.o
>> debugi386/client/console.o debugi386/client/keys.o
>> debugi386/client/menu.o debugi386/client/snd_dma.o
>> debugi386/client/snd_mem.o debugi386/client/snd_mix.o
>> debugi386/client/qmenu.o debugi386/client/m_flash.o
>> debugi386/client/cmd.o debugi386/client/cmodel.o
>> debugi386/client/common.o debugi386/client/crc.o
>> debugi386/client/cvar.o debugi386/client/files.o
>> debugi386/client/md4.o debugi386/client/net_chan.o
>> debugi386/client/sv_ccmds.o debugi386/client/sv_ents.o
>> debugi386/client/sv_game.o debugi386/client/sv_init.o
>> debugi386/client/sv_main.o debugi386/client/s!
>> v_send.o debugi386/client/sv_user.o debugi386/client/sv_world.o
>> debugi386/client/q_shlinux.o debugi386/client/vid_menu.o
>> debugi386/client/vid_so.o debugi386/client/sys_linux.o
>> debugi386/client/glob.o debugi386/client/net_udp.o
>> debugi386/client/q_shared.o debugi386/client/pmove.o
>> debugi386/client/cd_sdl.o debugi386/client/snd_sdl.o
>> debugi386/client/snd_mixa.o -lm -ldl -L/usr/lib -Wl,-rpath,/usr/lib
>> -lSDL -lpthread
>> (sorry, you might have to turn line wrapping on for that - to
>> summarize, 'gcc', some CFLAGS, a bunch of object files from a mix
>> of client/, server/, and linux/, and '-lm -ldl -
>> L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread')
>> I'm trying to make each directory into its own module of sorts,
>> archived into a static library and then linked in when appropriate.
>> I've pruned the archives so they only have the objects specified in the
>> above commandline, but when I used a line such as:
>> gcc -g -Wall -pipe -DQMAX -DLINUX_VERSION="\"3.21+\"" -Lclient/ \
>> -Llinux/ -Lqcommon/ -Lserver/ -llinux -lclient -lserver -lqcommon -lm \
>> -ldl -Wl,-rpath,/usr/lib -lSDL -lpthread
>> I get a lot of undefined references to VectorMA and some other vector
>> functions or globals. I even tried linking in the 'game' modules shared
>> object (aka "gamei386.so"), which got rid of a lot of undefined
>> references but still leaves me with a lot of undefined references to
>> 'NET_'* and 'CDAudio_'*.
>> Any ideas? BTW, my platform is linux if that matters much.
>> As an aside, the motivation for this is ease of new additions to the
>> engine. I am (was...) trying to add OpenGL-based dynamic lighting
>> (instead of multi-texturing lightmaps) and wanted to add a new file to
>> the build system, but it was not entirely intuitive.
>> As I've been doing this I noticed a lot of awkwardness in the engine,
>> like using 'extern <function_prototype>' instead of having header
>> files, which seems unsafe to me. So now I'm more interested in making
>> the build system catch stupidities as early as possible in the
>> compile/link/run stages. I don't know if these changes/additions would
>> be interesting to others, as I'm being kind of lax in keeping non-q2max,
>> software rendering, etc. working. If theres enough interest though, I
>> could be convinced in being more diligent in making sure those work.
>> Whew, that was long. Thanks for reading this far =)
I think that when resolving external dependancies, ld only
searches libraries on the command line AFTER the library / object
file that contained that undefined reference.
ld -o bogit -llib1 -llib2
If lib1 contains a reference to something in lib2, it'll get
resolved. But if lib2 contains a reference to an external
variable or function in lib1, it WON'T get resolved, since lib1
isn't searched for undefined references as it doesn't appear
Putting all object files on the command line makes ld search
every object file for every dependancy, which is why I think that
To fix this, do the following-like:
gcc -g -Wall -pipe -DQMAX -DLINUX_VERSION="\"3.21+\"" \
-Lclient/ -Llinux/ -Lqcommon/ -Lserver/ \
-Wl,-( -llinux -lclient -lserver -lqcommon -Wl,-) -lm \
-ldl -Wl,-rpath,/usr/lib -lSDL -lpthread
Do a 'man ld' and search for the option '--begin-group'
(abbreviated to '-(' ) - enclosing the libs in -( and -) makes
ld search every archive in that group for every external
dependancy in that group. I hope that works.
More information about the quake2