一、概述
u-boot的子目录Makefile是整个Makefile体系的重要组成部分,决定了对应子目录的编译过程。
二、分析
以cpu/arm920t/Makefile为例进行说明
(1)首先,调用顶层目录定义的编译规则config.mk
include $(TOPDIR)/config.mk
(2)然后,定义生成的所有目标,例如下边定义的代码的所有目标是 $(obj).depend $(START) $(LIB)
LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = cpu.o interrupts.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
START := $(addprefix $(obj),$(START)) all: $(obj).depend $(START) $(LIB)
SRCS变量是当前目录下所有要参与编译的".c"、".S"的集合。这个变量在生成依赖文件.depend时会用到。
另外,还注意倒OBJS、START、LIB前边都加了$(obj),这是为“生成目标的目录不是源码目录”情况作准备的。
(3)注意到总目标all后边的第一个子目标是.depend,这是生成编译目标的依赖文件.depend。在编译目标$(START) $(LIB)之前,必须将依赖关系指明,所以 .depend文件要放到其他目标的前边。.depend文件的生成代码在这里:
#################################################################### # defines $(obj).depend target
include $(SRCTREE)/rules.mk sinclude $(obj).depend ####################################################################
再将包含的$(SRCTREE)/rules.mk,内容展开
######################################################################### _depend: $(obj).depend $(obj).depend: $(src)Makefile $(TOPDIR)/config.mk $(SRCS)
@rm -f $@
@for f in $(SRCS); do \
g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \
$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$ $g $ $f >> $@ ; \
done #########################################################################
可以看到“$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$ $g $ $f >> $@ ;”就是将每个目标文件的依赖关系写入到.depend文件中。
(4)最后,看一下目标的生成过程。
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
对于$(LIB)目标,需要用AR命令来连接生成库文件,而对于$(OBJS)这样的目标文件,它们的编译规则则是在config.mk中定义的。
ifndef REMOTE_BUILD %.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $< else $(obj)%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
$(obj)%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
$(obj)%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
endif