How to write a good makefile for C++
Tags: beginners, codenewbie, linux, cpp
Published: 2020-01-12 01:28:52

Hello guys, its me again today I'm going to show you how to write a good makefile for a c++ project that you might have.

# What's a makefile
Just if you didn't knew I want to explain it, Basically a makefile its an easier way to compile our code, let me be clear **It's not language exclusive** you can use it on c++ just as you can use it in python, but most people use them on low level programming languages.

# How is it going to help me
Lets say that you have a big project, maybe 10 or 20 classes and you main file, so what's the compile line going to look like

```bash
g++ -Wall -Wextra -std=c++17 -ggdb -Iinclude -Llib src/AssetManager.cpp src/Game.cpp src/InputManager.cpp src/SplashState.cpp src/StateMachine.cpp src/GameState.cpp src/main.cpp -o bin/main -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system -llua53 -ldl
``` 

So this is the compile line for my Skeleton engine project.

{% github https://github.com/Dmendoza99/Skeleton-Engine %}

But as you can see its pretty long...
So imagine writing that every time you need to compile (lets say that terminals don't store last commands hahaha)

# What do I do then?
you create a makefile on your project's root, here is a example

```bash
touch makefile
```

so now your directory looks like this
```bash
.
├── bin/
├── include/
├── lib/
├── makefile
└── src/
```
I strongly recommend this "layout", you will place all .h or .hpp in your include directory, and your .cpp in your src directory, and precompiled libraries (.a, or .out) are going in your lib directory.

```make
CXX		  := g++
CXX_FLAGS := -Wall -Wextra -std=c++17 -ggdb

BIN		:= bin
SRC		:= src
INCLUDE	:= include
LIB		:= lib
LIBRARIES	:= 
EXECUTABLE	:= main


all: $(BIN)/$(EXECUTABLE)

run: clean all
	clear
	@echo "🚀 Executing..."
	./$(BIN)/$(EXECUTABLE)

$(BIN)/$(EXECUTABLE): $(SRC)/*.cpp
	@echo "🚧 Building..."
	$(CXX) $(CXX_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES)

clean:
	@echo "🧹 Clearing..."
	-rm $(BIN)/*
```

What's all wizary your are seeing? well lets go step by step.

* **CXX** Its the "program" you are using for compiling (g++ in my case)
* **CXX_FLAGS** Its the flags for your compiling program 
* **BIN** this is where your binary file is going to be placed
* **SRC** As I told you this is where all your .cpp are going to be
* **INCLUDE** Of course this is all your .hpp or .h file are going to be
* **LIB** As I said is where your precompiled files are going to be
* **LIBRARIES** This are the libraries flags for g++
* **EXECUTABLE** Its just the name of your binary file
* **all** It the "recipe" your makefile will call if you just call make on your terminal
* **run** It compiles your code and makes it run
* **$(BIN)/$(EXECUTABLE)** this one just compiles the code
* **clean** it cleans all your binary files.


If you need any help defining any recipe for your makefile let me know! I will be glad to help you out on anything.

# Now that I have everything setup what do I do?

Its really simple, look at this,

to compile your code you call this in your terminal

```bash
make
```

and to compile it and run it, you call this in your terminal

```bash
make run
```

And that's all really, go ahead and try it!

if you got any problem leave me a comment and I will help you out