第十篇 变量与函数的综合实战

在实际的工程项目中,生成的目标文件、最终可执行文件以及其它中间文件都需要进行管理,而不是生成在同一个目录下,本次,我们给出下面的实战需求:
  1、自动生成target文件夹存放可执行文件。
  2、自动生成objs文件夹存放编译生成的目标文件(*.o)。
  3、支持调试版本的编译选项。
  4、考虑代码的扩展性。
 
 下面先引入一些需要用到的工具原料,如下:
 
wildcard和addprefix都是make中的预定义函数,wildcard用来获取当前工作目录中的符合_pattern的文件并返回一个文件列表或者目录列表。
addprefix用于给名字列表_names中的每一个名字增加前缀。
关键技巧:
 
规则中的模式替换:
 
  上图中的模式替换写法为%.o : %.c,这种写法同第六篇中的模式规则有所不同,所代表的意义也不同,第六篇中的写法为OBJS := func.o main.o,OBJS : %.o : %c,意义为把OBJS列表中符合%.o模式的目标名给取出来,然后在将取出来的目标名后缀换位.c作为依赖。因此,第六篇中这种模式替换写法针对的是列表。
  本篇的写法中,直接对当前工作目录下的文件进行模式匹配,即%.c用于模式匹配当前目录下的文件,例如,当前目录下有func.c和main.c文件,make匹配到func.c,%.o用于将%.c匹配成功的文件名进行模式替换,.c替换为.o,从而生成func.o : func.c这个规则,而main.c同理。本篇中的模式替换针对的目标是当前工作目录。
  综合的示例的编译依赖如下:
 
 
 下面给出makefile程序:
复制代码
 1 CC := gcc
 2 MKDIR := mkdir
 3 RM := rm -fr
 4 
 5 DIR_OBJS := objs
 6 DIR_TARGET := target
 7 
 8 DIRS := $(DIR_OBJS) $(DIR_TARGET)
 9 
10 TARGET := $(DIR_TARGET)/hello-makefile.out
11 # main.c const.c func.c
12 SRCS := $(wildcard *.c)
13 # main.o const.o func.o
14 OBJS := $(SRCS:.c=.o)
15 # objs/main.o objs/const.o objs/func.o
16 OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))
17 
18 .PHONY : rebuild clean all
19 
20 $(TARGET) : $(DIRS) $(OBJS)
21     $(CC) -o $@ $(OBJS)
22     @echo "Target File ==> $@"
23     
24 $(DIRS) :
25     $(MKDIR) $@
26     
27 
28 $(DIR_OBJS)/%.o : %.c
29     ifeq ($(DEBUG),true)
30         $(CC) -o $@ -g -c $^ 
31     else   
32         $(CC) -o $@ -c $^
33     endif
34     
35 rebuild : clean all
36 
37 all : $(TARGET)
38 
39 clean :
40     $(RM) $(DIRS)
41     
42     
复制代码

 

 
   第28行的模式规则$(DIR_OBJS)/%.o : %.c中,加上了路径前缀,但是不影响模式匹配的含义,依旧根据%.o : %.c模式规则在当前目录下搜索文件,然后将.c替换为.o,并且添加目录前缀作为整体目标,也即将目标生成到指定的目录下。
小结:
   1、目录可以成为目标的依赖,在规则中创建目录。
   2、预定义函数是makefile实战时不可或缺的部分。
   3、规则中的模式匹配可以直接针对目录中的文件。
   4、可以使用命令行变量编译特殊的目标版本。
posted @ 2018-12-30 21:13  lemaden  阅读(85)  评论(0编辑  收藏  举报