<OT> - Help With Linux Makefile

Hi,

Was hoping some people could take a look at my makefile
and provide suggestions to make it better:#-----------------------------------------------------------------------------------------------------------

Checkers Genius[TM] Version 2.0 - MAKEFILE by JeZ+Lee & mattmatteh…

©opyright 2011 By www.16BitSoft.com

TARGET = cg

VERSION = 2.0

DEL_FILE = rm -f

CC = g++
CFLAGS = -pipe -Wall -g #-"ggdb"
SDL_CFLAGS = $(shell sdl-config --cflags)
SDL_LIBS = $(shell sdl-config --libs)

OPENGL_LIBS = -lGL
SDL_TTF_LIBS = -lSDL_ttf
SDL_IMAGE_LIBS = -lSDL_image
SDL_MIXER_LIBS = -lSDL_mixer

OBJECTS = src/main.o
src/audio.o
src/data.o
src/game.o
src/input.o
src/interface.o
src/logic.o
src/runtime.o
src/screens.o
src/settings.o
src/visuals.o

SOURCES = src/main.cpp
src/audio.cpp
src/data.cpp
src/game.cpp
src/input.cpp
src/interface.cpp
src/logic.cpp
src/runtime.cpp
src/screens.cpp
src/settings.cpp
src/visuals.cpp

HEADERS = src/audio.h
src/data.h
src/game.h
src/input.h
src/interface.h
src/logic.h
src/runtime.h
src/screens.h
src/settings.h
src/visuals.h

$(TARGET): $(OBJECTS)
$(CC) $(SDL_LIBS) $(OPENGL_LIBS) $(SDL_TTF_LIBS) $(SDL_IMAGE_LIBS)
$(SDL_MIXER_LIBS) $(OBJECTS) -o $@

.cpp.o:
$(CC) $(CFLAGS) $(SDL_CFLAGS) -c $< -o $@

clean:
rm $(OBJECTS) $(TARGET)
#-----------------------------------------------------------------------------------------------------------

Thanks in advance!

Jesse "JeZ+Lee"
16BitSoft
Video Game Design Studio
www.16BitSoft.com

Hello,

Hi,

Was hoping some people could take a look at my makefile
and provide suggestions to make it better:

#-----------------------------------------------------------------------------------------------------------

Checkers Genius[TM] Version 2.0 - MAKEFILE by JeZ+Lee & mattmatteh…

©opyright 2011 By www.16BitSoft.com

TARGET = cg

VERSION = 2.0

VERSION isn’t used anywhere, so you can remove it.

DEL_FILE = rm -f

DEL_FILE isn’t used anywhere, so you can remove it.

CC ? ? ?= g++
CFLAGS = -pipe -Wall -g #-"ggdb"
SDL_CFLAGS = $(shell sdl-config --cflags)
SDL_LIBS = $(shell sdl-config --libs)

When using $(shell), you almost always want to use ‘:=’ instead of
’=’. Otherwise every time SDL_CFLAGS gets expanded, it will run the
shell command. This is potentially very expensive.

OPENGL_LIBS ? ?= -lGL
SDL_TTF_LIBS ? ?= -lSDL_ttf
SDL_IMAGE_LIBS ? ?= -lSDL_image
SDL_MIXER_LIBS ?= -lSDL_mixer

OBJECTS = src/main.o
? ? ? ? ?src/audio.o
? ? ? ? ?src/data.o
? ? ? ? ?src/game.o
? ? ? ? ?src/input.o
? ? ? ? ?src/interface.o
? ? ? ? ?src/logic.o
? ? ? ? ?src/runtime.o
? ? ? ? ?src/screens.o
? ? ? ? ?src/settings.o
? ? ? ? ?src/visuals.o

SOURCES = src/main.cpp
? ? ? ? ?src/audio.cpp
? ? ? ? ?src/data.cpp
? ? ? ? ?src/game.cpp
? ? ? ? ?src/input.cpp
? ? ? ? ?src/interface.cpp
? ? ? ? ?src/logic.cpp
? ? ? ? ?src/runtime.cpp
? ? ? ? ?src/screens.cpp
? ? ? ? ?src/settings.cpp
? ? ? ? ?src/visuals.cpp

You can base OBJECTS on SOURCES by doing something like:
OBJECTS = $(SOURCES:.cpp=.o)

That way you only have to update one list if you add or remove a file.

HEADERS = src/audio.h
? ? ? ? ?src/data.h
? ? ? ? ?src/game.h
? ? ? ? ?src/input.h
? ? ? ? ?src/interface.h
? ? ? ? ?src/logic.h
? ? ? ? ?src/runtime.h
? ? ? ? ?src/screens.h
? ? ? ? ?src/settings.h
? ? ? ? ?src/visuals.h

HEADERS isn’t used anywhere - you can just remove it.

$(TARGET): $(OBJECTS)
? ?$(CC) $(SDL_LIBS) $(OPENGL_LIBS) $(SDL_TTF_LIBS) $(SDL_IMAGE_LIBS)
$(SDL_MIXER_LIBS) $(OBJECTS) -o $@

Don’t you want to put the objects before the libraries in the linker
line? I don’t see how this would actually succeed to link (or I’m
mis-remembering how it links things). Also I assume it’s a copy/paste
issue, but you need a tab character before the command line.

.cpp.o:
? ?$(CC) $(CFLAGS) $(SDL_CFLAGS) -c $< -o $@

For automatic dependencies, you want to add the -MMD compiler flag.
Then you can use a deps variable like so:

DEPS = $(SOURCES:.cpp=.d)
-include $(DEPS)

This will keep things mostly working as you edit header files, unless
you try to move them around or remove them.

clean:
? ?rm $(OBJECTS) $(TARGET)

You would also add $(DEPS) here if you go that approach.

Finally, as the author of tup (http://gittup.org/tup), I would be
remiss if I did not suggest to use that instead. The corresponding
Tupfile (in your src/ directory) would look like:

TARGET = cg
CC = g++
CFLAGS += -pipe
CFLAGS += -Wall
CFLAGS += -g
#CFLAGS += -"ggdb"
CFLAGS = sdl-config --cflags

LIBS += sdl-config --libs
LIBS += -lGL
LIBS += -lSDL_ttf
LIBS += -lSDL_image
LIBS += -lSDL_mixer

: foreach *.cpp |> $(CC) $(CFLAGS) -c %f -o %o |> %B.o {objs}
: {objs} |> $(CC) %f -o %o $(LIBS) |> $(TARGET)

Dependencies are always automatic (so you don’t specify -MMD), and
cleaning is done automatically when necessary (eg: If you remove the
rule to create $(TARGET), then the ‘cg’ executable is automatically
removed the next time you update).

Hope this helps!
-MikeOn Sat, May 14, 2011 at 7:50 AM, Jesse Palser wrote:

Hello,

Hi,

Was hoping some people could take a look at my makefile
and provide suggestions to make it better:

#-----------------------------------------------------------------------------------------------------------

Checkers Genius[TM] Version 2.0 - MAKEFILE by JeZ+Lee& mattmatteh…

©opyright 2011 By www.16BitSoft.com

TARGET = cg

VERSION = 2.0
VERSION isn’t used anywhere, so you can remove it.

DEL_FILE = rm -f
DEL_FILE isn’t used anywhere, so you can remove it.

CC = g++
CFLAGS = -pipe -Wall -g #-"ggdb"
SDL_CFLAGS = $(shell sdl-config --cflags)
SDL_LIBS = $(shell sdl-config --libs)
When using $(shell), you almost always want to use ‘:=’ instead of
’=’. Otherwise every time SDL_CFLAGS gets expanded, it will run the
shell command. This is potentially very expensive.

OPENGL_LIBS = -lGL
SDL_TTF_LIBS = -lSDL_ttf
SDL_IMAGE_LIBS = -lSDL_image
SDL_MIXER_LIBS = -lSDL_mixer

OBJECTS = src/main.o
src/audio.o
src/data.o
src/game.o
src/input.o
src/interface.o
src/logic.o
src/runtime.o
src/screens.o
src/settings.o
src/visuals.o

SOURCES = src/main.cpp
src/audio.cpp
src/data.cpp
src/game.cpp
src/input.cpp
src/interface.cpp
src/logic.cpp
src/runtime.cpp
src/screens.cpp
src/settings.cpp
src/visuals.cpp

You can base OBJECTS on SOURCES by doing something like:
OBJECTS = $(SOURCES:.cpp=.o)

That way you only have to update one list if you add or remove a file.

HEADERS = src/audio.h
src/data.h
src/game.h
src/input.h
src/interface.h
src/logic.h
src/runtime.h
src/screens.h
src/settings.h
src/visuals.h
HEADERS isn’t used anywhere - you can just remove it.

$(TARGET): $(OBJECTS)
$(CC) $(SDL_LIBS) $(OPENGL_LIBS) $(SDL_TTF_LIBS) $(SDL_IMAGE_LIBS)
$(SDL_MIXER_LIBS) $(OBJECTS) -o $@
Don’t you want to put the objects before the libraries in the linker
line? I don’t see how this would actually succeed to link (or I’m
mis-remembering how it links things). Also I assume it’s a copy/paste
issue, but you need a tab character before the command line.

.cpp.o:
$(CC) $(CFLAGS) $(SDL_CFLAGS) -c $< -o $@
For automatic dependencies, you want to add the -MMD compiler flag.
Then you can use a deps variable like so:

DEPS = $(SOURCES:.cpp=.d)
-include $(DEPS)

This will keep things mostly working as you edit header files, unless
you try to move them around or remove them.

clean:
rm $(OBJECTS) $(TARGET)
You would also add $(DEPS) here if you go that approach.

Finally, as the author of tup (http://gittup.org/tup), I would be
remiss if I did not suggest to use that instead. The corresponding
Tupfile (in your src/ directory) would look like:

TARGET = cg
CC = g++
CFLAGS += -pipe
CFLAGS += -Wall
CFLAGS += -g
#CFLAGS += -"ggdb"
CFLAGS = sdl-config --cflags

LIBS += sdl-config --libs
LIBS += -lGL
LIBS += -lSDL_ttf
LIBS += -lSDL_image
LIBS += -lSDL_mixer

: foreach *.cpp |> $(CC) $(CFLAGS) -c %f -o %o |> %B.o {objs}
: {objs} |> $(CC) %f -o %o $(LIBS) |> $(TARGET)

Dependencies are always automatic (so you don’t specify -MMD), and
cleaning is done automatically when necessary (eg: If you remove the
rule to create $(TARGET), then the ‘cg’ executable is automatically
removed the next time you update).

Hope this helps!
-Mike


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hi,

Thanks for the detailed critique of my makefile.
I’ll discuss these changes with my Linux team member.
Thank you!

Jesse "JeZ+Lee"
16BitSoft
Video Game Design Studio
www.16BitSoft.comOn 05/14/2011 09:47 AM, Mike Shal wrote:

On Sat, May 14, 2011 at 7:50 AM, Jesse Palser wrote:

Hi,

Was hoping some people could take a look at my makefile
and provide suggestions to make it better:

#-----------------------------------------------------------------------------------------------------------

Checkers Genius[TM] Version 2.0 - MAKEFILE by JeZ+Lee & mattmatteh…

©opyright 2011 By www.16BitSoft.com

TARGET = cg

VERSION = 2.0

DEL_FILE = rm -f

CC = g++
CFLAGS = -pipe -Wall -g #-"ggdb"
SDL_CFLAGS = $(shell sdl-config --cflags)
SDL_LIBS = $(shell sdl-config --libs)

First, “CC” is the C Compiler, thus the name CC. You should be using CXX
which is the C++ compiler. Second, don’t overwrite people’s choice of C/C++
compiler, ever. I compile lots of software and I’m really tired of having to
modify makefiles because they overwrite my choices. Same goes with CFLAGS,
should be CXXFLAGS, and don’t overwrite my choice. In other words, delete
the two lines with "CC = " and "CFLAGS = "

If you //must// modify CXXFLAGS, append to it, and only use extremely common
compiler options. For example, these work on basically any compiler:

-Dsymbol=value
-O
-g
-c
-o

whereas stuff like -pipe -Wall, etc does not. If you do this, you assume GCC
which is really annoying for anyone using anything other than GCC. Yes,
they exist.

Since you are using $(shell …), you need to know that Make does text
replacement everytime you use it. Thus if you have 100 *.cpp files compiled
as g++ $(SDL_CFLAGS), you will call sdl-config --cflags 100 times, which
can significantly slow your compilation down if you have a ton of variables
and/or a ton of source files. To get around that, use the “:=” instead of
"=". By doing that, GNU Make will evaluate the value of $(shell …) and
save it as SDL_CFLAGS.

Basically:

‘=’ in GNU make is more like #define macros in C/C++
":=" in GNU Make is more like ‘=’ in C/C++ (assignment)

Which means anything other than direct 1-to-1 text replacement (“FOO =
bar”), should be set using ‘:=’

OPENGL_LIBS = -lGL
SDL_TTF_LIBS = -lSDL_ttf
SDL_IMAGE_LIBS = -lSDL_image
SDL_MIXER_LIBS = -lSDL_mixer

Since you are using GNU Make, writing out the names of the files is only
needed once. With GNU Make you can simply write:

OBJECTS := $(SRC:.cpp=.o)

which will replace every *.cpp with *.o, so you can remove that other list.
You can probably get away with not writing out the file names at all by
doing

SOURCES := $(wildcard src/*.cpp)

This will effectively grab all of the files that match the pattern
"src/*.cpp", which should be all of you C++ source files.On Sat, May 14, 2011 at 6:50 AM, Jesse Palser wrote:

OBJECTS = src/main.o
src/audio.o
src/data.o
src/game.o
src/input.o
src/interface.o
src/logic.o
src/runtime.o
src/screens.o
src/settings.o
src/visuals.o

SOURCES = src/main.cpp
src/audio.cpp
src/data.cpp
src/game.cpp
src/input.cpp
src/interface.cpp
src/logic.cpp
src/runtime.cpp
src/screens.cpp
src/settings.cpp
src/visuals.cpp

HEADERS = src/audio.h
src/data.h
src/game.h
src/input.h
src/interface.h
src/logic.h
src/runtime.h
src/screens.h
src/settings.h
src/visuals.h

The HEADERS section is unused and unneeded, remove it.

$(TARGET): $(OBJECTS)
$(CC) $(SDL_LIBS) $(OPENGL_LIBS) $(SDL_TTF_LIBS) $(SDL_IMAGE_LIBS)
$(SDL_MIXER_LIBS) $(OBJECTS) -o $@

.cpp.o:
$(CC) $(CFLAGS) $(SDL_CFLAGS) -c $< -o $@

clean:
rm $(OBJECTS) $(TARGET)

#-----------------------------------------------------------------------------------------------------------

Thanks in advance!

Jesse "JeZ+Lee"
16BitSoft
Video Game Design Studio
www.16BitSoft.com


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org