Reputation: 23
I'm currently working on an SDL2 project and the directory is structured in the following way
./
|__assets
| |__*.png
|__src
| |__physcis
| |_*.cpp *.hpp
| |__textures
| |_obstacles
| |_*.cpp *.hpp
| |_constants
| |_*.cpp *.hpp
|
|__Makefile
Currently, my makefile has a very simple structure Makefile:
ROOTDIR=src/
TXTURDIR = src/textures/constant/
OBSTACLEDIR = src/textures/obstacles/
PHYSDIR = src/physics/
OBJS = $(ROOTDIR)Main.cpp \
$(ROOTDIR)WindowInit.cpp \
$(ROOTDIR)Timer.cpp \
$(ROOTDIR)GameLoop.cpp \
$(PHYSDIR)Gravity.cpp \
$(TXTURDIR)Texture.cpp \
$(TXTURDIR)TextureContainer.cpp \
$(TXTURDIR)Ball.cpp \
$(TXTURDIR)Bob.cpp \
$(TXTURDIR)Text.cpp \
$(TXTURDIR)ScoreCounter.cpp \
$(TXTURDIR)FPSCounter.cpp
CC = g++
COMPILER_FLAGS = -g -o
LINKER_FLAGS = -lSDL2 -lSDL2_image -lSDL2_ttf
OUT = exe
all: $(OUT)
$(OUT): $(OBJS)
$(CC) $(COMPILER_FLAGS) $@ $^ ${LINKER_FLAGS}
clean:
rm exe
Is there any way to speed my making process up by only compiling certain folders when there is a change and then linking compiled sections together afterwards?
Upvotes: 1
Views: 115
Reputation: 140669
Yes, this is the exact thing Makefiles are designed to do. Here's a set of changes to your existing Makefile that will do it:
Change your OBJS
variable to refer to .o
files instead of .cpp
files. This turns your existing compilation rule into a link rule.
OBJS = $(ROOTDIR)Main.o \
$(ROOTDIR)WindowInit.o \
$(ROOTDIR)Timer.o \
# ... etc ...
Make already knows how to create .o
files from the .cpp
files, thanks to its built-in set of implicit rules. However, you do need to adjust your configuration variable names to what Make's implicit rules expect. Don't put the -o
option in the compiler flags, Make will add that itself.
# _instead of_ setting CC, COMPILER_FLAGS, LINKER_FLAGS
CXX = g++
CXXFLAGS = -g
LIBS = -lSDL2 -lSDL2_image -lSDL2_ttf
Adjust the link rule to match the adjusted variable names. (You don't have a CPPFLAGS right now but you may want it in the future.)
$(OUT): $(OBJS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $^ $(LIBS)
At the bottom of the file, add a set of rules without recipes, specifying the individual dependencies of each object file. This is how you arrange for things to get rebuilt when you change your header files, and it also works around a misfeature where sometimes Make will delete object files immediately after they are used. (For a project this size, it's easiest to keep track of which source files use which header files manually. When it gets big enough that you want to have the computer deal with that for you, look into automake.)
$(ROOTDIR)Main.o: $(ROOTDIR)Main.cpp foo.h bar.h
$(ROOTDIR)WindowInit.o: $(ROOTDIR)WindowInit.cpp foo.h bar.h
# ... etc ...
Change the clean
target to clean up the object files as well (and while you're at it, use -rm -f
instead of bare rm
).
clean:
-rm -f $(OUT) $(OBJS)
Add a .PHONY
annotation at the very bottom of the file: this is not strictly necessary but will prevent weird things from happening if you ever have a file named 'all' or 'clean' for some reason:
.PHONY: all clean
And that's it, you're done.
Upvotes: 1