| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 自动生成依赖关系 -> 正文阅读 |
|
[系统运维]自动生成依赖关系 |
值得思考的问题目标文件 (.o) 是否只依赖于源文件 (.c)? 编译器如何编译源文件和头文件? 编译行为带来的缺陷预处理器将头文件中的代码直接插入源文件 编译器只通过预处理后的源文件产生目标文件 因此,
下面的 makefile 有没有问题?问题的提出?makefile
当前的目录文件 ?当我们修改了 foo.h 中的内容后,结果如下 并没有再次进行编译,这导致最终可执行文件没有重新生成。? 实验中的解决方案头文件作为依赖条出现于每个目标对应的规则中 当头文件改动,任何源文件都将被重新编译 (编译低效) 当项目中头文件数量巨大时,makefile 将很难维护 疯狂的想法通过命令自动生成对头文件的依赖 将生成的依赖自动包含进 makefile 中 当头文件改动后,自动确认需要重新编译的文件 预备工作 (原材料)Linux 命令 sed 编译器依赖生成选项 gcc -MM (gcc -M) Linux 中的 sed 命令sed 是一个流编辑器,用于流文件的修改 (增/删/查/改) sed 可用于流文本中的字符替换 sed 的字符串替换方式为 sed 's:src:des:g' sed 的正则表达式支持?在 sed 中可以用正则表达式匹配替换目标 并且可以使用匹配的目标生成替换结果 gcc 关键编译选项?生成依赖关系
小技巧:拆分目标的依赖将目标的完整依赖拆分为多个多个部分依赖 预备工作?makefile
运行结果如下所示: 我们将 test 目标的依赖拆分成两部分,和直接将 test 目标的依赖写成一起是一样的。? makefile 中的 include 关键字类似 C 语言中的 include 将其它文件的内容原封不动的搬入当前文件 make 对 include 关键字的处理?在当前目录搜索或指定目录搜索目标文件
初探 include 关键字?makefile
test.txt
执行结果如下所示: 首先 make 会查找当前目录中是否存在 test.txt 文件,当前目录中存在该文件,所以 make 会将 test.txt 中的内容插入到 include 的地方,other 成为了顶层目标,所以我们在执行 make 的时候,其实是在执行 other 所对应的命令。 我们将当前目录下的 test.txt 文件删除,再次执行 make,运行结果如下所示:? 此时 make 查找不到对应的文件,所以首先会产生一个警告,然后去查找当前 makefile 中是否存在对应的目标,当前 makefile 中存在 test.txt 目标,所以会执行目标所对应的命令,这时顶层的目标为 all,所以又会去执行 all 所对应的命令。 makefile 中命令的执行机制规则中的每个命令默认是在一个新的进程中执行 (Shell) 可以通过接续符 (;) 将多个命令组合成一个命令 组合的命令依次在同一个进程中被执行 set -e 指定发生错误后立即退出执行 下面的代码想要实现功能?有没有问题?每个命令都是 Shell 开启一个新的进程执行的,进程之间不会相互影响,所以 subtest 是创建在当前目录下的,而不是 test 目录下的。? makefile 的命令执行makefile
set -e 指定发生错误后立即退出执行,并通过接续符将四个命令组合成一个命令,Shell 此时只会创建一个进程去执行这些命令,所以 subtest 是创建在 test 目录下的。 解决方案的初步思路通过 gcc -MM 和 sed 得到 .dep 依赖文件 (目标的部分依赖)
通过 include 指令包含所有的 .dep 依赖文件
解决方案原型makefile
.dep 依赖文件记录了一个目标文件所对应的依赖关系;如果对应的依赖文件不存在,则通过 include 去执行目标所对应的命令,gcc -MM 生成目标文件的依赖关系,通过 sed 将这些依赖关系都添加 objs/ 前缀,并重定向到对应的依赖文件中。 问题如何在 makefile 中组织 .dep 文件到指定目录? 解决思路当 include 发现 .dep 文件不存在时
初步的代码设计不是问题的问题为什么一些 .dep 依赖文件会被重复创建多次? 问题本质分析deps 文件夹的时间属性会因为依赖文件创建而发生改变 make 发现 deps 文件夹比对应的目标更新 触发相应的规则重新解析和命令的执行 解决方案的优化使用 ifeq 动态决定 .dep 目标的依赖 ? makefile
当 deps 文件夹不存在时,.dep 文件依赖于 deps 文件夹和对应的 .c 源文件;当 deps 文件夹被创建出来时,.dep 文件就仅仅依赖于 .c 源文件了,就不会因为文件夹时间属性的更新而重新创建目标了。 当 make 的命令行参数为 空 或者 all 时,将依赖关系包含进 makefile 中。 include 暗黑操作一:使用了减号 (-) 不但关闭了 include 发出的警告,同时关闭了错误;当错误发生时,make 将忽略这些错误! ? include 暗黑操作二:如果 include 触发规则创建了文件,之后还会发生什么? ? include 暗黑操作三:如果 include 包含的文件存在,之后还会发生什么? 预备实验?makefile.1
当前目录下仅有 makefile,执行结果如下所示: 由于当前目录下不存在 test.txt,所以在 include 的时候会产生一个错误,make 终止执行。 在 include 前加上 '-' 后,执行结果如下所示: 尽管当前目录中不存在 test.txt,由于 include 前加上了 '-' ,它会屏蔽 include 产生的所有警告和错误,并继续向下执行。 ? makefile.2
执行结果如下所示: 当前目录下不存在 test.txt,include 发现不存在对应的文件后,就回去查找有没有 test.txt 这个目标,发现这个目标存在就去执行对应的命令,这个命令将创建 test.txt,并且将?other : ;@echo "this is other" 写入到 test.txt 中,并将 test.txt 的内容包含进 makefile,此时 other 为顶层目标,我们去执行 make 的时候,执行的就是 other 目标。? 当命令和目标、依赖 写在一行后,';' 后面为命令。\" 为转义为 " 字符。 makefile.3
test.txt
当前目录下存在 test.txt, b.txt。 执行结果如下所示: 由于当前目录下存在 test.txt,make 将 test.txt 的内容包含进 makefile 中,并且去查看是否存在 test.txt 的目标,查找到有对应的 test.txt 目标后,会查看依赖关系决定是否执行命令,由于这里的 b.txt 比 test.txt 更新,所以会执行对应的命令,打印 creating test.txt ...;最后,执行顶层命令。? makefile.4
test.txt
当前目录下存在 test.txt,b.txt,c.txt。 执行结果如下所示: make 首先会将 test.txt 内容包含进 makefile,然后去查看 test.txt 这个目标,由于 b.txt 比 test.txt 更新,所以会执行 test.txt 所对应的命令,重新创建 test.txt,并将??all : c.txt 写入到 test.txt,此时 include 会将 test.txt 重新包含进来,去执行顶层目标 all。 关于 include 的总结一当目标文件不存在时
当目标文件不存在,且查找到的规则中创建了目标文件
关于 include 的总结二当目标文件存在
关于 include 的总结三当目标文件存在,且目标名对应的规则被执行
疯狂想法的具体实现注意事项?当 .dep 文件生成后,如果动态的改变头文件间的依赖关系,那么 make 可能无法检测到这个改变,进而做出错误的编译决策。 解决方案将依赖文件名作为目标加入自动生成的依赖关系中 通过 include 加载文件时判断是否执行规则 在规则执行时重新生成依赖关系文件 最后加载新的依赖关系 疯狂的想法makefile
执行 make 时,首先查看 include,然后才是执行顶层目标所对应的规则。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/16 8:28:30- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |