Makefile基础教程(自动生成依赖关系)

文章介绍了在makefile中不包含.h文件依赖的后果,以及如何使用gcc-M和gcc-MM命令自动列出源文件的头文件依赖。同时,文章讲解了sed命令在处理文本文件中的应用。通过结合这些工具,文章展示了如何在makefile中生成并管理大量头文件的依赖,将依赖文件单独存放在deps文件夹中,提高了makefile的可维护性和移植性。
摘要由CSDN通过智能技术生成


前言

在前面的文章中我们都只使用到了.c文件作为依赖但是在实际的工程中肯定是不可能只有.c文件的还存在.h文件,那么在包含了.h文件后又该如何来包含依赖关系呢?

一、makefile不包含.h依赖的后果

首先先在目录下新建四个文件夹,其中就包含了fun.h这个文件。
在这里插入图片描述
makefile:

OBJS := fun.o main.o 

hello : $(OBJS)
	gcc -o $@ $^

$(OBJS): %.o : %.c
	gcc -o $@ -c $^

运行结果:
通过运行结果可以发现不包含.h文件的依赖,将没有办法找到头文件。
在这里插入图片描述
那么这样就需要将头文件包含进来:
将头文件的依赖包含进来后就能够成功编译。

OBJS := fun.o main.o 

hello : $(OBJS)
	gcc -o $@ $^

$(OBJS) : %.o : %.c fun.h
	gcc -o $@ -c $<

那么这也带来了一个问题,这里是只有一个.h头文件,在实际项目中肯定会有成千上万的头文件,当有很多头文件时也是需要一个个来进行添加吗?这样添加肯定会导致makefile的移植性降低,而且不容易维护。
那么如何自动的生成依赖关系呢?下面先做一些预备知识,我们这篇文章将会完成自动生成依赖关系。

二、gcc -M 和 gcc -MM命令

gcc -M命令会根据输入的源代码文件,输出这个源文件及所包含的头文件清单。例如,下面的命令会输出main.c文件及其相关的头文件清单:

在这里插入图片描述

gcc -MM命令与gcc -M命令类似,但会自动忽略掉标准库的头文件。例如,下面的命令会输出main.c文件及其相关的头文件清单(忽略标准库的头文件):
在这里插入图片描述

三、sed命令

sed是一种流文本编辑器,常用于在Linux系统中进行文本处理。sed可以对文本文件进行修改、替换、删除、添加等操作。使用sed命令可以方便地批量处理大量的文本文件。

sed命令的基本用法如下:

sed options ‘commands’ file

其中,options是sed的选项,'commands’是需要执行的命令(可以是多个命令),file是需要处理的文件名。如果没有指定文件名,sed命令会从stdin中读取文本。

常用的sed命令如下:

替换文本
sed ‘s/原文本/新文本/’ file

这个命令将会把file文件中的所有"原文本"替换成"新文本",并输出修改后的文本。如果需要替换所有的原文本,可以在s命令后加上"g"选项,如下所示:

sed ‘s/原文本/新文本/g’ file

删除行
sed ‘行号d’ file

这个命令将会删除file文件中指定行号的内容,并将剩余内容输出。

插入文本
sed ‘行号i\插入文本’ file

这个命令将会在file文件的指定行号前插入一行文本,并输出修改后的文本。

列出行号
sed ‘=’ file

这个命令将会在file文件的每一行前输出行号。

执行脚本
sed -f script.sed file

这个命令将会执行脚本文件script.sed中的命令,对file文件进行处理。

上述仅是sed命令的一部分,sed具有其他更多的选项和用法。在实际应用中,我们可以根据需要灵活运用sed命令,对文本数据进行快速、方便的处理。

下面来使用一下sed命令的修改功能:
在这里插入图片描述

四、makefile中命令的执行机制

在makefile中规则中的每个命令默认是在一个新的进程中执行(shell)

可以通过接续符(;)将多个命令组合成一个命令

组合的命令依次在同一个进程中被执行
下面编写一个makefile验证:


all : 
	mkdir test
	cd test
	mkdir test1

执行结果:
在这里插入图片描述
通过执行结果可以发现test1并不是在test里面创建的,但是我们这样写makefile的本意就是让他在test里面创建一个test1子文件夹,这样的运行结果是为什么呢?这是因为在makefile中规则中的每个命令默认是在一个新的进程中执行(shell)。

要想让这些命令在同一个进程下执行的话可以使用set -e命令。
修改后的makefile:


all : 
	set -e;\
	mkdir test;\
	cd test;\
	mkdir test1

运行结果:
在这里插入图片描述

四、生成依赖文件并单独放入文件夹中

编写下面的makefile为每一个文件都生成对应的依赖,并存放在deps文件夹中。

.PHYON : all clean

CC := gcc
MKDIR := mkdir
RM := rm -rf

DIR_DEPS := deps

SRCS := $(wildcard *.c)
DEPS := $(SRCS:.c=.dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))

include $(DEPS)

all : 
	@echo all

$(DIR_DEPS) :
	$(MKDIR) $@

$(DIR_DEPS)/%.dep : $(DIR_DEPS) %.c
	@echo "Creating $@ ..."
	@set -e;\
	$(CC) -MM -E $(filter %.c, $^) | sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g' > $@


clean :
	$(RM) $(DIR_DEPS)

运行结果:
在这里插入图片描述
在这里插入图片描述

总结

本篇文章讲述了如何自动生成依赖关系这对我们后面项目的构建是非常重要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花落已飘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值