Simple build system using Make

Happy new year folks ! I hope you get to achieve everything you’ve set your mind to for 2021, even though 2020 wasn’t the best year for many of us.

With that aside, here is another tutorial post that can also be found on my YouTube channel (/c/cppdev) directly here. As before, this will be presented on Linux Ubuntu distribution.

This is an alternative on how to create a simple build system for your project. We are going to create a build system only based on Make this time around. We are not going to use CMake, which, as we learned from previous post, generates the Makefiles. In this case, we directly implement the Makefiles ourselves and build the project without using another tool – aside from the compiler which was mentioned in the CMake post also.

To get right into it, we have to do some steps in order to set up our build system with Make.

First of all, what is Make?

Make is a build automation tool that automatically builds executable programs and libraries from source code by reading files called Makefiles which specify how to derive the target program.

To make a parallel, in the previous post related to CMake, we had some configuration files called "CMakeLists.txt". This time around, we will have some files called simply "Makefile".

In order for us to create a simple build system using this build automation tool, we need to proceed with some steps and have a basic understanding on how to compile our program without such a tool.

Enter the compiler…

In order for us to build some executable or library, we need a compiler. We already discussed a bit about this in the previous post but what we didn’t discuss is how to use only the compiler to build our software – without any automation tool.

The compiler that we are going to use for this, is the same as before, the g++ compiler. If the g++ utility is not present on our machine, we can installed with the following command "sudo apt-get install g++"

We can check if we already have it, by using "g++ --version".

Now that we have it installed, we can directly use it, in order to build our project directly.

Building directly with compiler only

We are going to use only the g++ compiler in order to build a simple project.

If we take, for e.g., our previous simple project (CPPTutorial) in which we have a "src" directory with the source code files (.cpp) and an "include" directory with all the include files (.h/.hpp) then we can use the compiler as follows:

We need to execute the compiler binary (g++) and provide some arguments such as : the source files to be build, the include directives with the include directories and the output name that we want. Of course we can also provide multiple compilation options but that is not the case at this time.

Our full command should look like this :

g++ src/main.cpp -Iinclude/ -o CPPTutorial

This will actually generate the "CPPTutorial" executable from source file "main.cpp" and also using include files from the "include" directory.

That’s it, that is all we have to do, in order to build our program using only the compiler.

Make overview and Makefile directory structure

By using Make in our build system, we are also going to use a compiler (the g++ compiler). To be more precise, we are going to configure Make utility to use g++ compiler to build our program using the Makefiles. We will only use Make, directly.

If we take the same project used before in our posts, which has the following directory structure :

We are going to create “Makefile” in the top most directory and the directory structure will look like this :

Now that we have this file created, all we need to do is to actually implement the code inside and use the Make utility to build our project.

Makefile contents (implementation)

I will try to add the contents of the global Makefile that we previously created and comment each line with “#” in order to provide information on what it means.

We will provide a posibility to build two binaries in this Makefile, one for the actual executable – CPPTutorial – and one for the tests executable – CPPTutorial-test.


# set the C++ compiler
CXX := g++

# store all source files (that end with ".cpp") from "src" directory in a variable (SRC)
SRC := $(wildcard src/*.cpp)

# store all source files (that end with ".cpp") from "test" directory in a variable (TESTS)
TESTS := ${wildcard test/*.cpp)

# store include dir path in a variable (INCL_DIR)
INCL_DIR := include/

# set two possible target names (actual executable and tests executable)

# add actual logic for the executable target (CPPTutorial)
# just create build directory first then use g++ to compile everything with output in the build directory
    @mkdir build
    @$(CXX) -I$(INCL_DIR) $(SRC) -o build/CPPTutorial

# add actual logic for the test executable target (CPPTutorial-test)
# just create build/test directory then use g++ to compile everything needed for test binary in the build/test directory
    @mkdir build/test
    @$(CXX) $(TESTS) -o build/test/CPPTutorial-test

# clean target - just delete build/test directory and build directory
    @rm -r -f build/test && rm -r -f build

We can go ahead and save this file and we have everything set up for our simple Make based build system.

All that is left to do, is to use the Make utility with the Makefile that we have just created in order to build our project.

Building with Make utility

It’s quite easy to use the Make utility now that we have the Makefile created.

We just have to be in the path in which the Makefile exists and use the following command : "make <target_name>".

In our case this is going to be "make CPPTutorial" or "make CPPTutorial-test".

That’s it. We have gone through the process of creating a very simple Make based build system for our project. Of course, from here, you can update it and make it more complex, but this is only intended to help you get started and have a rough idea of what the Make utility is and how you can use it.

I hope you learned something new today and this information will be valuable to your future work in the programming world.

4 thoughts on “Simple build system using Make”

  1. You haven’t actually set any make rules for independent targets. Compiling everything in src isn’t the way. You’ve also hardcoded target it seems.

    1. This is a post related to the beginners video from my YouTube channel related to Make and it’s as I have stated at the end of my post : “only intended to help you get started and have a rough idea of what the Make utility is and how you can use it.”

      I only try to provide a starting point for people new to this stuff. There is actual official documentation related to Make that can be checked and followed by people wanting to learn more.

      However, thanks for the feedback. Much appreciated :).

  2. Pingback: Simple build system using Bitbake – The CPPDEV

  3. Pingback: Simple build system using Bitbake - cppdev

Leave a Reply

%d bloggers like this: