在学习李云《驾驭Makefile》出现了一点问题,本着刨根问底,遇到问题不忽略,要搞明白的精神,要把遇到的问题解决,然后总结分享。
在李云《驾驭Makefile》:http://yunli.blog.51cto.com/831344/195759(感谢李大牛的无私奉献精神)中模仿2.5节对Makefile后,进行编译,会不断的刷死循环,如图所示,怎么改都不对,不知为何。
先把Makefile贴上
.PHONY:clean all
CC=gcc
RM=rm
BIN_DIR=bin
OBJ_DIR=objs
MKDIR=mkdir
DIR_DEPS=deps
RM_OP=-rf
EXE=simple
EXE:=$(addprefix $(BIN_DIR)/, $(EXE))
SRC=$(wildcard *.c)
OBJS=$(patsubst %.c, %.o, $(SRC))
DIRS = $(BIN_DIR) $(OBJ_DIR) $(DIR_DEPS)
OBJS:=$(addprefix $(OBJ_DIR)/, $(OBJS))
DEPS = $(SRC:.c=.dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
bar ?= $(OBJS:.o=.c)
all : $(EXE)
#1
-include $(DEPS)
$(DIRS):
$(MKDIR) $@
$(EXE):$(BIN_DIR) $(OBJS)
$(CC) -o $@ $(filter %.o, $^)
$(OBJ_DIR)/%.o: $(DEP_OBJ_DIR) %.c
$(CC) -o $@ -c $(filter %.c, $^)
#2
$(DIR_DEPS)/%.dep:$(DIR_DEPS) %.c
@echo "Making $@..."
@set -e;\
$(RM) $(RM_OP) $@;\
$(CC) -E -MM $(filter %.c, $^) > $@.tmp;\
sed 's,\(.*\)\.o[:]*,objs/\1.o $@:,g' < $@.tmp > $@;\
$(RM) $(RM_OP) $@.tmp
clean:
$(RM) $(RM_OP) $(DIRS)
----------------------------------------------------------我是分隔符-------------------------------------------------------
引起问题的关键有两个地方,一个是采用include关键字,包含了.dep文件,二是.dep目录是生成.dep的先决条件(或称依赖关系)。make在执行Makefile时,会先将依赖文件扫描一遍,如果在编译的过程中,被依赖文件变化了,(make查看文件时间戳),就会重新编译过程,以保证将最新的变化编译进可执行文件,这一点毋庸置疑,是make的特点。而上面的Makefile之所以产生死循环,那是因为生成.dep文件时,同时改变了dep文件目录的时间戳,对于make命令来说,作为生成.dep文件所依赖的.dep目录就不是最新的了,而这个目录是生成.dep的先决条件,所以需要重新建.dep文件而构建.dep文件后,.dep文件目录又不是最新了,所以make会再次构建.dep文件,这就造成了死循环。
make --> 生成.dep文件 --> .dep目录时间戳变化 --> 重新make --> 生成.dep文件 --> .dep目录时间戳变化 --> 重新make.......
解决这个问题的方法就是,让已经存在.dep目录的时候,其目录就不要成为生成.dep的先决条件了,也就是去掉这层依赖关系,这样就不会重新编译.dep文件。
.PHONY:clean all
CC=gcc
RM=rm
BIN_DIR=bin
OBJ_DIR=objs
MKDIR=mkdir
DIR_DEPS=deps
RM_OP=-rf
EXE=simple
EXE:=$(addprefix $(BIN_DIR)/, $(EXE))
SRC=$(wildcard *.c)
OBJS=$(patsubst %.c, %.o, $(SRC))
DIRS = $(BIN_DIR) $(OBJ_DIR) $(DIR_DEPS)
OBJS:=$(addprefix $(OBJ_DIR)/, $(OBJS))
DEPS = $(SRC:.c=.dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
bar ?= $(OBJS:.o=.c)
all : $(EXE)
ifeq ("$(wildcard $(DIR_DEPS))", "")
DEP_DIR_DEPS:=$(DIR_DEPS)
endif
-include $(DEPS)
$(DIRS):
$(MKDIR) $@
$(EXE):$(BIN_DIR) $(OBJS)
$(CC) -o $@ $(filter %.o, $^)
$(OBJ_DIR)/%.o: $(DEP_OBJ_DIR) %.c
$(CC) -o $@ -c $(filter %.c, $^)
#2
$(DIR_DEPS)/%.dep:$(DEP_DIR_DEPS) %.c
@echo "Making $@..."
@set -e;\
$(RM) $(RM_OP) $@;\
$(CC) -E -MM $(filter %.c, $^) > $@.tmp;\
sed 's,\(.*\)\.o[:]*,objs/\1.o $@:,g' < $@.tmp > $@;\
$(RM) $(RM_OP) $@.tmp
clean:
$(RM) $(RM_OP) $(DIRS)
可见在使用Makefile的依赖关系时,出现问题最好将依赖关系画图,理清依赖关系,以及注意make更新最新文件的特性,这样的问题还是能够避免的。
Makefile中的死循环问题--学习李云《驾驭Makefile》中的疑惑解决相关推荐
- Makefile新手?千万别错过了《驾驭Makefile》
网上搜索makefile教程,转载和推荐最多的就是陈皓<跟我一起写 Makefile>系列,无出其右. 这个系列很不错,适合初学Makefile,了解Makefile的各种规则.语法.依赖 ...
- 计算机控制在无人车中的应用,深度学习在无人驾驶环境感知中的应用方案
机器深度学习是近年来在人工智能领域的重大突破之一,它在语音识别.自然语言处理.计算机视觉等领域都取得了不少成功.由于车辆行驶环境复杂,当前感知技术在检测与识别精度方面无法满足无人驾驶发展需要,深度学习 ...
- 学习李沐的课程中的问题记录
(50条消息) 李沐<动手学深度学习>d2l--安装和使用_梁小憨憨的博客-CSDN博客_d2l Python安装 d2l 库过程中出现" Failed building whe ...
- 蓝墨云班课与中职计算机课,蓝墨云环境下中职《计算机应用基础》的对分课堂教学研究...
摘要: 中职<计算机应用基础>课程着重让学生了解计算机基础知识,掌握计算机基本操作能力,以及培养学生综合能力,并引导学生学以致用.同时培养学生能够利用计算机开展自主学习的能力,为终身学习奠 ...
- python中的颜色_Python学习第234课——html中的颜色值
在网页中,经常需要给一些html元素设置颜色,比如给某个html元素设置边框的颜色.字体的颜色.背景颜色等等. 给html元素设置颜色,就是在css中写上你想要设定的具体的颜色值. 比如说,你想给一个 ...
- Blender中的主程序纹理学习课程 Master Procedural Texturing in Blender
挖掘Blender不可思议的强大节点编辑器的无限潜力. 你会学到: 逐步构建高级和高度可定制的程序纹理. 将许多不同层次的细节结合成一个复杂而现实的结果. 从头开始构建高级程序纹理背后的思维过程. 使 ...
- UE5虚幻引擎5中的实时特效学习 Introduction to real time FX in Unreal Engine 5
MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言:英语+中英文字幕(根据原英文字幕机译更准确) |时长:40节课(3h 36m) |大小解压后:2.65 G ...
- 中职生学云计算机技术应用,云课堂在中职计算机课程教学中的应用
赵德元 [摘要]云课堂是基于云计算技术的一种高效.便捷.实时互动的远程教学课堂形式.现如今,云课堂已开始在中职校园中得到实践和运用.文章分析了中职计算机课程教学现状,阐明了云课堂教学的优势,并对云课堂 ...
- CVPR2020:点云分析中三维图形卷积网络中可变形核的学习
CVPR2020:点云分析中三维图形卷积网络中可变形核的学习 Convolution in the Cloud: Learning Deformable Kernels in 3D Graph Con ...
最新文章
- Go 学习笔记(65)— Go 中函数参数是传值还是传引用
- 【我的Android进阶之旅】解决SDK升级到27.0.3遇到的GLIBC_2.14 not found、no acceptable C compiler found in $PATH等问题...
- TextView文本折叠Three
- 2015年第六届蓝桥杯 - 省赛 - C/C++大学B组 - C. 三羊献端
- springboot中获取bean_最新Spring Boot干货总结(超详细,建议收藏)
- 机器学习总结(17)-XGBoost
- 什么是压栈操作?指令:PUSH src ;src为16位操作数
- 怎样为企业挑选正确的EDR解决方案
- PHP中使用PDO操作MySQL
- 量化指标公式源码_最牛通达信量化副图指标公式源码
- Python2.7安装Numpy
- SQL server 还原数据库遇到正在使用的解决方法:
- ZUI datagrid 数据表格重新渲染问题
- Google文档初学者指南
- 从不重视体检的我拿到了体检报告,我慌了…
- 海南省软考报名时间成绩查询海南省教育考试院海南省人事考试网报名入口
- JVM知识点精华汇总 侵立删
- 小满Router(第一章入门)
- 【企业】如何将零和博弈转换为正和博弈
- 关于字符串中加入变量的方式
热门文章
- boll指标(布林带)计算公式
- 百度SEO发包快排解密
- ESP8266 RTOSSDK3.0 的工程同步到3.4
- 功能测试与抓包工具Fiddler(http与fiddler)
- 前端基础(二)----- CSS初识
- 天池学习赛 -【零基础入门语音识别-食物声音识别】Task1 食物声音识别-Baseline【代码详细手写解释】
- 进步与成就感——使用技巧
- 简述计算机数控系统的工作原理,计算机数控系统复习题-20210321010307.docx-原创力文档...
- python的故事--我抄的,但抄的可以,是一个叫栋哥的电台讲的
- 解决maven打包的时候依赖jar包打不进去