Building Software with gcc and make

At the heart of the development tool chain is the compiler. The compiler used in all the setups shown here is gcc.

If you are new to gcc and wish to learn, check out An Introduction to GCC.

The other essential tool used in the command line setups shown here is make. Make is a tool which controls the generation of executables and other non-source files of a program from the program’s source files. In other words, make is used to build your program.

For info on make check out

  • Managing Projects with GNU Make, Third Edition
  • GNU Make Manual

When building SDL programs from the command line sdl-config can be used. sdl-config outputs the necessary command line options needed for SDL which are then passed to gcc. For example running

sdl-config --cflags

on Mac OS X produces

-I/usr/local/include/SDL -D_GNU_SOURCE=1 -D_THREAD_SAFE

as output. This can be used in makefiles like so

CFLAGS=-W -Wall -O3 `sdl-config --cflags` -I/usr/local/include

 

Using the GNU Autotools

Although I used the attached makefile (668 bytes) during the initial development of Classic Invaders I later converted the build system to use the GNU Autotools.

Using the Autotools has some advantages

  • It provides the user with the standard ‘./configure && make && make install’ procedure.
  • It’s easier to adapt the package to different systems since ‘./configure’ supports many options to overwrite the default settings.
  • Using Automake the dependencies between source files are managed for you.
  • Once setup, preparing the package for distribution is automated with the ‘make dist’ or ‘make distcheck’ targets.

The main disadvantage is that the Autotools have a steep learning curve, but overall I think the time spent to convert to using this system was worth it.

Some books on using the Autotools

  • The Goat Book
  • Autotools

The original makefile used to build the game Classic Invaders is shown below. To check out the files used in the Autotools build system download the latest Classic Invaders source package (2 MB).

CC=g++
CFLAGS=-W -Wall -O3 `sdl-config --cflags` -I/usr/local/include
LIBS=`sdl-config --libs` -lSDL_image -lSDL_ttf -lSDL_mixer
ย 
cinvaders: shot.o alien.o game.o game_entity.o main.o player.o ttf.o ui.o \
  status.o bonus_ship.o sound.o
        $(CC) -o cinvaders shot.o alien.o game.o game_entity.o main.o player.o \
        ttf.o ui.o status.o bonus_ship.o sound.o $(LIBS)
alien.o: alien.cpp alien.h game.h game_entity.h screen.h
        $(CC) $(CFLAGS) -c alien.cpp
game.o: game.cpp game.h ui.h status.h sound.h game_entity.h screen.h \
  player.h alien.h shot.h bonus_ship.h explosion.h shield_piece.h rand_num_gen.h
        $(CC) $(CFLAGS) -c game.cpp
game_entity.o: game_entity.cpp game_entity.h screen.h
        $(CC) $(CFLAGS) -c game_entity.cpp
main.o: main.cpp game.h
        $(CC) $(CFLAGS) -c main.cpp
player.o: player.cpp player.h game.h game_entity.h
        $(CC) $(CFLAGS) -c player.cpp
shot.o: shot.cpp shot.h game.h game_entity.h
        $(CC) $(CFLAGS) -c shot.cpp
ttf.o: ttf.cpp ttf.h
        $(CC) $(CFLAGS) -c ttf.cpp
ui.o: ui.cpp ui.h ttf.h screen.h
        $(CC) $(CFLAGS) -c ui.cpp
status.o: status.cpp status.h screen.h
        $(CC) $(CFLAGS) -c status.cpp
bonus_ship.o: bonus_ship.cpp bonus_ship.h screen.h game_entity.h game.h
        $(CC) $(CFLAGS) -c bonus_ship.cpp
sound.o: sound.cpp sound.h
        $(CC) $(CFLAGS) -c sound.cpp
ย 
.PHONY: clean
clean:
        for i in *.o; do rm -f $$i; done
        if [ -a cinvaders ]; then rm -f cinvaders; fi
        if [ -a cinvaders.exe ]; then rm -f cinvaders.exe; fi