Budding breaks ground
Example 1: hello world
Edit Makefile
all:
echo "hello world"
Compile and execute
$ make
$ make all
result output
Grammar Description
- There must be only TAB in front of echo (that is, the TAB key on your keyboard), and there must be at least one TAB, which cannot be replaced by spaces.
Example 2: Makefile defines multiple targets
Edit Makefile
all:
echo "hello world"
test:
echo "hello test"
Compile and execute
$ make
$ make all
$ make test
result output
Grammar Description
- When the Makefile contains multiple targets, use make directly to compile the omitted mode, and compile the first target by default.
Example 3: Makefile comments
Edit Makefile
all:
@echo "hello world"
test:
@echo "hello test"
Compile and execute
$ make
$ make all
$ make test
result output
Grammar Description
- Use the @ symbol to tell make not to display this line of commands at runtime.
Example 4: Simple dependencies
Edit Makefile
all:test
@echo "hello world"
test:
@echo "hello test"
Compile and execute
$ make
$ make test
result output
Grammar Description
- all:test tells make that the all target depends on the test target, which is also called a prerequisite in the Makefile. When this kind of target dependency occurs, the make tool will first build each target in the rule in order from left to right. For example here, if you want to build all, then make will build the test target before building it.
Example 5: simple program compilation
foo.c source code
#include <stdio.h>
void foo()
{
printf("This is foo()!\n");
}
main.c source code
extern void foo();
int main()
{
foo();
return 0;
}
Edit Makefile
all: main.o foo.o
gcc -o simple main.o foo.o
main.o: main.c
gcc -o main.o -c main.c
foo.o: foo.c
gcc -o foo.o -c foo.c
clean:
rm simple main.o foo.o
Compile and execute
$ make
result output
Grammar Description
- The key to writing a Makefile is to sort out the dependencies between files.
Example 6: False target
There is a clean file in the Makefile of Example 5, we hope to clean up the historical files through the clean command. However, when the clean command is executed, it is found that the file cannot be deleted. This is because make takes clean as a condition and finds this file in the current directory, plus the clean target doesn't have any prerequisites, so when we ask make to build the clean target for us, it thinks clean is up to date.
For this situation, it can be solved by the fake target in the Makefile, which can be defined by the keyword .PHONY .
Edit Makefile
.PHONY:clean
all: main.o foo.o
gcc -o simple main.o foo.o
maiin.o: main.c
gcc -o main.o -c main.c
foo.o: foo.c
gcc -o foo.o -c foo.c
clean:
rm simple main.o foo.o
Compile and execute
$ make
$ ./simple
$ make clean
result output
Grammar Description
- Makefile fake target keyword .PHONY .
Example 7: Makefile variables
Edit Makefile
.PHONY:clean
CC = gcc
RM = rm
EXE = simple
OBJS = main.o foo.o
$(EXE):$(OBJS)
$(CC) -o $(EXE) $(OBJS)
main.o:main.c
$(CC) -o main.o -c main.c
foo.o:foo.c
$(CC) -o foo.o -c foo.c
clean:
$(RM) $(EXE) $(OBJS)
Compile and execute
$ make
$ ./simple
$ make clean
result output
Grammar Description
- Variable definition: variable name = variable value;
- Variable reference: $(variable name) or ${variable name}
Example 8: Makefile automatic variables
Edit Makefile
.PHONY:clean
CC = gcc
RM = rm
EXE = simple
OBJS = main.o foo.o
$(EXE):$(OBJS)
$(CC) -o $@ $^
main.o:main.c
$(CC) -o $@ -c $^
foo.o:foo.c
$(CC) -o $@ -c $^
clean:
$(RM) $(EXE) $(OBJS)
Compile and execute
$ make
$ ./simple
$ make clean
result output
Grammar Description
- $ @ is used to indicate the target in a rule; when there are multiple targets in a rule, $ @ refers to any target that causes the command to be run;
- $^ is used to denote all prerequisites in a rule;
- $< is used to denote the first prerequisite in a rule.
- In Makefile, '$' has a special meaning, so if you need to use echo to output '$', you need to use two consecutive '$'; at the same time, '$ @' also has a special meaning for Shell, so you need to use '$ Add a caret ' \ ' in front of $@'.
additional instance
//Makefile
.PHONY: all
all: first second third
@echo "\$$@ = $@"
@echo "$$^ = $^"
@echo "$$< = $<"
first second third:
//输出
$make
$@ = all
$^ = first second third
$< = first
Example 9: Makefile special variables
1. MAKE
Edit Makefile
.PHONY: all
all:
@echo "MAKE = $(MAKE)"
Compile and execute
$ make
result output
Grammar Description
- The MAKE variable indicates what the make command name is;
- Usage scenario: We need to use it when we need to call another Makefile in the Makefile. This method is conducive to writing an easy-to-port Makefile.
2. MAKECMDGOALS
Edit Makefile
.PHONY: all clean
all clean:
@echo "\$$@ = $@"
@echo "MAKECMDGOALS = $(MAKECMDGOALS)"
Compile and execute
$ make
$ make all
$ make clean
$ make all clean
result output
Grammar Description
- MAKECMDGOALS indicates what the current make target entered by the user is.
Example 10: Categories of Makefile variables
1. Recursively expand variables
Edit Makefile
.PHONY: all
foo=$(var1)
var1=-$(var2)
var2=100
all:
@echo $(foo)
Compile and execute
$ make
result output
Grammar Description
- The variable defined by the = symbol is called a recursive expansion variable.
2. Simple expansion variable
Edit Makefile
.PHONY: all clean
x = foo
y = $(x) b
x = later
xx := foo
yy := $(xx) b
xx := later
all:
@echo "x = $(y), xx = $(yy)"
Compile and execute
$ make
result output
Grammar Description
- The variables defined by the := symbol are called simple expansion variables.
3. Conditional assignment variable
Edit Makefile
.PHONY: all clean
foo = x
foo ?= y
bar ?= y
all:
@echo "foo = $(foo), bar = $(bar)"
Compile and execute
$ make
result output
Grammar Description
- ? The variable defined by the = symbol is called a conditional assignment variable;
- Meaning: When the variable has not been defined before, define it and assign the value on the left to it; if it has been defined before, it will not change its original value.
Example 11: Makefile advanced variable reference function
Edit Makefile
.PHONY: all
foo=a.o b.o c.o
bar := $(foo:.o=.c)
all:
@echo "bar = $(bar)"
Compile and execute
$ make
result output
Grammar Description
- An advanced function of variable reference in the above example, which completes suffix replacement while assigning values.
Example 12: override directive
Edit Makefile
.PHONY: all
override foo=100
all:
@echo "foo = $(foo)"
Compile and execute
$ make
$ make foo=0
result output
Grammar Description
- override can prevent the value of the defined variable from being overwritten. As above: the output value of make foo=0 is still 100.
Example 13: Makefile mode
Edit Makefile
.PHONY:clean
CC = gcc
RM = rm
EXE = simple
OBJS = main.o foo.o
$(EXE):$(OBJS)
$(CC) -o $@ $^
%.o:%.c
$(CC) -o $@ -c $^
clean:
$(RM) $(EXE) $(OBJS)
Compile and execute
$ make
$ ./simple
result output
Grammar Description
- The % character pattern is similar to wildcards in the Windows operating system.
Example 14: addprefix function
Edit Makefile
.PHONY: all
without_dir = foo.c bar.c main.o
with_dir := $( addprefix objs/, $(without_dir))
all:
@echo $(with_dir)
Compile and execute
$ make
result output
Grammar Description
- addprefix is used to add a prefix to each substring in the string, in the form: $(addprefix prefix, names…)
Example 15: filter function
Edit Makefile
.PHONY: all
text = a.c b.c c.s d.h
text := $(filter %.c %.s, $(text))
all:
@echo $(text)
Compile and execute
$ make
result output
Grammar Description
- filter is used to obtain a string that satisfies the pattern according to the pattern from a string, in the form: $(filter pattern…, text)
Example 16: filter-out function
Edit Makefile
.PHONY: all
text = a.c b.c c.s d.h
text := $(filter-out %.c %.s, $(text))
all:
@echo $(text)
Compile and execute
$ make
result output
Grammar Description
- filter-out is used to filter out a part of the string from a string according to the pattern, in the form: $(filter-out pattern..., text)
Example 17: patsubst function
Edit Makefile
.PHONY: all
text = a.c b.c c.c
text := $(patsubst %.c %.h, $(text))
all:
@echo $(text)
Compile and execute
$ make
result output
Grammar Description
- patsubst is used for string replacement; at the same time, the patsubst function can use patterns, so it can also be used to replace prefixes, etc.; form: $(patsubst pattern, replacement, text)
Example 18: strip function
Edit Makefile
.PHONY: all
src = a.c b.c c.c
dst := $(strip $(src))
all:
@echo "src = $(src)"
@echo "dst = $(dst)"
Compile and execute
$ make
result output
Grammar Description
- patsubst is used to remove extra spaces in variables; form: $(strip string)
Example 19: wildcard function
Edit Makefile
//显示当前Makefile目录下所有 .c 文件
.PHONY: all
src = $(wildcard *.c)
all:
@echo $(src)
Compile and execute
$ make
Result output (foo.c main.c bar.c and other files are included in the directory where the default Makefile is located)
Grammar Description
- wildcard wildcard function, similar to "*" in Windows or Linux command line; form: $(wildcard pattern)