makefile 自动生成依赖关系-笔记

自动生成依赖关系

拿去直接用?建议仔细看看,因为有些隐含规则的使用可能导致在你的项目中无法正常运行

MODULE = livestream
TAR	= lib${MODULE}.a
#获取所有的.c .o .d列表
SUB_DIRS += ./udp
SUB_DIRS += ./http
SUB_DIRS += ./srt
SUB_DIRS += ./rtmp
SUB_DIRS += ./hls
VPATH= $(SUB_DIRS) .
CFLAGS += $(foreach dir,$(VPATH),-I$(dir))
CSRCS=$(foreach dir,$(VPATH),$(wildcard $(dir)/*.c))
# CSRCS 中所有的.c替换成.o
OBJS=$(CSRCS:.c=.o)
# OBJS 中所有的.o替换成.d
DEPS=$(OBJS:.o=.d)
# $(info CSRCS=$(CSRCS))
# $(info OBJS =$(OBJS))
# $(info DEPS =$(DEPS))
# $(info CFLAGS =$(CFLAGS))
############################### build ###############################
all: ${TAR}

$(TAR):$(OBJS)
	@printf "CC -o $@\n"
	@${AR} -r ${TAR} $(OBJS)
	@cp ${TAR} ../libs/

# 下面的可以不用,因为隐含规则里有.c生成.o的规则,替换makefile内置的CFLAGS变量可以控制这一隐含规则执行时的参数
# 同时因为我们用了-include $(DEPS),在.d文件展开时,也会包括一个.o:.c的过程
# 不定义下面的过程的话,编译过程会被打印出来,除非将$(CC)替换成一个不打印的
$(OBJS):%.o:%.c
    @$(CC) -o $@ -c $< $(CFLAGS)
    @printf "CC -o $@\n"

$(DEPS):%.d:%.c
	@$(CC) -MM $(CFLAGS) $< -MT $(patsubst %.c,%.o,$<) -MF $@

# 将所有的.d文件包含进来,
-include $(DEPS)

.PHONY:clean install
clean:
	$(RM) $(TAR) $(OBJS) $(DEPS)
install:
	@cp ${TAR} ../libs/

利用隐含规则,这个其实可以简化为

SUB_DIRS += ./udp
SUB_DIRS += ./http
SUB_DIRS += ./srt
SUB_DIRS += ./rtmp
SUB_DIRS += ./hls
VPATH= $(SUB_DIRS) .
# 简化版的省略了CFLAGS += $(foreach dir,$(VPATH),-I$(dir)),是利用了VPATH特性
CFLAGS +=
CSRCS=$(foreach dir,$(VPATH),$(wildcard $(dir)/*.c))
OBJS=$(CSRCS:.c=.o)
DEPS=$(OBJS:.o=.d)
############################### build ###############################
all: ${TAR}

$(TAR):$(OBJS)
    @${AR} -r ${TAR} $(OBJS)

$(DEPS):%.d:%.c
    @$(CC) -MM $(CFLAGS) $< -MT $(patsubst %.c,%.o,$<) -MF $@

-include $(DEPS)

.PHONY:clean install
clean:
	$(RM) $(TAR) $(OBJS) $(DEPS)
install:
	@cp ${TAR} ../libs/

其中利用的隐含规则为

  • %.o自动使用%.c通过 ( C C ) 和 (CC)和 (CC)(CFLAGS)生成
  • 自动搜索VPATH中的头文件和源文件

对下面的语句做详细解释

$(DEPS):%.d:%.c
    @$(CC) -MM $(CFLAGS) $< -MT $(patsubst %.c,%.o,$<) -MF $@
  • $(CC) -MM $(CFLAGS) $< : 利用gcc的-MM参数,将$<(.c文件)中用到的头文件打出来,包括头文件中包含的头文件,-MM不会输出标准库的头文件

  • -MT $(patsubst %.c,%.o,$<) : 因为默认生成的.d中,目标(.o)不带路径,但是我传进去的$<(.c文件)是带路径,我需要给他替换下,以避免同名源文件导致的目标重定义,生成的.d结果如下

http/http_proto.o: http/http_proto.c http/http_proto.h http/http_curl.h \
 http/http.h /home/zhangbin/2022/TVMAN/tvman/app/liveStream/livestream.h \
 /home/zhangbin/2022/TVMAN/tvman/common/include/myzlog.h \
 /home/zhangbin/2022/TVMAN/tvman/common/include/zlog.h \
 /home/zhangbin/2022/TVMAN/tvman/common/include/util.h \
 /home/zhangbin/2022/TVMAN/tvman/app/include/common_type.h \
 /home/zhangbin/2022/TVMAN/tvman/common/include/key_value.h
  • -MF $@: -MF就是指定输出的文件名,这里的$@是一个.d文件

"VPATH"特性:

makefile的内置变量,通过VPATH可以指定依赖文件的搜索路径,当规则的依赖文件在当前目录不存在时,make 会在此变量所指定的目录下去寻找这些依赖文件。通常我们都是用此变量来指定规则的依赖文件的搜索路径。其实“ VPATH”变量所指定的是 Makefile中所有文件的搜索路径,包括了规则的依赖文件和目标文件。

make 搜索目录的顺序是按照变量“ VPATH”定义中的目录顺序进行的(当前目录永远是第一搜索目录)

makefile的打印信息

可以用来打印makefile执行过程中的各个变量值

$(error $(XXX))

$(warning $(XXX))

$(info $(XXX))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值