prepare()
{
local absolute_path cmd dir count
# Parse output directory 'O=<dir>'
cmd=${OUTDIR%=*}
if [ "${cmd}" = 'O' ]; then
OUTDIR=${OUTDIR#*=}
OUTOPT=O=${OUTDIR}
else
case $BOARD in
#Help
--help|-help|help|--h|-h)
echo "HELP--"
help
exit 0
;;
# Parse from exit .config
''|elf*|trust|loader|uboot|map|sym)
count=`find -name .config | wc -l`
dir=`find -name .config`
echo "BOARD = " $BOARD
# Good, find only one .config
if [ $count -eq 1 ]; then
dir=${dir%/*}
OUTDIR=${dir#*/}
echo "dir = " $dir
echo OUTDIR= $OUTDIR
# Set OUTOPT if not current directory
if [ $OUTDIR != '.' ]; then
OUTOPT=O=${OUTDIR}
fi
echo "OUTOPT = " $OUTOPT
elif [ $count -eq 0 ]; then
echo
echo "Build failed, Can't find .config"
help
exit 1
else
echo
echo "Build failed, find $count '.config': "
echo "$dir"
echo "Please leave only one of them"
exit 1
fi
;;
*)
OUTDIR=.
;;
esac
fi
# Parse help and make defconfig
case $BOARD in
#Help
--help|-help|help|--h|-h)
help
exit 0
;;
#Subcmd
''|elf*|trust|loader|uboot|map|sym)
;;
*)
#Func address is valid ?
if [ -z $(echo ${FUNCADDR} | sed 's/[0-9,a-f,A-F]//g') ]; then
return
elif [ ! -f configs/${BOARD}_defconfig ]; then
echo
echo "Can't find: configs/${BOARD}_defconfig"
echo
echo "******** Rockchip Support List *************"
echo "${SUPPORT_LIST}"
echo "********************************************"
echo
exit 1
else
echo "make for ${BOARD}_defconfig by -j${JOB}"
make ${BOARD}_defconfig ${OUTOPT} #这里执行了xxx_defconfig
fi
;;
esac
# Initialize RKBIN and RKTOOLS
if [ -d ${RKBIN_TOOLS} ]; then
absolute_path=$(cd `dirname ${RKBIN_TOOLS}`; pwd)
RKBIN=${absolute_path}
RKTOOLS=${absolute_path}/tools
else
echo
echo "Can't find '../rkbin/' repository, please download it before pack image!"
echo "How to obtain? 3 ways:"
echo " 1. Login your Rockchip gerrit account: \"Projects\" -> \"List\" -> search \"rk/rkbin\" repository"
echo " 2. Github repository: https://github.com/rockchip-linux/rkbin"
echo " 3. Download full release SDK repository"
exit 1
fi
}
实际上prepare是进行了make xxx_defconfig
分析一下编译输出信息:
make for evb-px30_defconfig by -j24
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#
make xxx_defconfig 过程调用关联的构建文件都在scripts/下, 执行之后会生成一些文件,
先看看这个make xxx_defconfig的过程:
要查看一下uboot目录下的Makefile:
先从打印的信息去追溯:
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/con
等信息
显然, 需要先编译一些scripts/basic下面的文件
$(Q)$(MAKE) $(build)=scripts/basic
追溯到: Q = @
MAKE = make
build 在: Kbuild.include
(注意导入的地方:
# We need some generic definitions (do not try to remake the file).
scripts/Kbuild.include: ;
include scripts/Kbuild.include)
build := -f $(srctree)/scripts/Makefile.build obj
即: -f ./scripts/Makefile.build obj
所以,预编译执行的是:
make -f ./scripts/Makefile.build obj=scripts/basic
如果往下追溯,需要查看scripts 下的Makefile.build 内容,又是一个大工程,这个另起一个博文讨论
defconfig 过程在:
ifeq ($(mixed-targets),1)
# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.
PHONY += $(MAKECMDGOALS) __build_one_by_one
$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one
@:
__build_one_by_one:
$(Q)set -e; \
for i in $(MAKECMDGOALS); do \
$(MAKE) -f $(srctree)/Makefile $$i; \
done
else
ifeq ($(config-targets),1) #在这里执行了xxx_defconfig
# ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend
# in scripts/kconfig to make the *config target
KBUILD_DEFCONFIG := sandbox_defconfig
export KBUILD_DEFCONFIG KBUILD_KCONFIG
config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
%config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
@echo "PRINT TEST KBUILD_DEFCONFIG=" $KBUILD_DEFCONFIG
else
# ===========================================================================
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.
# Additional helpers built in scripts/
# Carefully list dependencies so we do not try to build scripts twice
# in parallel
PHONY += scripts
scripts: scripts_basic include/config/auto.conf
$(Q)$(MAKE) $(build)=$(@)
ifeq ($(dot-config),1)
# Read in config
-include include/config/auto.conf
# Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected.
-include include/config/auto.conf.cmd
# To avoid any implicit rule to kick in, define an empty command
$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
# 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
u-boot.cfg spl/u-boot.cfg tpl/u-boot.cfg: include/config.h FORCE
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf $(@)
-include include/autoconf.mk
-include include/autoconf.mk.dep
# We want to include arch/$(ARCH)/config.mk only when include/config/auto.conf
# is up-to-date. When we switch to a different board configuration, old CONFIG
# macros are still remaining in include/config/auto.conf. Without the following
# gimmick, wrong config.mk would be included leading nasty warnings/errors.
ifneq ($(wildcard $(KCONFIG_CONFIG)),)
ifneq ($(wildcard include/config/auto.conf),)
autoconf_is_old := $(shell find . -path ./$(KCONFIG_CONFIG) -newer \
include/config/auto.conf)
ifeq ($(autoconf_is_old),)
include config.mk
include arch/$(ARCH)/Makefile
endif
endif
endif
查看了依赖: scripts_basic outputmakefile FORCE
三者需要先调用得到,
1、scripts_basic 从前面打印先执行的 HOSTCC scripts/basic/fixdep 也印证了需要
make -f ./scripts/Makefile.build obj=scripts/basic
2、outputmakefile
outputmakefile:
ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif
KBUILD_SRC 未定义,不执行
3、FORCE
不管目标有没有更新,强制执行
再看一下依赖条件: ifeq ($(mixed-targets),1) 需要考察: config-targets 是否是1
然后追溯到 KBUILD_EXTMOD ,显然,这个宏没有定义,如下:
ifeq ($(KBUILD_EXTMOD),) #成立
ifneq ($(filter config %config,$(MAKECMDGOALS)),) #此时filter出 config 关键字 并且 和 空格 做比较, 成立
config-targets := 1
ifneq ($(words $(MAKECMDGOALS)),1) #参数不止一个字母? 不成立
mixed-targets := 1
endif
endif
endif
上面这段中,MAKECMDGOALS 默认是makefile make 目标,此时是evb-px30_defconfig
$(filter config %config,$(MAKECMDGOALS))
该ifneq 是成立的,因为$(filter config %config 出来的时候是evb-px30
显然config-targets 是1
那么执行的config如下: %config: 是执行入口,
ifeq ($(config-targets),1)
# ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend
# in scripts/kconfig to make the *config target
KBUILD_DEFCONFIG := sandbox_defconfig
export KBUILD_DEFCONFIG KBUILD_KCONFIG
config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
%config: scripts_basic outputmakefile FORCE #执行xxx_defconfig
$(Q)$(MAKE) $(build)=scripts/kconfig $@
else
可以看到执行的config的语句在:
$(Q)$(MAKE) $(build)=scripts/kconfig $@
根据变量值代入那么就是:
make -f ./scripts/Makefile.build obj=scripts/kconfig evb-px30_defconfig
对应的编译输出:
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/con