第二篇 makefile的基本结构
makefile用于定义并描述源文件之间的依赖关系,用于说明如何编译各个源文件并生成最终的可执行文件,规则是makefile中的基本组成部分。
一个最基本的依赖规则如下所示:

targets代表这个规则的目标,通常是需要生成的目标文件名,或者是make所需执行的命令名称,例如:all。prerequisites代表该规则的依赖,也即当前目标所依赖的其他目标或者文件。command为规则的命令即完成目标所要执行的命令,也叫动作,可以写为图中command1的形式,即和依赖写在同一行,和依赖之间通过分号隔开。也可以写成command2的形式,即写在依赖的下一行,并以tab键开头,tab字符告诉make解释器此行是一个命令行。可以使用续行符“\”将内容分开写到下一行,提高可读性。
targets可以包含多个目标,使用空格对多个目标名进行分隔。prerequisites也可以包含多个依赖,通过空格对多个依赖进行分隔。
一个简单的makefile如下:

上图中,all目标依赖test目标,即需要test的存在,并执行echo "make all"命令才可以完成。而test目标没有依赖,只需要执行echo "make test"即可完成。
运行make命令,得到下图的结果,可以看到test目标先执行,然后才能执行all目标。小技巧:在命令之前加上@符号,可以不输出命令本身,使命令无回显,而只输出命令执行结果。

一个规则被执行需要满足以下条件中的一个:
1、当目标对应的文件不存在,执行对应的命令。
2、当依赖在时间上比依赖更新,执行对应的命令。
3、当依赖关系连续发生时,对比依赖链上的每一个目标。
另一个makefile案例:

hello.out需要func.o和main.o文件的存在,并执行对应的命令才能完成。main.o依赖main.c,并执行相应命令才能完成。func.o依赖func.c,并执行相应命令才能完成。执行make后,输出如下所示,可见,只有main.o func.o子目标完成后,才能生成最终的目标hello.out。

修改func.c,再次执行make,输出如下,main.o没有被重新生成,而只有func.o和hello.out的目标对应的命令被执行了,因为main.o存在,且在时间上比 main.c更新,所以该目标对应的命令不会执行,无需重新生成。

将hello.out目标改为all,如下所示:

当我们再次执行make时,gcc -o hello.out main.o func.o,这句命令总会执行,即使依赖文件并没有更新,这是因为在当前目录下并没有一个叫all的文件存在,make在解析makefile时,发现当前路径下没有all文件,而这正符合三个条件中的第一个,因此,命令会被执行。解决技巧如下:

将hello.out和all目标写在一起,当执行make时,make解释器默认的目标是hello.out,当前目录下会存在hello.out文件,因此,当依赖不改变时,多次执行make命令也不会去更新最终的可执行文件了,而是给出文件是最新的提示,如下所示:

欢迎评论、指导以及进一步交流,QQ527635593
本文参考:
狄泰软件教学课件
gun make手册
专业嵌入式软件开发
第二篇 makefile的基本结构的更多相关文章
- “MVC+Nhibernate+Jquery-EasyUI”信息发布系统 第二篇(数据库结构、登录窗口、以及主界面)
“MVC+Nhibernate+Jquery-EasyUI”信息发布系统 第二篇(数据库结构.登录窗口.以及主界面) 一.在上一篇文章中,主要说的就是把主框架搭建起来,并且Nhibernate能达到增 ...
- 使用wepy开发微信小程序商城第二篇:路由配置和页面结构
使用wepy开发微信小程序商城 第二篇:路由配置和页面结构 前言: 最近公司在做一个微信小程序的项目,用的是类似于vue的wepy框架.我也借此机会学习和实践一下. 小程序官方文档:https://d ...
- linux-0.11分析:boot文件 setup.s 第二篇随笔
boot文件 setup.s 第二篇随笔 参考 [github这个博主的][ https://github.com/sunym1993/flash-linux0.11-talk ] 中断获取光标的位置 ...
- 《javascript权威指南》读书笔记——第二篇
<javascript权威指南>读书笔记——第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字 ...
- 第二篇.Bootstrap起步
第二篇Bootstrap起步 我们可以在http://getbootstrap.com下载bootstrap的文件 点击左边的download bootstrap可以下载bootstrap的css,j ...
- 【OpenGL】第二篇 Hello OpenGL
---------------------------------------------------------------------------------------------------- ...
- 解剖SQLSERVER 第二篇 对数据页面头进行逆向(译)
解剖SQLSERVER 第二篇 对数据页面头进行逆向(译) http://improve.dk/reverse-engineering-sql-server-page-headers/ 在开发Orc ...
- 深入理解javascript作用域系列第二篇——词法作用域和动态作用域
× 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...
- [老老实实学WCF] 第二篇 配置WCF
老老实实学WCF 第二篇 配置WCF 在上一篇中,我们在一个控制台应用程序中编写了一个简单的WCF服务并承载了它.先回顾一下服务端的代码: using System; using System.Col ...
随机推荐
- hdu 6020 MG loves apple 恶心模拟
题目链接:点击传送 MG loves apple Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Ja ...
- 强大的Manage
Queue和Pipe实现的数据共享方式只支持两种结构 Value 和 Array.Python中提供了强大的Manage专门用来做数据共享,其支持的类型非常多,包括: Value,Array,list ...
- ros python 订阅robot_pose
#!/usr/bin/env python import rospy import tf import time from tf.transformations import * from std_m ...
- python 正则表达式替换字符串中匹配的字符
import re street = '21 Ramkrishna Road' print(re.sub('Road$', 'Rd.', street)) 将结尾的Road用Rd.替换
- c++ primer plus 第五章 课后题答案
#include <iostream> using namespace std; int main() { ; cout << "Please enter two n ...
- 一个很棒的Flutter学习资源列表
目录 文章 一开始 HOWTO文档 网站/博客 高级 视频 组件 演示 UI 材料设计 图片 地图 图表 导航 验证 文字和富文本 分析.流量统计 自动构建 风格样式 媒体 音频 视频 语音 存储 获 ...
- Shell需注意的语法问题
1.文件头声明别漏掉#和! #!/bin/bash 2.赋值语句①=号两端不能有空格(判断语句=号两端必须有空格)②使用变量必须使用符号$ var1=valecho $var1 3.if语句写错下面任 ...
- 如何查看DNS?
查看dns服务ip: 命令: ipconfig/all 查看dns缓存: 命令:ipconfig/displaydns 强制更新缓存: 命令:ipconfig /flush ...
- 雷林鹏分享:Ruby 类案例
Ruby 类案例 下面将创建一个名为 Customer 的 Ruby 类,您将声明两个方法: display_details:该方法用于显示客户的详细信息. total_no_of_customers ...
- Confluence 6 LDAP 用户结构设置
用户对象类(User Object Class) 这个是在 LDAP 用户对象中对用户分类的名字.例如: user 用户对象过滤器(User Object Filter) 当对用户对象进行搜索的时候 ...