Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: SFML Makefiles  (Read 21259 times)

0 Members and 1 Guest are viewing this topic.

Munchor

  • Newbie
  • *
  • Posts: 16
    • View Profile
SFML Makefiles
« on: August 31, 2012, 12:13:23 pm »
Hey there,

LIBS=-lsfml-graphics -lsfml-window -lsfml-system

all:
        @echo "** Building the game"
        g++ -c "State.cpp" -o State.o
        g++ -c "PlayState.cpp" -o PlayState.o
        g++ -c "Game.cpp" -o Game.o
        g++ -c "Object.hpp" -o Object.o
        g++ -c "Player.hpp" -o Player.o
        g++ -o thegame Game.o State.o PlayState.o Object.o Player.o $(LIBS)

clean:
        @echo "** Removing object files and executable..."
        rm -f thegame

install:
        @echo '** Installing...'
        cp thegame /usr/bin

uninstall:
        @echo '** Uninstalling...'
        rm thegame

That's the makefile I've been using for my SFML Project.

Code: [Select]
** Building the game
g++ -c "State.cpp" -o State.o
g++ -c "PlayState.cpp" -o PlayState.o
g++ -c "Game.cpp" -o Game.o
g++ -c "Object.hpp" -o Object.o
g++ -c "Player.hpp" -o Player.o
g++ -o thegame Game.o State.o PlayState.o Object.o Player.o -lsfml-graphics -lsfml-window -lsfml-system
/usr/bin/ld:Object.o: file format not recognized; treating as linker script
/usr/bin/ld:Object.o:1: syntax error
collect2: error: ld returned 1 exit status
make: *** [all] Error 1

It hasn't quite been working, though. Do you guys also use Makefiles, any tips? Thank you.
« Last Edit: August 31, 2012, 12:20:18 pm by Munchor »

roarbug

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: SFML Makefiles
« Reply #1 on: September 03, 2012, 08:53:23 pm »
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)

roarbug

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: SFML Makefiles
« Reply #2 on: September 03, 2012, 08:55:29 pm »
And for your error message it's maybe because you're trying to compile a header file .hpp instead of .cpp.
It's like this in C, it's probably the same in C++.