What is a Makefile? & What are its uses?

You are currently viewing What is a Makefile? & What are its uses?

Hello! In the previous articles, we discussed GDB and its commands. Also, how GDB works with objdump to debug a program. Now we are learning about another important utility, Makefile. What is a makefile? How does it reduce the work of a programmer? Also, How can it increase your efficiency? Let’s find out!

make:

The make utility is a Linux tool for automating the build process of a program. make utility searches for a “Makefile” which contains the steps to compile and link the program appropriately to its dependencies.

So let’s say we have a c program and we have to compile it for SHAKTI and generate OBJDUMP. Commands for compiling and generating objdump for a c program,

riscv64-unknown-elf-gcc hello.c -o hello.elf
riscv64-unknown-elf-objdump -d hello.elf &> hello.dump

Might look easier! Now consider there are 100’s of C programs like this which has to be compiled. In other words, We have to repeat this a 100 times.

How makefile automates the entire process?

Let’s say that a huge C code base also has a lot of internal dependencies. During compilation, you need to link each and every program with its respective dependencies (header or other library files) and then build it. It is a tedious process.

If there is an error in one of the files. Think about the complications since they are interdependent. After the necessary correction, You have to repeat the entire compilation.

To reduce this effort, make utility is used. makefile contains a set of rules regarding the build process of the program. So whenever changes are made, just execute the makefile instead of compiling all the files again separately.

Syntax of a rule in a makefile:

target: prerequisites
<TAB> recipe

Basic examples:

Create an empty directory containing a file called Makefile with the following content:

print_hello:
<TAB>  echo “Hello World”

Firstly, move inside this folder and then type “make“. It would execute the makefile we created. The output is as follows,

$ make
echo "Hello World"
Hello World

In this example, print_hello behaves like a function.

  • Whenever you execute make, the function is called. This is called the target.
  • The prerequisites or dependencies follow the target. For the sake of simplicity, we have not defined any prerequisites in this example.
  • The command echo “Hello World” is called the recipe. The recipe uses prerequisites to make a target.
  • The target, prerequisites and recipes together make a rule.

In this output, You can see the entire command displayed before the output.

To avoid this, we can prefix the commands with a @,

print_hello:
<TAB>  @echo “Hello World”

Output,

$ make
Hello World

A target might be a binary file that depends on prerequisites (source files) or simply it could be just a name for the recipe, as in our example. We call these “phony targets.” Read more about frequently used Linux commands.

Now let’s add a few more phony targets,

print_hello:
<TAB>  @echo “Hello World”
create:
<TAB>  @echo "Creating empty text file..."
@cat one.txt
clean:
<TAB>  @echo "Cleaning up..."
<TAB>  @rm *.txt

When we execute “make”, the output is as follows,

$ make
Hello World

Only the first target has been executed and the others have been ignored. That’s because only the first target in the makefile is the default target. This is the reason you will see all as the first target in most projects. It is the responsibility of all to call other targets. 

Let’s include the phony target all,

all: print_hello create
print_hello:
<TAB>  @echo “Hello World”
create:
<TAB>  @echo "Creating empty text files..."
@touch file-{1..10}.txt
clean:
<TAB>  @echo "Cleaning up..."
<TAB>  @rm *.txt

Output,

$ make
Hello World
Creating empty text files...

It is a good practice not to call clean in all or put it as the first target. clean should be called manually when cleaning is needed as a first argument to make.

$ make clean
Cleaning up…...

Keeping all this in mind, lets see if you guys can understand the makefile used in SHAKTI. This is the makefile for UART application printing “Hello world” Click here!

Note: shakti-sdk and shakti-tools are currently a private repository. Please login or sign up to Gitlab and request access here to view the code.