扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
之前我们学习了 makefile 中的变量及函数的相关语法知识,那么我们今天就来以实际需求为例来进行实际编写。实战需求:1、自动生成 target 文件夹存放可执行文件;2、自动生成 objs 文件夹存放编译生成的目标文件(*.o);3、支持调试版本的编译选项;4、考虑代码的扩展性。
成都创新互联公司长期为成百上千客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为濮阳企业提供专业的做网站、成都做网站,濮阳网站改版等技术服务。拥有10多年丰富建站经验和众多成功案例,为您定制开发。
那么在进行今天的 makefile 编写之前,我们还需要了解下几个知识点:a> $(wildcard _pattern),它的作用是获取当前工作目录中满足 _pattern 的文件或目录列表;b> $(addprefix _prefix,_names),它的作用是给名字列表 _names 中的每一个名字增加前缀 _prefix。
其中的关键技巧:1、自动获取当前目录下的源文件列表(函数调用):SRCS := $(wildcard *.c);2、根据源文件列表生成目标文件列表(变量的值替换):OBJS := $(SRCS:.c=.o);3、对每一个目标列表加上路径前缀(函数调用):OBJS := $(addprefix path/, $(OBJS))。
我们来看看规则中的模式替换(目录结构),如下
看看编译规则的依赖,如下
下来我们来看看具体的 makefile 是怎样编写的,还是以之前的那三个 .c 文件为源文件。
CC := gcc MKDIR := mkdir RM := rm -rf DIR_OBJS := objs DIR_TARGET := target DIRS := $(DIR_OBJS) $(DIR_TARGET) TARGET := $(DIR_TARGET)/hello-makefile.out # main.c func.c const.c SRCS := $(wildcard *.c) # main.o func.o const.o OBJS := $(SRCS:.c=.o) # objs/main.o objs/func.o objs/const.o OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS)) .PHONY : rebuild clean all $(TARGET) : $(DIRS) $(OBJS) $(CC) -o $@ $(OBJS) @echo "Target File ==> $@" $(DIRS) : $(MKDIR) $@ $(DIR_OBJS)/%.o : %.c ifeq ($(DEBUG),true) $(CC) -o $@ -g -c $^ else $(CC) -o $@ -c $^ endif rebuild : clean all all : $(TARGET) clean : $(RM) $(DIRS)
我们来看看编译效果
我们看到已经正确执行了,在当前目录下自动生成两个文件夹 objs target。在 objs 文件夹里生成三个 .o 文件,在 target 文件夹中生成 hello-makefile.out 文件,执行这个可执行文件,结果也是我们之前定义的。下来我们来看看能不能定义 DEBUG 版的程序,这时便要用到一个命令了 objdump -S target,它用于来查看程序是否为调试版。下来我们来看看结果,图 a 为普通版的,图 b 为 DEBUG 版的
图 a 普通版
图 b DEBUG 版
我们看到 DEBUG 版本相对于普通版来说,多了一些东西,比如我们在里面写的 printf 语句,而且多了函数调用的语句。普通版则是只执行程序就 OK 了。通过今天的综合示例的编写,总结如下:1、目录是可以成为目标的依赖的,在规则中创建目录;2、预定义函数是 makefile实战时不可或缺的部分;3、规则中的模式匹配可以直接针对目录中的文件;4、可以使用命令行变量编译特殊的目标版本。
欢迎大家一起来学习 makefile 语言,可以加我QQ:243343083。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流