[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 =)
>> -tom

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 
after lib2.

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 mailing list