u-boot-2018.05之make编译过程目标依赖分析

匿名 (未验证) 提交于 2019-12-03 00:29:01


- 第一步:配置,执行make xxx_defconfig进行各项配置,生成.config文件 (u-boot-2018.05之make配置过程分析)
- 第二步:编译,执行make进行编译,生成可执行的二进制文件u-boot.*

顶层目标依赖

_allall$(ALL-y)的依赖

从顶层Makefile开始查找,首先找到的是_all伪目标:

# That's our default target when none is given on the command line PHONY := _all _all:

紧接着会对_all伪目标添加all伪目标的依赖:

PHONY += all ifeq ($(KBUILD_EXTMOD),) _all: all else _all: modules endif

all自身依赖于$(ALL-y)

all: $(ALL-y)

$(ALL-y)u-boot目标文件的依赖

$(ALL-y)定义了最终需要生成所有文件:

# Always append ALL so that arch config.mk's can add custom ones ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg binary_size_check  ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin ifeq ($(CONFIG_SPL_FSL_PBL),y) ALL-$(CONFIG_RAMBOOT_PBL) += u-boot-with-spl-pbl.bin else ifneq ($(CONFIG_SECURE_BOOT), y) # For Secure Boot The Image needs to be signed and Header must also # be included. So The image has to be built explicitly ALL-$(CONFIG_RAMBOOT_PBL) += u-boot.pbl endif endif ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img ALL-$(CONFIG_TPL) += tpl/u-boot-tpl.bin ALL-$(CONFIG_OF_SEPARATE) += u-boot.dtb ifeq ($(CONFIG_SPL_FRAMEWORK),y) ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb.img endif ALL-$(CONFIG_OF_HOSTFILE) += u-boot.dtb ifneq ($(CONFIG_SPL_TARGET),) ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%) endif ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf ALL-$(CONFIG_EFI_APP) += u-boot-app.efi ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi  ifneq ($(BUILD_ROM),) ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom endif  # enable combined SPL/u-boot/dtb rules for tegra ifeq ($(CONFIG_TEGRA)$(CONFIG_SPL),yy) ALL-y += u-boot-tegra.bin u-boot-nodtb-tegra.bin ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb-tegra.bin endif

以上的$(ALL-y)目标中看起来非常复杂,但除了第一行的通用目标外,其余目标都只在特殊条件下才生成,这里略去不提。只分析通用目标依赖:

ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg binary_size_check
i. 依赖u-boot.bin

依赖u-boot.bin

ifeq ($(CONFIG_OF_SEPARATE),y) u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE     $(call if_changed,cat)  u-boot.bin: u-boot-dtb.bin FORCE     $(call if_changed,copy) else u-boot.bin: u-boot-nodtb.bin FORCE     $(call if_changed,copy) endif


u-boot.bin --> u-boot-dtb.bin --> u-boot-nodtb.bin + dts/dt.dtb

u-boot.bin --> u-boot-nodtb.bin

进一步,对于u-boot-nodtb.bin,其规则是:

u-boot-nodtb.bin: u-boot FORCE     $(call if_changed,objcopy)     $(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))     $(BOARD_SIZE_CHECK)
ii. 依赖System.map

依赖System.map

System.map: u-boot         @$(call SYSTEM_MAP,$<) > $@
iii. 依赖u-boot.cfg

依赖u-boot.cfg

u-boot.cfg: include/config.h FORCE     $(call if_changed,cpp_cfg)

u-boot文件目标依赖

a). 依赖u-boot

依赖u-boot

u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE     $(call if_changed,u-boot__) ifeq ($(CONFIG_KALLSYMS),y)     $(call cmd,smap)     $(call cmd,u-boot__) common/system_map.o endif

其中$(u-boot-init)$(u-boot-main)分别被定义为:

u-boot-init := $(head-y) u-boot-main := $(libs-y)
i. 依赖$(head-y)

$(head-y)arch/arm/Makefile被定义为:

head-y := arch/arm/cpu/$(CPU)/start.o
ii. 依赖$(libs-y)

在顶层Makefile中搜索一下$(libs-y),其被定义为各层驱动目录下build-in.o的集合:

libs-y += lib/ ...此处...libs-y := $(sort $(libs-y)) u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples libs-y      := $(patsubst %/, %/built-in.o, $(libs-y))u-boot-main := $(libs-y)

b). 依赖u-boot.lds

依赖u-boot.lds

u-boot.lds: $(LDSCRIPT) prepare FORCE     $(call if_changed_dep,cpp_lds)

其中$(LDSCRIPT)的定义如下:

# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use # that (or fail if absent).  Otherwise, search for a linker script in a # standard location.  ifndef LDSCRIPT     #LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds.debug     ifdef CONFIG_SYS_LDSCRIPT         # need to strip off double quotes         LDSCRIPT := $(srctree)/$(CONFIG_SYS_LDSCRIPT:"%"=%)     endif endif  # If there is no specified link script, we look in a number of places for it ifndef LDSCRIPT     ifeq ($(wildcard $(LDSCRIPT)),)         LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds     endif     ifeq ($(wildcard $(LDSCRIPT)),)         LDSCRIPT := $(srctree)/$(CPUDIR)/u-boot.lds     endif     ifeq ($(wildcard $(LDSCRIPT)),)         LDSCRIPT := $(srctree)/arch/$(ARCH)/cpu/u-boot.lds     endif endif

如果没有定义LDSCRIPTCONFIG_SYS_LDSCRIPT,则默认使用u-boot自带的lds文件。包括board/$(BOARDIDR)$(CPUDIR)目录下定制的针对board或cpu的lds文件,如果没有定制的lds文件,则采用arch/$(ARCH)/cpu目录下默认的u-boot.lds

prepare系列目标依赖

prepare系列依赖的规则

实际上prepare是一系列prepare伪目标和动作的组合,完成编译前的准备工作:

# Things we need to do before we recursively start building the kernel # or the modules are listed in "prepare". # A multi level approach is used. prepareN is processed before prepareN-1. # archprepare is used in arch Makefiles and when processed asm symlink, # version.h and scripts_basic is processed / created.  # Listed in dependency order PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3  # prepare3 is used to check if we are building in a separate output directory, # and if so do: # 1) Check that make has not been executed in the kernel src $(srctree) prepare3: include/config/uboot.release ifneq ($(KBUILD_SRC),)     @$(kecho) '  Using $(srctree) as source for U-Boot'     $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \         echo >&2 "  $(srctree) is not clean, please run 'make mrproper'"; \         echo >&2 "  in the '$(srctree)' directory.";\         /bin/false; \     fi; endif  # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile  prepare1: prepare2 $(version_h) $(timestamp_h) \                    include/config/auto.conf ifeq ($(wildcard $(LDSCRIPT)),)     @echo >&2 "  Could not find linker script."     @/bin/false endif  archprepare: prepare1 scripts_basic  prepare0: archprepare FORCE     $(Q)$(MAKE) $(build)=.  # All the preparing.. prepare: prepare0

伪目标prepareprepare0archprepareprepare1prepare2prepare3

prepare系列其他的依赖规则

prepare1的依赖列表中,除了include/config/auto.conf外,还有$(version_h)$(timestamp_h),他们的依赖分别为:

$(version_h): include/config/uboot.release FORCE     $(call filechk,version.h)  $(timestamp_h): $(srctree)/Makefile FORCE     $(call filechk,timestamp.h)

这里的两个filechk函数调用会动态生成version.htimestamp.h

对于最里层的prepare3的依赖include/config/uboot.release,还存在下一级依赖:

# Store (new) UBOOTRELEASE string in include/config/uboot.release include/config/uboot.release: include/config/auto.conf FORCE     $(call filechk,uboot.release)

对于include/config/auto.conf,Makefile中有一个匹配的规则:

# If .config is newer than include/config/auto.conf, someone tinkered # with it and forgot to run make oldconfig. # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd     $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig     @# If the following part fails, include/config/auto.conf should be     @# deleted so "make silentoldconfig" will be re-run on the next build.     $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \         { rm -f include/config/auto.conf; false; }     @# include/config.h has been updated after "make silentoldconfig".     @# We need to touch include/config/auto.conf so it gets newer     @# than include/config.h.     @# Otherwise, 'make silentoldconfig' would be invoked twice.     $(Q)touch include/config/auto.conf

所以include/config/auto.conf依赖于$(KCONFIG_CONFIG)include/config/auto.conf.cmd
$(KCONFIG_CONFIG)实际上就是.config
include/config/auto.conf.cmd是由fixdep在编译时生成的依赖文件。




标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!