Easily master Makefile with the help of examples -- sprouting ground



Budding breaks ground

insert image description here

Example 1: hello world


Edit Makefile

all:
	echo "hello world"


Compile and execute

$ make
$ make all 


result output

insert image description here


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

insert image description here


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

insert image description here

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

insert image description here


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

insert image description here


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.

insert image description here

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

insert image description here


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

insert image description here

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

insert image description here


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
insert image description here


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
insert image description here


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 outputinsert image description here


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
insert image description here


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
insert image description here


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 outputinsert image description here


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

insert image description here


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

insert image description here


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

insert image description here


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
insert image description here


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

insert image description here


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

insert image description here


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

insert image description here


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)

insert image description here


Grammar Description

  • wildcard wildcard function, similar to "*" in Windows or Linux command line; form: $(wildcard pattern)

Guess you like

Origin blog.csdn.net/locahuang/article/details/126966304