6. 编译生成多个可执行文件
  假设现在不只是想生成可执行main,还想生成可执行文件main2,可以这样写
BIN = main main2                【自定义变量BIN】
OBJECTS= main.o add.o sub.o
all : $(BIN)   【关注重点】
main : $(OBJECTS)
gcc -Wall -g  $< -o $@
main2: $(OBJECTS)
gcc -Wall -g  $< -o $@
main.o : main.c
gcc -Wall -g -c $< -o $@
main2.o :msin2.c
gcc -Wall -g -c $< -o $@
add.o:add.c add.h
gcc -Wall -g -c $< -o $@
sub.o:sub.c sub.h
gcc -Wall -g -c $< -o $@
clean :
rm -f $(OBJECTS) $(BIN)
  为了生成目标文件all,需要先生成BIN,也即是 main main2。这样可以生成两个可执行文件了。利用自定义变量可以再简化这段Makefile文件:
BIN = main main2
OBJECTS= main.o add.o sub.o
CC = gcc
CFALGS = -Wall -g
all : $(BIN)
main : $(OBJECTS)
$(CC) $(CFALGS)  $< -o $@
main2: $(OBJECTS)
$(CC) $(CFALGS)  $< -o $@
main.o : main.c
$(CC) $(CFALGS) -c  $< -o $@
main2.o :msin2.c
$(CC) $(CFALGS) -c  $< -o $@
add.o:add.c add.h
$(CC) $(CFALGS) -c  $< -o $@
sub.o:sub.c sub.h
$(CC) $(CFALGS) -c  $< -o $@
clean :
rm -f $(OBJECTS) $(BIN)
  但是这样看起来,重复的内容还是比较多,可以使用下面的方法来继续简化:
BIN = main main2
OBJECTS= main.o add.o sub.o
CC = gcc
CFALGS = -Wall -g
all : $(BIN)
main : $(OBJECTS)
$(CC) $(CFALGS)  $< -o $@
main2: $(OBJECTS)
$(CC) $(CFALGS)  $< -o $@
.o .c :                                               【关注重点在这里】
$(CC) $(CFALGS) -c  $< -o $@
clean :
rm -f $(OBJECTS) $(BIN)
  利用 .o.c :,可以自动地把所有的.c文件到.o文件的生成都使用同一条命令来完成,简化的重复的工作。
  7. make常用的内嵌函数
  首先看make中函数调用的形式:
  //函数调用
  $(function arguments)     【function是函数名称,arguments是参数,使用$来调用】
  值得注意的是,函数名称与参数之间是空格。
  来看三个常用make内嵌函数。
  $(wildcard PATTERN) 作用是在当前目录下匹配模式的文件。
  src = $(wildcard *.c)  【在当前目录下搜索所有.c文件,文件名称列表保存到src中】
  $(patsubst PATTENR,REPLACEMENT,TEXT) 模式替换函数,作用是把TEXT中文件列表从模式PATTENR替换为REPLACEMENT模式。
  $(patsubst %.c,%.o,$src)  【把src中的.c文件列表中的文件从.c替换为.o】
  等价于:
  $(src:.c =.o)   【这种方式更常用】
  shell函数
  shell函数可以执行shell下的命令,同样是使用$来引用,例如
  $(shell ls -d */) 【将当前目录下的所有文件夹都列出来】
  下面通过一个多级目录的例子来使用这些函数。场景是这样的,当前目录下有main.c文件,同时还有若干个目录,每个目录中都有各自的.c文件。利用所有的.c文件编译生成后的main文件:
CC       = gcc
CFLAGS   = -Wall -g
BIN      = main
SUBDIR   = $(shell ls -d */)      【SUBDIR变量保存了子目录的列表】
ROOTSRC  = $(wildcard *.c)  【ROOTSRC保存了当前目录下的.c文件列表】
ROOTOBJ  = $(ROOTSRC:%.c = %.o)  【ROOTBOJ 保存了当前目录下.c文件同名的.o列表】
SUBSRC   = $(shell find $(SUBDIR) -name '*.c')  【SUBSRC 保存了所有子目录下的的.c文件】
SUBOBJ   = $(SUBSRC:%.c = %.o)     ?    ?【SUBOBJ保存了所有子目录下的.c文件同名的.o文件列表】
$(BIN):$(ROOTOBJ) $(SUBOBJ)         【main的生成依赖与当前目录及所有子目录下的.o文件】
$(CC) $(CFLAGS) -o $(BIN) $(ROOTOBJ) $(SUBOBJ)
.o .c:
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(BIN) $(ROOTOBJ) $(SUBOBJ)