【Linux + Makefile】十分钟教你学会Makefile的FORCE
相信大家在使用Linux环境编程的时候,一定接触过Makefile这个玩意。Makefile在搭建自定义的编译环境,尤其是自动化编译、多功能一键编译等功能上,还是发挥了很大的作用。如果接触过Linux内核编译的童鞋,一定会看到编译内核中的各级Makefile中,有很多地方都会有 FORCE 这样的字段出现,那么这个 FORCE 究竟是何方神圣呢?本文将给你答案,通过阅读本文,你讲了解到以下内容:
- Makefile的基本规则
- FORCE 在Makefile的含义
- FORCE在实际工程中的应用
Makefile的基本规则
Makefile的基本形式如下所示:
TARGET : DEPENDENCESCMD# TARGET:生成的目标,可以是一个文件,也可以是一个虚拟符号(非真实文件)
# DEPENDENCES: 生成目标的所有依赖,它是一个集合,可以只有一个文件,或者很多文件;也可以是虚拟符号
# CMD:把所有依赖生成目标的执行命令,其中CMD前面是一个TAB键,而不能是空格
Makefile的基本规则,归纳起来就是一句话:【当一个TARGET (欲生成的目标)比它的任何一个DEPENDENCES(依赖的文件)旧时,这个TARGET就要重新生成】。
这句话读起来很简单,就是Makefile在执行编译的时候,会先去判断TARGET和其依赖文件的时间,如果TARGET的时间比较旧,意味着依赖文件有更新了,所以TARGET要重新生成;反之,如果TARGET的时间比较新,意味着在TARGET生成后,依赖文件是没有改变过的,自然就不用重新去生成TARGET。
FORCE 在Makefile的含义
有了上一小节中介绍的Makefile基本概念后,我们来进一步分析下Makefile中的FORCE,以下是FORCE在Makefile中出现的最简化版本:
file = test.txtall: generate-a-filegenerate-a-file: $(file) $(file):@echo "Force to generate a test file for every make ..."rm -rf $(file) && echo `date "+%Y-%m-%d %H:%M:%S"` > $(file)FORCE:
.PHONY: FORCE
这个Makefile不是用于真正的编译工程,而是提供一个很简单的功能,生成一个test.txt,并且这个test.txt的内容是记录每次编译的时间。但是使用这个makefile执行make时,发现只有第一次make的时候,才会生成test.txt,而其他时候只要test.txt还存在都不会重新生成,如下所示:
很明显,它没有达到我们期望的“每次编译都重新生成test.txt”。这个时候 FORCE 就发挥作用了,我们在 test.txt目标的后面添加 FORCE作为它的依赖试试看,即如下所示:
file = test.txtall: generate-a-filegenerate-a-file: $(file) $(file): FORCE #FORCE表示每次这段都要执行@echo "Force to generate a test file for every make ..."rm -rf $(file) && echo `date "+%Y-%m-%d %H:%M:%S"` > $(file)FORCE:
.PHONY: FORCE
执行输出如下所示: 我们可以看到,这达到了我们的目的,每次test.txt都是重新生成了,它记录了每次make的时间。
这个就是要归功于 FORCE 的功劳了。我们来分析下,为何加了 FORCE 就能实现这样的功能。
我们可以注意到FORCE这个目标,它的DEPENDENCES是空的,CMD部分也是空的;这个比较特殊了,在Makefile里,像这样依赖为空、执行命令也为空的TARGET,则需要每次都重新生成,而这个TARGET不一定是一个文件,可以是任意的符号,而 FORCE 只是我们最常用的符号,理论上它可以换成任意符号,比如NO-FORCE、SOMETHING等等。
FORCE在实际工程中的应用
上一小节,我们讲到可以用Makefile配合shell命令来自动生成一些文件,自然我们很容易想到,在我们实际的编译工程中,往往需要动态生成一些配置项,然后嵌入到代码中,比如编译版本号、编译时间等。
假设我们有以下一个main.c:
#include <stdio.h>
#include "build_info.h" #这个头文件需要每次编译时自动生成int main(int argc, const char *argv[])
{printf("%s >>> APP_TIME=%s\n", __func__, APP_TIME);return 0;
}
示例代码很简单,就是再main函数中打印一个 build_info.h中的一个宏定义APP_TIME,这个build_info.h要求每次编译的时候都重新生成。我们给出的Makefile示例如下:
##拷贝时,注意tab键
SHELL = /bin/bash #指定shell使用/bin/bash,否则echo -e可能会出问题
ECHO = echo
BIN = test
BUILG_INFO_H = build_info.h
SRC-C-y = main.c
SRC-O = $(patsubst %.c, $(O)%.o, $(SRC-C-y))all: gen_build_info $(BIN)$(BIN) : $(SRC-O)gcc -o $(O)"$@" $(SRC-O)%.o : %.cgcc -c "$<" -o "$@"gen_build_info: $(BUILG_INFO_H)$(BUILG_INFO_H): FORCE #强制生成build_info.h@$(RM) $@@$(ECHO) ' GEN $@'@$(ECHO) -e " #ifndef __BUILD_INFO_H__\n"\"#define __BUILD_INFO_H__\n"\"#define APP_TIME \"`date "+%Y-%m-%d %H:%M:%S"`\"\n"\"#endif" > $@FORCE:
.PHONY: FORCE
make执行输出测试如下:
从输出的测试,我们可以看出,make的每次执行都触发了生成build_info.h,但是运行编译出来的test可执行程序,我们发现并不是每次生成的build_info.h的内容都传递到了test里面;也就是当build_info.h改变的时候,test没有被重新编译。这里先留下点疑问,为何会产生这样的问题。博主将会在后续的文章中解决这个问题。
不管怎么样,经过对上文的学习,我们至少掌握了 FORCE的基本用法,而在实际项目工程中,我们也见证了它的威力;那么,你学会了吗?如果还有疑问,欢迎在评论席提出你的问题和看法,博主定会尽力解决你的困惑。
版权申明:本文为博主原创文章,转载请注明出处!【Linux + Makefile】十分钟教你学会Makefile的FORCE_架构师李肯-CSDN博客
原创作者:recan
电子邮箱:recan.szu@foxmail.com
延伸阅读:
【Linux + Makefile】Makefile的高阶用法:解决C文件包含的头文件修改了,但C文件不重新编译的问题
【Linux + Makefile】十分钟教你学会Makefile的FORCE相关推荐
- 一分钟教你学会python_十分钟教你学会python编写小游戏
原标题:十分钟教你学会python编写小游戏 看过,估计大家都已经精通了吧,好的,话不多说,今天就活学活用,用python来编写纸牌游戏21点,江湖人称黑杰克,BLACK JACK-(注意法式卷舌). ...
- python编写小游戏17_十分钟教你学会python编写小游戏
原标题:十分钟教你学会python编写小游戏 看过,估计大家都已经精通了吧,好的,话不多说,今天就活学活用,用python来编写纸牌游戏21点,江湖人称黑杰克,BLACK JACK-(注意法式卷舌). ...
- origin做相关性分析图_高分文章的相关性热图,十分钟教你学会无代码复现
相关性热图可以便捷的显示多个变量之间的相关性,因此在组学数据分析中得到广泛应用,例如基因的共表达分析.样本重复检验.微生物群落的共发生网络分析等. 在昨天推文下就有人问热图怎么画?画热图最常规的办法自 ...
- 十分钟教你学会打包APP
我们打包APP需要用到HBuilder,所以先讲解如何安装使用 HBuilder的下载与安装 HBuilder的官网下载地址:https://www.dcloud.io/ 点击DOWNLOAD后会弹出 ...
- 十分钟教你开发EOS智能合约
十分钟教你开发EOS智能合约 在CSDN.柏链道捷(PDJ Education).HelloEOS.中关村区块链产业联盟主办的「EOS入门及最新技术解读」专场沙龙上,柏链道捷(PDJ Educatio ...
- 十分钟教你配置frp实现内网穿透
十分钟教你配置frp实现内网穿透 一.frp的作用 利用处于内网或防火墙后的机器,对外网环境提供 http 或 https 服务. 对于 http, https 服务支持基于域名的虚拟主机,支持自定义 ...
- java连接数据库 oracle,Oracle数据库之一分钟教你学会用java连接Oracle数据库
本文主要向大家介绍了Oracle数据库之一分钟教你学会用java连接Oracle数据库,通过具体的内容向大家展现,希望对大家学习Oracle数据库有所帮助. package java_jdbc; // ...
- 元件怎么反转_电气图纸怎么看?三分钟教你学会看懂,受用一生
图纸一般用于设计方面,设计师绘制出图纸,我们再根据图纸进行操作,尤其是电气图纸,上面有很多符号,很难看懂,下面通过三分钟教你学会看懂电气图纸. 一.什么是电气图 用电气图形符号.带注释的围框或简化外形 ...
- python批量删缩进_鬼畜小姐姐+野狼disco,十分钟教你如何用Python剪辑一个牛逼的抖音小视频?...
鬼畜小姐姐+野狼disco,十分钟教你如何用Python剪辑一个牛逼的抖音小视频? 前言 半个月前,后台有个小伙伴问我,如何将视频中的音频提取出来,并且将声音转成文字写入到 word 中,正好接下来的 ...
最新文章
- torch量化其他功能(量化、反量化)
- python project_GitHub - DeqianBai/Python-Project: A series of python projects
- js字符串的各种格式的转换 ToString,Format
- 盯紧那群养生的年轻人,他们的焦虑值300亿
- 搭建hypervisor类型为VMWare的cloudstack环境
- CentOS-6.0下安装配置Cacti
- 华为动态NAT小实验演示
- html三元运算符 模板,AngularJS模板中的三元运算符
- 【OpenCV】OpenCV函数精讲之 -- 通道合并:merge()函数
- 被灵魂问倒:这个BUG为什么没测出来?
- 题解【luogu2045 方格取数游戏加强版】
- vs2017安装完成,但有错误。
- BrainOS —最像大脑的AI
- 417.太平洋大西洋水流问题
- c语言一些简单的程序
- Jetson nano : PWM风扇调速。
- 【毕业设计/课程设计】企业员工绩效考评APP的设计与实现
- 对标阿里P6-P7高级Java程序员的进阶技术路线
- 用c语言录入3组学生数据编程,学生信息管理系统C语言编程
- 2021年德阳2中高考成绩查询,2021年德阳高中录取分数线是多少及高中排名榜