Hi,
There is a key concept of make that you have not understood.
It is supposed to be one rule (or target, or reciepe) for each individual generation.
For exemple if you only modify PlayState.cpp, there is not need to compile Player.o again, you can reuse it.
For a small project you won't see any speed difference, but for a bigger one, you will.
Also the less you write on your hard drive, the more it will appreciate! (except if your working directory is in a ramdisk)
for example to make one rule by object your makefile would look like this:
PlayState.o: PlayState.cpp
g++ -c "PlayState.cpp" -o PlayState.o
After there is a rule for every object, you can build the main program like below. See that the target is the generated file name, and see its dependencies upon all the .o files. So that make can check the timestamp for every file (all the generated and all the sources and then it can only recompile what is needed.
thegame: Game.o State.o PlayState.o Object.o Player.o
g++ -o thegame Game.o State.o PlayState.o Object.o Player.o $(LIBS)
your uninstall rule is wrong, you should give the directory where the program is (and you can use the -r option):
uninstall:
@echo '** Uninstalling...'
rm -f /usr/bin/thegame
You can add a dependency to the file "thegame" for the install rule:
install: thegame
@echo '** Installing...'
cp thegame /usr/bin
With these corrections, the Makefile will look like this:
LIBS=-lsfml-graphics -lsfml-window -lsfml-system
all: thegame
State.o: State.cpp
g++ -c "State.cpp" -o State.o
PlayState.o: PlayState.cpp
g++ -c "PlayState.cpp" -o PlayState.o
Game.o: Game.cpp
g++ -c "Game.cpp" -o Game.o
Object.o: Object.cpp
g++ -c "Object.cpp" -o Object.o
Player.o: Player.cpp
g++ -c "Player.cpp" -o Player.o
thegame: Game.o State.o PlayState.o Object.o Player.o
@echo "** Building the game"
g++ -o thegame Game.o State.o PlayState.o Object.o Player.o $(LIBS)
clean:
@echo "** Removing object files and executable..."
rm -f thegame *.o
install:
@echo '** Installing...'
cp thegame /usr/bin
uninstall:
@echo '** Uninstalling...'
rm -f /usr/bin/thegame
Also you forgot the *.o files in the clean target.
It can still be improved.
In a reciepe the target can be replaced by $@ and the source (the first in the list) can be replaced by $<
State.o: State.cpp
g++ -c $< -o $@
(I see your quotes around your file names, you should just don't use filenames that need some)
Then all the .o generations are made on the same model, so we can use some kind of template (dunno what is the correct naming for this):
%.o: %.cpp
g++ -c $< -o $@
We can use a variable so that people can change the compiler command:
CXX := g++
%.o: %.cpp
$(CXX) -c $< -o $@
You can inform make about the targets that are not a file. (because as I told you make checks for that, as it is its primary use)
.PHONY: all install uninstall clean
(you can put it anywhere)
If State.cpp uses PlayState.cpp, you can tell the dependency:
State.o: State.cpp State.hpp PlayState.hpp
no need to give a command it will use the one from %.o: %.cpp
LIBS=-lsfml-graphics -lsfml-window -lsfml-system
CXX := g++
all: thegame
%.o: %.cpp
$(CXX) -c $< -o $@
%.o: %.hpp
$(CXX) -c $< -o $@
thegame: Game.o State.o PlayState.o Object.o Player.o
@echo "** Building the game"
$(CXX) -o thegame Game.o State.o PlayState.o Object.o Player.o $(LIBS)
clean:
@echo "** Removing object files and executable..."
rm -f thegame *.o
install:
@echo '** Installing...'
cp thegame /usr/bin/
uninstall:
@echo '** Uninstalling...'
$(RM) /usr/bin/thegame
you can replace "rm -f" by $(RM) it's defined by default, and maybe it expends differently in different environments.
I hope this can help
(you can reuse this content under CC0 license)