← Back to list

The missing manual: Introduction to make

Make is a build tool. It is a program created to automate the build process. Note that it was not created only to use with C or C++. In…

Suraj Kareppagol · 2026-06-06 16:44 · 0 claps · 3.9 min read
#software-development #software-engineering #linux #automation #gnu
Open on Medium ↗
Wiki topics: 🔓 · Open Source

The missing manual: Introduction to make

Introduction to make

Introduction to make

Make is a build tool. It is a program created to automate the build process. Note that it was not created only to use with C or C++. In this post I will explain how to use this tool.

Before we begin, create a directory and write a simple C program. Then create a file named as Makefile. Once this file is written run the make command.

The rules and recipes

The main building blocks of make are targets and rules to build them. Targets are the executable which needs to be built and rules are the instructions on how to build them.

Here is the example. Write the target and then put colon (:) right after that. Then put tab in the next line, then the command to build the executable. Tabs are necessary when adding the commands.

main:
  gcc main.c -o main

Lets expand this syntax. Here we have the target which is our executable, then dependencies. These are the source files or intermediate object which are needed to build the target. Then we have the recipes on the next line each prefixed with a tab.

target: dependencies
  recipe

The dependencies can be source files or other targets. Lets look at an example.

main: a.o main.c
  gcc a.o main.c -o main

a.o:
  gcc -c a.c -o a.o

Here we have the main rule main, which depends on a target and executable. Here we have another rule for building that target. Make will first check if there is recipe for building the target a.o, there is a recipe. Next it searches for the source file main.c, it is present. Then it builds the main executable.

Please note that target name can be anything not necessarily the executable name.

Variables

Variables are available in make which are containers to hold data. Here the variables only hold strings. Here CC and SRCS are two examples. Note that I have used the = operator to assign the values.

CC = gcc
SRCS = main.c a.c

The variables can be used directly in the recipes using the ${FOO} or $(FOO)syntax. Lets write a Makefile to create and print these variables to console.

CC = gcc
SRCS = main.c

main: $(SRCS)
  echo $(CC) $(SRCS)
  gcc $(SRCS) -o main

Here the recipes are simple console commands. The below is the console output for the above Makefile.

echo main.c
main.c
gcc main.c -o main

By default make prints the command which is being executed, this is really helpful while debugging. If this behavior is not needed then each command can be prefixed with a @ or just use -s, --slientor --quietoption with make command.

main:
  @echo $(gcc) $(SRCS)
make -s

Make by default provides some variables. There are a lot, but here are the two variables that we are going to use in later sections.

  • $@: Target file name
  • $^: All prerequisites

Built-in Functions

Make provides several built-in functions. We will just go through two basic functions which are wildcard and patsubst.

Wildcard

Suppose we have several source files and want to store the names in a variable. But writing each name is a hassle and if we delete or create a new file, each time we need to modify the variable. Instead of doing this we can use the wildcard function.

SRCS = $(wildcard *.c)

Lets unpack this.

  • SRCS: Variable name
  • =: Assignment operator
  • $(): Evaluate an expression
  • wildcard: Wildcard function
  • *.c: Wildcard pattern, collect all the files that match this pattern

This will populate the SRCS variable with all the source files which match the *.c wildcard pattern in the current directory. If the directory is different just prefix it, for example src/*.c.

Pattern Substitution

Pattern substitution makes life easier. Suppose we have several source files and these are the dependencies used to build the final executable. Now we don’t want keep writing *.o as files.

main: a.o b.o c.o d.o e.o
  echo make

Instead of doing this we can use the patsubst function. This will substitute a pattern in original source.

$(patsubst pattern, replacement, text)

Lets take a look at an example and unpack this.

OBJS = $(patsubst %.c, %.o, $(SRCS))
  • OBJS: Variable which will hold object file names
  • patsubst: Function name
  • %.c: Pattern to search and replace
  • %.o: Substitution pattern
  • $(SRCS): Input to patsubst

This function will fetch all the files which match %.c and keep the % as it is and replace the rest of the part with .o. Below is the output from the patsubst. Experiment with the parameters here to better understand it.

a.c b.c main.c
a.o b.o main.o

Example

Lets write a small Makefile that uses the concepts we just saw. I have 3 source files a.c, b.c and main.c. Now we need to compile these and build the final executable using make.

SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c, %.o, $(SRCS))

all: $(OBJS)
  gcc $^ -o main

%.o: %.c
  gcc -c $^

clean:
  rm *.o main

We have two variables, we collect the source files and then we collect the object file names after using patsubst. The alltarget depends on $(OBJS), that is targets which match these dependencies.

We could write each of these target.

a.o:
  gcc -c a.c

b.o:
  gcc -c b.c

But these is tedious, we can again use the pattern matching here to create targets based on a specific pattern.

%.o: %.c
  gcc -c $^

Here these translates to all of the targets which match *.o pattern. Once we are done with this the all target will be created. Here we can have additional utility targets such as clean to clear the intermediate files.

Conclusion

These concepts are enough to get started. I will put more posts exploring more features of make. If you have any questions please leave a comment or connect with me on LinkedIn.


메타데이터
post_id
52f04a5ae776
slug
the-missing-manual-introduction-to-make-52f04a5ae776
url
https://medium.com/@surajkareppagol.dev/the-missing-manual-introduction-to-make-52f04a5ae776
canonical_url
https://medium.com/@surajkareppagol.dev/the-missing-manual-introduction-to-make-52f04a5ae776
author_url
https://medium.com/@surajkareppagol.dev
status
ok
fetched_at
2026-06-11 06:59:45