以下基于韦东山老师的Linux应用基础之Makefile
初识
b.o : b.c
:表示,b.o依赖于b.c,当b.c有改动(即时间产生了变化)时,就会运行gcc -c -o b.o b.c
- gcc -c 表示只进行编译,而不进行链接
test : b.o a.o
gcc -o test a.o b.o
b.o : b.c
gcc -c -o b.o b.c
a.o : a.c
gcc -c -o a.o a.c
语法
:=
:定义即时变量,A:=$(C)
在定义时就马上去找,如果在当前行往上没有这个变量,则为空=
:定义延时变量,会在使用的时候去寻找C
+=
:拼接字符串?=
:如果这个变量是第一次定义,那么就赋值,如果不是,则不赋值$^
:表示所有依赖文件,即冒号后面的文件%
:通配符,类似于ls *
中的*$@
:表示目标$<
:表示第一个依赖文件.PHONY:
表示假象目标,是为了解决防止路径下有一个名称为all
文件,导致make all
无法运行的问题
A := $(C)
B = $(C)
C = 123
C += 456
D = 789
D ?= qwe
test : b.o a.o
gcc -o test $^
%.o : %.c
gcc -c -o $@ $<
all:
@echo ${A}
@echo ${B}
@echo ${C}
@echo ${D}
clean:
rm test
.PHONY: clean
函数
$(foreach f,%(A),$(f).o)
:对列表A中的每一个元素,都将其赋为xxx.o
的形式,类似于循环$(fileter %/, $(C))
:到C
中寻找符合%/
格式的值$(fileter-out %/, $(C))
:到C中寻找不符合%/
格式的值$(wildcard *.c)
:在当前目录下,寻找所有*.c文件$(wildcard $(files2))
:在当前目录下,寻找所有存在于files2
列表中的文件$(patsubst %.c,%.d,$(files2))
:将files2
中符合%.c
的文件替换为%.d
%
为通配符,类似于Linux中的*
A = a b c
B = $(foreach f,$(A),$(f).o)
C = a b c d/
D = $(fileter %/, $(C))
E = $(fileter-out %/, $(C))
files = $(wildcard *.c)
files2 = a.c b.c c.c d.c e.c
files3 = $(wildcard $(files2))
dep_files = $(patsubst %.c,%.d,$(files2))
all:
@echo B = $(B)
@echo D = $(D)
@echo E = $(E)
@echo files = $(files)
@echo file3 = $(files3)
@echo dep_files = $(dep_files)
实例
CFLAGS = -Werror
:选项变量,存放一些gcc
的选项,除了-Werror
外还可以存放-I
等-MD
:自动生成依赖文件-MF .$@.d
:自动生成的依赖文件的名称ifneq ($(dep_files),)
:判断dep_files
所包含的文件是否为空include $(dep_files)
:类似于C
语言中的#include
objs = a.o b.o c.o
dep_files := $(patsubst %,.%.d,$(objs))
dep_files := $(wildcard $(dep_files))
CFLAGS = -Werror
test:$(objs)
gcc -o test $^
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o : %.c
gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d
distclean:
rm $(dep_files)
clean:
rm *.o test
.PHONY:clean