linux开发工具之Makefile(下)

时间:2021-09-05 02:22:04

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)