How to Write an Impressive Makefile from Version 1 to Version 5

1. The Three Essential Elements of Makefile

How to Write an Impressive Makefile from Version 1 to Version 5

2. Working Principle

How to Write an Impressive Makefile from Version 1 to Version 5

3. Start Writing

First, let’s write our program, taking C language as an example.

1) func.h

Define two functions: addition and subtraction:

How to Write an Impressive Makefile from Version 1 to Version 5

2) Implementation of the Addition Function

How to Write an Impressive Makefile from Version 1 to Version 5

3) Implementation of the Subtraction Function

How to Write an Impressive Makefile from Version 1 to Version 5

4) main function

How to Write an Impressive Makefile from Version 1 to Version 5

3.1 Version 1

The most basic version: just write it directly, a simple explanation: when we compile the above files, we use gcc -o main main.c add.c sub.c.

Then we convert it into a Makefile, following the above working principles and rules.

For example, sub.o depends on sub.c generated by the gcc -c command, and this dependency can be achieved by:

sub.o: sub.c

Then write the implementation command on the second line, noting that the second line must strictly follow the tab control similar to Python syntax. The rest are similar operations.

How to Write an Impressive Makefile from Version 1 to Version 5

3.2 Version 2

We find that Version 1 is too long; how can we optimize it? We can use the characteristics of the language, and Makefile has variables for assignment. Assign all .o files to the obj variable and main to the target variable.

Referencing these variables is done in the form of: $(target). $(variable).

The last two lines explain the automatic variables mentioned earlier:

$<: The first dependency in the rule
$@: The target in the rule
$^: All dependencies in the rule

So the last line becomes as shown in the figure, where %.o and %.c match each .o and .c file. Modifying Version 1 becomes as shown in the figure:

How to Write an Impressive Makefile from Version 1 to Version 5

3.3 Version 3

Introduce the CC variable. In Makefile, there are some built-in variables, such as CC, which we can assign and modify, or use directly. Further modify Version 2 to become Version 3.

How to Write an Impressive Makefile from Version 1 to Version 5

3.4 Version 4

Here we introduce two commonly used functions in Makefile: wildcard and patsubst, which are used for finding local files and pattern matching, respectively.

src= Find all .c files locally, obj= Replace all .c files locally with all .o files.

How to Write an Impressive Makefile from Version 1 to Version 5

3.5 Version 5

When using Makefile, we need to clean all .o and intermediate files; how can we implement this in Makefile?

By using clean, and the normal clean syntax is:

clean:
    rm *.o main

If we run clean twice in a row, we will encounter problems, as shown in the figure:

How to Write an Impressive Makefile from Version 1 to Version 5

This issue arises because you deleted once, and the local disk does not have the corresponding file, which leads to an error. The solution to this problem is to add the -f parameter to force it.

clean:
    rm *.o main -f

When we create a clean file locally and then run make clean, it always shows the latest, as shown in the figure:

How to Write an Impressive Makefile from Version 1 to Version 5

Here we introduce a concept: phony targets. Because make clean will compare the local disk with the files after make clean, and make clean does not generate corresponding files, according to the characteristics of Makefile, every time after an update, it must be new, while the local disk is existing, so there will definitely be a mismatch, resulting in the above result.

Targets like make can generate files, while make clean does not generate files, are called phony targets, and at this time, we need to declare this in Makefile:

.PHONY: clean
clean:
    rm *.o main

Finally, when we want to do other tasks under clean, such as creating files, if there are no permissions or other issues, the following commands will not be executed.

For example, creating a file under /usr/local where ordinary users do not have permissions will inevitably result in an error:

.PHONY: clean
clean:
    mkdir /usr/local/a
    rm *.o main

How to Write an Impressive Makefile from Version 1 to Version 5

It will directly report an error. The solution to this problem is simple: add a hyphen (-) before the command line.

.PHONY: clean
clean:
    -mkdir /usr/local/a
    rm *.o main

How to Write an Impressive Makefile from Version 1 to Version 5

Finally, the complete Makefile is as follows:

How to Write an Impressive Makefile from Version 1 to Version 5

Leave a Comment