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

本文介绍了在Makefile中处理包含头文件的依赖问题,通过gcc-M和gcc-MM命令获取头文件列表,以及使用sed命令自动化生成依赖文件。重点讲解了如何在Makefile中正确处理多文件和标准库头文件,并演示了如何编写makefile以实现依赖关系的自动生成和管理。
摘要由CSDN通过智能技术生成

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

精选 原创

花落已飘 2023-06-08 10:53:10 博主文章分类:Makefile

文章标签 sed 头文件 sed命令 文章分类 开源 阅读数356

@TOC


前言

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

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

首先先在目录下新建四个文件夹,其中就包含了fun.h这个文件。

Makefile基础教程(自动生成依赖关系)_头文件

makefile:

OBJS := fun.o main.o 

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

$(OBJS): %.o : %.c
	gcc -o $@ -c $^
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

运行结果:

通过运行结果可以发现不包含.h文件的依赖,将没有办法找到头文件。

Makefile基础教程(自动生成依赖关系)_sed命令_02

那么这样就需要将头文件包含进来: 将头文件的依赖包含进来后就能够成功编译。

OBJS := fun.o main.o 

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

$(OBJS) : %.o : %.c fun.h
	gcc -o $@ -c $<
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

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

二、gcc -M 和 gcc -MM命令

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

Makefile基础教程(自动生成依赖关系)_sed命令_03

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

Makefile基础教程(自动生成依赖关系)_sed命令_04

三、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基础教程(自动生成依赖关系)_sed命令_05

四、makefile中命令的执行机制

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

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

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

all : 
	mkdir test
	cd test
	mkdir test1
  • 1.
  • 2.
  • 3.
  • 4.

执行结果:

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

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

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

all : 
	set -e;\
	mkdir test;\
	cd test;\
	mkdir test1
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

运行结果:

Makefile基础教程(自动生成依赖关系)_sed命令_07

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

编写下面的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)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

运行结果:

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

Makefile基础教程(自动生成依赖关系)_sed命令_09

总结

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

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qq_20312079

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

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

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

打赏作者

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

抵扣说明:

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

余额充值