千家信息网

make--变量与函数的综合示例 自动生成依赖关系

发表于:2025-02-05 作者:千家信息网编辑
千家信息网最后更新 2025年02月05日,一.变量与函数的示例示例的要求1.自动生成target文件夹存放可执行文件2.自动生成objs文件夹存放编译生成的目标文件3.支持调试版本的编译选项4.考虑代码的扩展性完成该示例所需的1.$(wild
千家信息网最后更新 2025年02月05日make--变量与函数的综合示例 自动生成依赖关系

一.变量与函数的示例

示例的要求
1.自动生成target文件夹存放可执行文件
2.自动生成objs文件夹存放编译生成的目标文件
3.支持调试版本的编译选项
4.考虑代码的扩展性
完成该示例所需的
1.$(wildcardpattern)获取当前工作目录中满足pattern的文件或目录列表
2.$(addprefix,_name)给名字列表name的每一个名字增加前缀_prefix
关键技巧
1.自动获取当前目录下的源文件列表(函数调用)

SRC : = $(wildcard *.c)

2.根据源文件列表生成目标目标文件列表(变量的值替换)

OBJS := $(SRCS:.c=.o)

3.对每一个目标文件列表加上路径前缀(函数调用)

OBJS := $(addprefix path/,$(OBJS))

规则中的模式替换(目录结构)

编译规则的依赖

编译的示例代码及运行结果

CC := gccMKDIR := mkdirRM := rm -frDIR_OBJS := objsDIR_TARGET := targetDIRS := $(DIR_OBJS) $(DIR_TARGET)TARGET := $(DIR_TARGET)/hello-makefile.out# main.c const.c func.cSRCS := $(wildcard *.c)# main.o const.o func.oOBJS := $(SRCS:.c=.o)# objs/main.o objs/const.o objs/func.oOBJS := $(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 $^    endifrebuild : clean allall : $(TARGET)clean :    $(RM) $(DIRS)

运行结果

小结:
1.目录可以成为目标的依赖,在规则中创建目录
2.预定义函数是makefile不可或缺的部分
3.规则这的模式匹配可以直接针对目录中的文件
4.可以使用命令行变量编译特殊的目标版本

二.自动生成依赖关系

一.编译行为带来的缺陷
1.预处理器将头文件中的代码直接插入源文件
2.编译器只能通过预处理后的源文件产生目标文件'
所以,规则中以源文件为依赖,命令可能无法执行
示例

在第一张图可以看出main.c与func.c是依赖于func.h的,此时将func.h中的打印信息改了之后运行的结果如下图所示


由运行的结果可以看到把打印的信息改变了,但是make之后的结果并没有改变,这是因为并没有把func.h算子啊依赖上去,所以在它的打印信息改变之后,结果还是一样的 ,需要进行以下修改才能实现修改打印信息,运行结果也改变(如图所示)

由上面的解决方法可以得出
1.头文件作为依赖条出现于每个目标对应的规则中
2.当头文件改动,任何源文件都将被重新编译
3.当项目中头文件数量巨大时,makefile将很难维护

二.改进的方法
1.通过命令自动生成对头文件的依赖
2.将生成的依赖自动包含进makefile中
3.当头文件改动后,自动确认需要重新编译的文件
所需条件
1.Linux命令sed
2.编译器依赖生成选项gcc -MM(gcc -M)
A.Linux中的sed命令
1.sed是一个流编辑器,用于流文本的修改(增/删/查/改)
2.sed可用于流文本的中的字符串替换
3.sed的字符串替换方式为 :sed 's:src:des:g'

B.sed的正则表达式支持
1.在sed中可以用正在表达式匹配替换目标
2.并且可以使用匹配的目标生成替换结果

C.gcc关键编译选项(生成依赖关系)
1.获取目标的完整依赖关系(gcc -M test.c)
2.获取目标的部分依赖关系(gcc -MM test.c)
D.makefile中的include关键字
1.类似C语言中的include
2.将其它文件的内容原封不动的搬入当前文件


make对include关键字的处理方式
a.在当前目录搜索或指定目录搜索目标文件
1.搜索成功:将文件搬入当前makefile中
2.搜索失败:产生警告
a.以文件名作为目标查找并执行对应规则
b.当前文件名对应的规则不存在时,最终产生错误
代码示例及运行结果

makefile中命令的执行机制
1.规则中的每个命令默认是在一个新的进程中执行
2.可以通过连续符(;)将多个命令组成一个命令
3.组合的命令依次在同一个进程中被执行
4.set -e指定发生错误后立即退出执行

示例:


该代码主要的目的是想在当前文件夹下新建test文件夹,然后进入test文件夹,创建subtest文件夹,但是make之后的结果如图所示,可以看到subtest与test文件夹在同一级目录,不是我们要的结果
经过修改之后的代码及运行结果

三.综合示例

思路:通过gcc -MM 和sed得到.dep依赖文件,通过inclue指令包含所有的.dep依赖文件

运行的结果:

该示例可能会出现的问题是如何在makefile在组织.dep文件到指定目录
解决的思路:
当include发现.dep文件不存在:
1.通过规则和命令创建deps文件
2.将所有.dep文件创建到deps文件夹
3..dep文件记录目标文件的依赖关系
代码实现

总结:
a.使用减号(-)不但关闭了include发出的警告,同时关闭了错误,当错误发生时make将忽略这些错误
b.当目标文件不存在(以文件名查找规则,并执行)
c.当目标文件不存在,且查找到的规则在创建了目标文件(将创建成功的目标文件包含进当前makefile)
d.当目标文件存在(将目标文件包含进当前makefile,以目标文件名查找是否有相应的规则)
e.当目标文件存在,且目标名对应的规则被执行(规则中的命令更新了目标文件,make重新包含目标文件,替换之前包含的内容),目标文件未被更新(无操作)

文件 目标 规则 结果 命令 目录 编译 生成 示例 文件夹 运行 代码 源文件 错误 函数 自动生成 信息 关键 文件名 搜索 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 数据库有 ( ) 组成. 中国 银行 网络安全 服务器普通声卡能用吗 分盘会员软件开发 网络安全管理技术研究所 服务器到期了续费多久能恢复 胶州租房网络安全 什么是net软件开发工程 江苏网络技术咨询平台 江苏省信息化建设网络安全规定 计算机终端和服务器怎么看 青岛双轨制直销软件开发公司 增城区光纤网络技术开发价格多少 数据库系统基础第六版 中文 南京点程互联网科技有限公司 安徽年喜网络技术有限公司电话 基础应用类的服务器规划 南京企业软件开发项目 计算机网络技术与应用慕课 曙光服务器驱动下载 网络安全阀法立法指导思想 闵行区项目数据库服务商前景 无线网络技术 蓝牙论文 com接口服务器出现意外情况 汕尾数据链软件开发优化价格 微信公众号服务器资源 偃师移动dns服务器地址 国务院扶贫大数据库 丹阳市环宇网络技术 重庆应用软件开发哪家便宜
0