Makefile学习笔记(三)
概述
只依靠简单的变量和模式规则写一个复杂项目的Makefile是比较困难的,也不是不能写,只是源文件一多,模式规则的量就很大。庆幸的是,make提供了一些函数,可以很方便地写出复杂项目的Makefile。这里就来记录一下两个比较常用的make函数。
make函数调用形式
make函数调用,与变量获取形式类似: $(func param),参数param根据所调用函数来传递,参数间用’,’隔开。
wildcard
考虑一种情况,某文件夹下的源文件编译之后产生的.o文件,将被其他部分链接,该文件夹下的源文件又比较多,手打的话,也是很麻烦的一件事。这里使用make提供的wildcard函数就很方便了,wildcard可用于获取工作目录下符合匹配模式的文件列表,比如:
$(wildcard *.c) # 获取工作目录下的后缀为c的源文件列表,以空格形式隔开
有了wildcard,在编写数目较大的模式规则时就方便多了,只要写出合适的匹配模式即可。
patsubst
patsubst主要用于文本替换,函数原型为: $(patsubst parttern, replacement, text),当text中有满足pattern的部分时,以replacement替换该部分。比如:
$(patsubst %.c, %.o, $(wildcard *.c)) # 获取工作目录下c文件列表,并将文本中的后缀c改为后缀o
只看这些,可能还是不能很好的理解这两个函数,下面就以一个万能Makefile模板来说明上面两个函数的运用。
实例
CC := clang
LIBS :=
LDFLAGS :=
DEFINES :=
INCLUDE := -I ./
CFLAGS := -std=c11 -Wall -g $(DEFINES) $(INCLUDE)
CXXFLAGS := -std=c++14 -Wall -g $(DEFINES) $(INCLUDE)
SOURCE := $(wildcard *.c) # 获取工作目录下的源文件列表
OBJS := $(patsubst %.c, %.o, $(SOURCE)) # 将文本中后缀c的部分换为后缀o
TARGET := test
all: $(TARGET)
@echo $(SOURCE)
@echo $(OBJS)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
objs: $(OBJS) # 依赖make隐式推导,编译.c文件为对应名称的.o文件
clean:
@rm -f *.o
@rm -f $(TARGET)
上面这段万能Makefile适用于C项目,由wildcard、patsubst和make的隐式规则推导构成。all下的echo可以看出两个函数的结果,稍微理解一下就清楚怎么用了。