Understanding the dependence in Makefile
make is a simple and useful tool which controls the building of your source code. It can be used in any programming language. It's also can be used for reducing the repetitive tasks. For example, if you have multiple shell tasks that listed one by one. You can use
make to organize the workflow.
If you've downloaded an open-source project or joined a new project as a developer. To run the entire project, you have to start building it first. Nearly all open-source projects have a
Makefile for organizing code. But the
Makefile is not easy to understand. Its official manual is so long and hard to understand. It's difficult to modify a
Makefile for you want if you're a newbie. Indeed, you can Google the
Makefile tutorial and then copy&paste some codes within your
Makefile. Even though you don't know how
Makefile works, your code running.
This post will take you 10 minutes to understand the
make core conception. Afterwards, you will create your own
Makefile to run some basic tasks and figured out how
Dependence is the
make's core conception. Understanding the dependence is the most important principle in
make. In the
Makefile every task depends on other prerequisites, which can be files, tasks, or some other form of rules. If you want to run a task, you must define the target and prerequisites. We call this a dependence. A simple
Makefile consists of "dependencies" with the following shape:
Makefile do nothing because the
bar target is undefined. Target should be depend on a defined prerequisite or be defined how it works. The following target defined to run
foo: echo "hello world" #noticed: you must use 'tab' to start this line.
A realistic example
Next, we will give you a realistic example. Suppose we have a simple C project, which contains the following files:
. ├── http.c ├── http.h ├── main.c ├── socket.c ├── socket.h
In our project, we have the following dependent relationships:
To build an executing file with
gcc, we must compile the source code for the object and then linked them to an executing file. Here are our rules:
http.o: http.c http.h socket.h gcc -c http.c socket.o: socket.h gcc -c socket.c main.o: main.c http.h socket.h gcc -c main.c
Link all object files to an execute file:
exe: http.o socket.o main.o gcc -o exe http.o socket.o main.o
make exe to build your own project.