Complete Makefile Tutorial for Beginners [Explained with Examples]

Complete Makefile Tutorial for Beginners [Explained with Examples]

If you are landed here and reading this article, you might have heard a lot of buzz about makefile. If you have joined any new project, you might have seen people talking about it.

In this Makefile Tutorial for Beginners, I will explain it complete with simple examples.

Basically, it is used to compile the C/C++ source code files and to make the project build automatically.

But…

Many developers face issues dealing with the makefile. And then it is obvious, there are many doubts and it is not easy for beginners to understand this. In fact, I went through the same phase when I read all mess on the internet.

So, I want to make this simple for you.

Table of Content

At the end of this post, you will learn all the basic things you should know working on makefile or to create one for your project.

Read it complete step-by-step.

What is makefile?

Makefile, you may have seen in many projects.

The project usually have different files to compile and to make the executable binaries. All these different files have dependencies. For example, one source file must be compiled before other one and likewise…

Basically, the makefile is used to order the sequence of a compilation of files. In other words, the makefile is used to organize the code compilation procedure.

For many, it sounds difficult to understand, let see the example where you need to follow the order of compilation.

C Program Example:

#include <hellomake.h>

int main() {
  // call a function in another file
  printHelloMake();

  return(0);
}

Save this file as hellomake.c.

#include <stdio.h>
#include <hellomake.h>

void printHelloMake(void) {

  printf("Hello makefiles!\n");

  return;
}

The function printHelloMake() is defined in hellofunc.c file.

/*
example include file
*/

void printHelloMake(void)

This is header file hellomake.h which contents the printHelloMake() function declaration. And function printHelloMake() is used in hellomake.c file.

Here, hellofunc.c depends on hellofunc.c. So, you need to compile hellomake.c before hellofunc.c.

If you are using gcc compiler, you have a straightforward run command to compile C program. Run this following command in the compiler.

gcc -o hellomake hellomake.c hellofunc.c -I.

Here,

  • gcc – is compiler name.
  • -o : This is a parameter to name your output the binary/executable file.
  • -I. : Indicates that all the input files need to compile presents in the current directory.

There are certain problems with this commands. And it gives purpose for makefile.

What is the purpose/use of makefile?

In above command, there are only two files, what if there are hundreds of files need to compile?

Do you think is it comfortable to write this gcc compilation command by mentioning all these 100’s file names?

If you can do this, this tutorial is not for you.

One more reason…

If you switch to another computer or terminal, you can not just run the previous command by pressing up and down button on the terminal.

You have to retype from the scratch. Do you want to write this command again with hundreds of files? Obviously not!

So, here comes the use of makefile. There are many advantages of the makefile.

In the makefile, you can mention all your files that need to compile.

By considering our above example, here is simple makefile that you can create and try running.

How to Create and Run Simple makefile? [Example]

hellomake: hellomake.c hellofunc.c
        gcc -o hellomake hellomake.c hellofunc.c -I.

Save this file as makefile or Makefile.

When you run the command make in the same directory where the makefile is located, it compiles the file in the same order mentioned in the makefile rule.

Here,

  • hellomake is the output binary or executable file.
  • The file name mentioned after :, defines the order of compilation.
  • In the second line, the tab is used to identify the scope. You should not miss using it.

If you make any changes in programming files, you have to run command make which will give hellomake as output executable file.

Running command make is easier than writing complete gcc command every time for compilation.

Defining Macros/Variables in the makefile:

Looking further…

You can also, define variables in the makefile.

CC=gcc
CFLAGS=-I.

hellomake: hellomake.o hellofunc.o
     $(CC) -o hellomake hellomake.o hellofunc.o $(CFLAGS)

Here, CC and CFLAGS are two different variables defines in the makefile.

You can retriever its value using $ symbol.

If you want to change the compiler, it will be easy to change the value of CC variable and it will reflect throughout the program. Same for CFLAGS variable.

These variables are defined at the top of the makefile and also called as macros.

Writing Rules for makefile:

We can also define the generic rule inside the makefile.

CC=gcc
CFLAGS=-I.
HEADER= hellomake.h

%.o: %.c $(HEADER)
	$(CC) -c -o $@ $< $(CFLAGS)

hellomake: hellomake.o hellofunc.o 
	gcc -o hellomake hellomake.o hellofunc.o -I.

%.o: %.c $(HEADER) defines that .o version of the file depends on the .c version of the same file and header files included in HEADER macros.

The rule further says…

  • c is to compile the file.
  • o is to pass the output file.
  • $@ depicts the name of the output file as name present before the : file. In above example, the value of $@ is hellomake.
  • $< depicts the first element in the dependency list.
  • Other macros like CC, CFLAGS, and HEADER are same as like we have seen earlier.

If you have multiple header files to include, you can simply generate the macro with all the header files. As we have defines in HEADER macro.

Macro inside another macro:

You can use the value of the macro defined above in your other macros.

IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)

Your libraries and other header files do not necessarily present in the same directory. To make the project more organize, we can save all the libraries inside the “include” directory parallel to the “src” (source) directory.

These directory naming conventions are widely used.

IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)

%.o: %.c $(HEADER)
    $(CC) -c -o $@ $< $(CFLAGS)

hellomake: hellomake.o hellofunc.o
gcc -o hellomake hellomake.o hellofunc.o -I.

This is simple makefile tutorial. And I am sure you get your basics done with this tutorial. Now you can implement makefile in your project whether if it is a small or a big project.

Now action on you…

  • Write makefile for your project.
  • Include all the source files in the makefile.
  • Set the rule and dependencies according to your project needs.
  • Simply run make command.

Damn it!

This will help you to avoid your big and gusty way of writing compiler commands. Simply add all source files in the makefile, set rules and execute.

You can use the makefile with Linux Operation System or any other. You should have C/C++ compiler to compile the source files mentioned in the makefile directories.

Yes, you have done it!

Hope you like this makefile tutorial for beginners. I am free to take any question if you have. Comment it below, I will reply it back.

Happy Programming!

2 Comments

  1. Please suggest me how can I have command in STL in c++. From where should I read and what type of code I should practice which will help in the project?

    1. STL is the Standard Template Library which has multiple components- Algorithms, Container, Functions and Iterators. Its container is special which includes list, queue, vector…

      Understand these components and check where you can use it in programming.

      Moreover, Its all about what project you want to use for. Choose the Data Structure and Algorithm based on the project requirement.

Leave a Reply

Your email address will not be published. Required fields are marked *