make 常用内嵌函数以及多级目录Makefile
一、函数调用 $(function arguments),利用$号引用函数,下面是Makefile中常用三个函数:
1、$(wildcard PATTERN):wildcard函数
当前目录下匹配模式的文件,例如 src=$(wildcard *.c),匹配所有的.c文件,生成的src就是所有的.c文件。
3、$(patsubst PATTERN , REPLACEMENT , TEXT) : patsubst是一个模式替换函数
例如$(patsubst %.c ,%.o,$src) 等价于 $(src:.c=.o) ,将src中所有.c文件替换为.o文件
4、shell函数
执行shell命令,例如$(shell ls -d */) :将当前文件夹下面的所有文件夹列出来。
二、二级目录Makefile
CC =gcc CFLAGS =-Wall -g BIN =main SUBDIR =$(shell ls -d */) #当前目录下的所有文件夹 ROOTSRC =$(wildcard *.c) #查找当前目录下所有.c文件 ROOTOBJ =$(ROOTSRC:%.c=%.o) #将.c文件名替换成.o文件名 SUBSRC =$(shell find $(SUBDIR) -name '*.c') SUBOBJ =$(SUBSRC:%.c=%.o) $(BIN):$(ROOTOBJ) $(SUBOBJ) #第一个目标是总的目标 $(CC) $(CFLAGS) -o $(BIN) $(ROOTOBJ) $(SUBOBJ) .c.o: $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(BIN) $(ROOTOBJ) $(SUBOBJ)
三、将每个目录下的文件都生成一个可执行文件(多级目录Makefile):
这个Makefile是递归执行,假设有一个目录,包含一个Makefile文件和两个目录test1 test2。其中test1目录下包含:test1.c 、Makefile 。test2目录下包含test2.cpp、Makefile。
首先看一下主目录下的Makefile:
SUBDIRS =test1 test2 .PHONY:default all clean $(SUBDIRS) #一共5个伪目标 default :all all clean: $(MAKE) $(SUBDIRS) TARGET=$@ # $(MAKE)相当于make,这句相当于 make test1 test2 TARGET=all,并进入当前目录。同理执行make clean也是给子目录传递clean $(SUBDIRS): $(MAKE) -C $@ $(TARGET) #将TARGET(all)传递到下一层目录,make -C进入子目录,再执行make命令。这一行生成test1 test2. (make -C test1 all)等价于make all test1/Makefile
make的递归执行,make的“-C”选项,是首先进入子目录而后再执行make。进入test1中的Makefile后,查看一下test1中Makefile内容:进入子目录之后,执行make all,要生成all,先 生成print与$(BIN)
CC =gcc BIN =test1 OBJS =test1.o .PHONY: all clean print all:print $(BIN) print: @echo "---- make all in $(PWD) ----" $(BIN):$(OBJS) $(CC) $(OBJS) -o $@ %.o:%.c $(CC) -c $< clean: @echo "---- make clean in $(PWD) -----" rm -f $(BIN) $(OBJS)
同理进入test2目录下,对于test2.cpp,该目录下的Makefile文件如下:
CXX =g++ BIN =test2 OBJS =test2.o CPPFLAGS =-Wall -g .PHONY: all clean print all:print $(BIN) print: @echo "---- make all in $(PWD) ----" $(BIN):$(OBJS) $(CXX) $(OBJS) -o $@ %.o:%.cpp $(CXX) -c $< clean: @echo "---- make clean in $(PWD) ----" rm -f $(BIN) $(OBJS)