How to use make utility to build C projects? (original) (raw)
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:
- client.c: Contains the main() function.
- server.c: Contains the greetings() function definition.
- server.h: Header file declaring the greetings() function.
- makefile.mk: The build script.
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.