如何编写一个Makefile文件 - 2

接着上一篇

https://blog.csdn.net/hubert937/article/details/118839665

 

顶级目录Makefile.build
PHONY := __build
__build:


obj-y :=
subdir-y :=

include Makefile

# obj-y := a.o b.o c/ d/
# $(filter %/, $(obj-y))   : c/ d/
# __subdir-y  : c d
# subdir-y    : c d
__subdir-y	:= $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y	+= $(__subdir-y)

# c/built-in.o d/built-in.o
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)

# a.o b.o
cur_objs := $(filter-out %/, $(obj-y))
dep_files := $(foreach f,$(cur_objs),.$(f).d)
dep_files := $(wildcard $(dep_files))

ifneq ($(dep_files),)
  include $(dep_files)
endif


PHONY += $(subdir-y)


__build : $(subdir-y) built-in.o

$(subdir-y):
	make -C $@ -f $(TOPDIR)/Makefile.build

built-in.o : $(cur_objs) $(subdir_objs)
	$(LD) -r -o $@ $^

dep_file = .$@.d

%.o : %.c
	$(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<
	
.PHONY : $(PHONY)

PHONY := __build
__build:

上面的语法定义一个伪目标

obj-y :=  #目标文件变量
subdir-y := #字母文件变量

上面两个语句定义了两个变量,但赋空值,这是因为下面的语句 

include Makefile 

包括当前目录下的Makefile,而当前目录下的Makefile是有各级子目录定义的,子目录的Makefile的内容就是该目录中需要编译的文件和子目录,#表示注释

__subdir-y    := $(patsubst %/,%,$(filter %/, $(obj-y)))

filter函数:在$(obj-y)中提取格式为%/的内容,%是一个通配符;patsubst函数:filter提取出来的内容,按照指定格式子替换,此处是把%/格式的内容,替换为%,即去掉了/

 ifneq ($(dep_files),)
  include $(dep_files)
endif

如果没有include 变量的内容,就include一下。

PHONY += $(subdir-y)

以上语句将子目录定义为伪目标,伪目标一不生成真正的目标文件,二他只是用来执行其规则下面的命令而已。伪目标可以称之为标签。

__build : $(subdir-y) built-in.o

 依赖关系伪目标__build,依赖文件为$(subdir-y) built-in.o,根据Makefile语法,检查依赖文件是否最新或者是否存在,如果存在,则跳过下一个语句。如果不存在,则在文件中找到生成该文件的规则来中执行。那么此时可以执行以下规则:

$(subdir-y):
    make -C $@ -f $(TOPDIR)/Makefile.build

这段意思为用根目录下的Makefile.build来对目标文件指定的目录进行执行make命令, 自身调用自身形成递归调用,直到该目录下没有子目录。然后执行下面的语句:

built-in.o : $(cur_objs) $(subdir_objs)
    $(LD) -r -o $@ $^

上面这条规则是,如果子目录不存在,即$(subidir_objs)为空,则把当前文件夹下的依赖文件用LD链接命令,链接为一个built-in.o文件,如果存在子目录,则把子目录的built-in.o文件和当前文件夹下的依赖文件一块链接成built-in.o文件。

 dep_file = .$@.d

 %.o : %.c
    $(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<

 上面的规则对应的是,首先依赖文件%.o文件,而%.o文件不存在时,则用这条规则下的命令生成由对应的%.c文件生成%.o文件以及依赖文件。这条命令生成的有,.%.o.d和%.o文件,%是通配符。

最后,Makefile.build重点理解它的递归性质,顶级目录下Makefile调用一个Makefile.buld ,然后这个Makefile.build调用形成递归,先进入最底层目录把整个文件夹编译链接为build-in.o,然后再和上一级目录的所有.o文件链接形成build-in.o直到顶级目录形成目标文件。

子目录的Makefile明天说吧...挺简单的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值