Follow and star our public account for exciting content

Source: Internet
Makefile is a compilation control file widely used for automating project builds. It defines a series of rules to guide the build process. With Makefile, developers can easily manage compilation, linking, cleaning, and other tasks for large projects. This article will start with the basic usage of Makefile and gradually delve into more advanced applications, presenting you with a comprehensive and detailed Makefile usage manual.
Basic Structure of Makefile
A simple Makefile consists of rules, which are composed of targets, dependencies, and commands:
target: dependencies
commands
The Tab character before the commands is mandatory. Here is a simple example:
hello: hello.c
gcc -o hello hello.c
Using Variables
Declaring variables in Makefile can make our code more concise.
CC=gcc
CFLAGS=-std=c99
LDFLAGS=
OBJ=main.o utils.o
app: $(OBJ)
$(CC) -o app $(OBJ) $(LDFLAGS)
main.o: main.c
$(CC) $(CFLAGS) -c main.c
utils.o: utils.c utils.h
$(CC) $(CFLAGS) -c utils.c
Generic Rules and Pattern Matching
Pattern rules can reduce the workload of repeating the same commands.
%.o: %.c
$(CC) $(CFLAGS) -c $<
$< is one of the automatic variables, representing the first item in the dependency list.
Automatic Variables
Makefile provides a series of automatic variables that are very useful in the commands of rules:
-
$@ represents the target file name in the rule;
-
$^ represents the list of all dependency files;
-
$< represents the first dependency file;
-
$? represents the list of all dependencies that are newer than the target.
Using Functions
Makefile has many built-in functions for performing string operations, file operations, etc.
For example, to get the list of source files:
SRC=$(wildcard *.c)
OBJ=$(patsubst %.c,%.o,$(SRC))
Controlling Make’s Behavior
-
make -B forces recompilation of all targets;
-
make -n shows the commands that will be executed without actually executing them;
-
make -f <file> specifies a Makefile with a different name;
-
make -j allows parallel execution (multi-core compilation).
Advanced Usage – Conditional Statements
Makefile also supports conditional statements, which are very useful when different commands need to be executed in different environments.
ifeq ($(OS),Windows_NT)
RM=del /Q
else
RM=rm -f
endif
clean:
$(RM) *.o
Organizing Makefile with Variables and File Inclusion
For large projects, organizing multiple Makefiles is a good approach.
# In the sub Makefile
include config.mk
Custom Functions
By defining reusable functions, you can make your Makefile more powerful and flexible.
define run-cc
$(CC) $(CFLAGS) -o $@ $^
endef
app: $(OBJ)
$(call run-cc)
Handling Multiple Targets
Define a rule to handle multiple files in bulk.
FILES := file1 file2 file3
all: $(FILES)
$(FILES):
touch $@
Using Phony Targets
Phony targets do not represent actual files; they are just names for actions.
.PHONY: clean
clean:
rm -f *.o app
Debugging Makefile
You can usemake –debug or add comments to help debug the Makefile.
app: main.o utils.o
# This is a linking command
$(CC) -o app main.o utils.o
Conclusion
Makefile is a powerful tool for build automation, capable of simplifying the build process for small projects and flexibly managing the complex build systems of large applications. Through the detailed discussion and rich examples in this article, you should be able to master the various skills of Makefile and apply them in real projects.
I hope the above content helps you gain a deeper understanding and usage of Makefile. Remember, “Practice makes perfect”—writing your own Makefile and trying out these features is the best way to learn.
Source from the internet, copyright belongs to the original author. If there is any infringement, please contact for removal.
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
Follow my public account and reply "C language" to receive 300G of programming materials for free.
Click "Read the original text" for more sharing. Feel free to share, bookmark, like, and view.