Basics of Makefile

Basics of Makefile

Lost Little Scholar

Reading takes

4

minutes

Speed reading only takes 2 minutes

1

Introduction

The following C language code is very simple

#include <stdio.h>
int main(){    printf("Hello World!.
");    return 0;}

In Linux, we can compile it using the following command

gcc hello.c -o hello

However, as the project grows, there will inevitably be more and more .c files and .h header files, and it becomes very cumbersome to use compiler directives directly. Just entering the file names can affect your mood, and it is also very easy to make mistakes, as shown in the example below

gcc hello.c aaa.c bbb.c -lpthread -ltest1 -ltest2 -o hello

Moreover, even if you only modify one file, you need to recompile all the files, wasting a lot of development time. The best way to solve this problem is to write down the compilation rules for the project, allowing the compiler to automatically load the rules for compilation.

To achieve the above goal, two tools are needed: make and Makefile, which are used together, each with its own role

  • make: It helps us find the modified files in the project and, based on dependencies, find other related files affected by the modification, then compile these files according to the rules separately, thus avoiding recompiling all files in the project.

  • Makefile: Defines the compilation rules and dependencies, allowing the make tool to accurately perform the compilation work

2

What is Makefile

Makefile is a file used to specify the build process for compiling and linking software, usually located in the root directory of the software source code. By defining a series of rules, Makefile tells the make tool how to compile and link the code to generate the final executable file or library file.

3

Basic Syntax of Makefile

Makefile consists of a series of rules, the basic format of a rule is

target: prerequisites
	command

Here, target is the file to be generated, prerequisites are the files or targets that target depends on, and command is the actual command to be executed.

4

Makefile Example

Here is a simple example

app: main.o add.o
	gcc main.o add.o -o app
main.o: main.c
	gcc -c main.c
add.o: add.c
	gcc -c add.c

This Makefile contains 3 rules, specifying that app depends on main.o and add.o, which in turn depend on their respective source files. make will automatically complete the compilation based on the dependencies.

So, the compilation command becomes very simple, just type make to generate the executable file app.

5

Common Knowledge Points of Makefile

Variables can be defined in Makefile, for example

objects = main.o kbd.o command.o display.o
prog: $(objects)
	cc $(objects) -o prog

Using the objects variable to represent multiple target files makes the syntax cleaner.

Wildcards can be used to specify a class of targets in bulk, for example

.PHONY: clean
clean:
	rm *.o

Here, *.o specifies all .o files as dependencies for the clean target, so all .o files can be deleted during clean. The .PHONY declares a phony target, which does not correspond to actual files.

A rule can also specify multiple targets, for example

bigoutput littleoutput: text.g
	generate text.g -o bigoutput
	generate text.g -o littleoutput

In the above example, both bigoutput and littleoutput are generated simultaneously.

Static patterns can be used to reference target names in rules, for example

%.o : %.c
	$(CC) -c $< -o $@

This pattern rule can match all .c to .o conversions.

Custom functions are supported, for example

upcase = $(subst a,A,$(1))
a.o : a.c
	$(CC) -c $(call upcase,$<) -o $@

Here, the upcase function converts the parameter to uppercase.

6

Free Community

Basics of Makefile

Basics of Makefile

Leave a Comment