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) |