How to use make utility to build C projects?

Last Updated : 4 Apr, 2026

In C/C++ development, code is split into dependencies (e.g., your app.c "borrows" a login function from auth_library.c). If the library isn't compiled into an object file first, your app cannot be built. The make utility automates this by following a script called a Makefile.

Key principles of makefile:

  • Makefile: A file containing variables, targets, and commands to compile and link your project.
  • Make Utility: A command-line tool that processes the Makefile instructions.
  • Dependency Management: It specifies which files must be created before others.
  • Efficiency: It only recompiles files that have changed since the last build.

Project Structure:

To demonstrate, we will use four files:

  1. client.c: Contains the main() function.
  2. server.c: Contains the greetings() function definition.
  3. server.h: Header file declaring the greetings() function.
  4. makefile.mk: The build script.

1. server.h (Header)

It declares the function so other files can use it.

C++
void greetings();

2. server.c (Function Definition)

Implements the greeting logic here.

C++
#include "server.h"
#include <stdio.h>

void greetings() { 
    printf("geeksforgeeks!"); 
}

3. client.c (Main Program)

The entry point that calls the external function.

C++
#include <stdio.h>
#include "server.h"

int main() {
    printf("hey there, welcome to ");
    greetings();
    return 0;
}

4. makefile.mk (Build Script)

This file defines the targets (what to build) and prerequisites (what is needed).

Important: Commands must be preceded by a Tab character, not spaces.

C++
# Target: Prerequisites
# [Tab] Command

a: client.o server.o
	gcc client.o server.o -o a

client.o: client.c server.h
	gcc -c client.c

server.o: server.c server.h
	gcc -c server.c

Execution Steps

1. Compile the Project: Run the make command with the -f flag to specify your filename.

make -f makefile.mk

This creates an executable named a (Windows) or a.out (Linux).

2. Run the Program:

For Windows run : a

or,

For Linux run : ./a

Output:

hey there, welcome to geeksforgeeks!

How it Works Internally

  • Dependency Graph: Make builds a visual map of which files depend on others.
  • Topological Sorting: It uses this algorithm to determine the exact sequence of compilation.
  • Timestamps: It compares the "Last Modified" time of the source file vs. the object file, if the source is newer, it triggers a recompile.

When to Use Make

  • Large Projects: When managing dozens or hundreds of source files.
  • Automated Testing: To run a suite of tests immediately after a successful build.
  • Cross-Platform Builds: To handle different compiler flags for different operating systems.
  • Time Saving: To avoid recompiling the entire project when you only changed one line of code.
Comment