#make tiny4412_config
一切从顶层目录中的makefile 中开始寻找答案:
%_config:: unconfig
@$(MKCONFIG) -A $(@:_config=)
其中%是通配符代表所有可能的字符
当make 之后先执行unconfig:
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep
obj := $(OBJTREE)/
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
其中BUILD_DIR是通过o=来指定的一个目录
其中CURDIR是内部变量
插讲:$(if CONDITION,THEN-PART[,ELSE-PART])
¾ 函数功能:第一个参数“CONDITION” ,在函数执行时忽略其前导和结尾空字符,如果包含对其他变量或者函数的引用则进行展开。如果“CONDITION”的展开结果非空,则条件为真,就将第二个参数“THEN_PATR”作为函数的计算表达式;“CONDITION”的展开结果为空,将第三个参数“ELSE-PART”作为函数的表达式,函数的返回结果为有效表达式的计算结果。
¾ 返回值:根据条件决定函数的返回值是第一个或者第二个参数表达式的计算结果。当不存在第三个参数“ELSE-PART” ,并且“CONDITION”展开为空,函数返回空。
¾ 函数说明:函数的条件表达式“CONDITION”决定了函数的返回值只能是“THEN-PART”或者“ELSE-PART”两个之一的计算结果。
¾ 函数示例:
SUBDIR += $(if $(SRC_DIR) $(SRC_DIR),/home/src)
函数的结果是:如果“SRC_DIR”变量值不为空,则将变量“SRC_DIR”指定
的目录作为一个子目录;否则将目录“/home/src”作为一个子目录。
回到正题,对于unconfig命令就是一种将删除上一个make XXX_config产生的文件。主要是一些产生autoconfig.h(用于.h文件中),auto.config(用于makefile中)
对于@$(MKCONFIG) -A $(@:_config=)这个命令:
1,我们先讲$(@:_config=)这句话主要是对tiny4412_config进行处理。刚才那个命令的意思是将字符中的_config替换成等号右边的字符,没有就是为空,所以处理之后为tiny4412。
2,@$(MKCONFIG)
MKCONFIG := $(SRCTREE)/mkconfig
SRCTREE := $(CURDIR)
也就是顶层目录中的mkconfig。通过它去进一步解析这个命令。所以上面命令变成mkconfig -A tiny4412其中-A表示要自动配置。
好,继续贴代码来分析
if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
# Automatic mode
line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
echo "make: *** No rule to make target \`$2_config'. Stop." >&2
exit 1
}
set ${line}
# add default board name if needed
[ $# = 3 ] && set ${line} ${1}
fi
上面的代码就去boards.cfg里面去找tiny4412,找到了就把赋于line
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%_config}" ; shift ;;
-t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
*) break ;;
esac
done
$#为shell中的一个特殊变量,代表传入参数的个数,-gt是大于的意思,该行的意思是“当传入参数个数大于0时”进入循环
case "$1" in接着下面的几行意思表示,判断第一个参数中是否有-- -a -n参数,我们传入的参数都没有这些,所以他们根本没机会执行到
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
有或的意思,如果||前的[]中不为NULL,那么||后面的就屏蔽了,很不幸,这里||前面部分却为NULL,所以BOARD_NAME=tiny4412(第一个参数的值)
继续贴代码:
[ $# -lt 4 ] && exit 1
[ $# -gt 7 ] && exit 1
参数个数正确性判断不能小于4个,也不能大于7个。
# Strip all options and/or _config suffixes
CONFIG_NAME="${1%_config}"
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
arch="$2"
cpu="$3"
if [ "$4" = "-" ] ; then
board=${BOARD_NAME}
else
board="$4"
fi
board = tiny4412
根据相应的点对各个基本的板子参数进行赋值。知道了 target:tiny4412, arch: arm , cpu: armv7, board name: tiny4412, vendor:samsung, soc:exynos
[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
[ $# -gt 6 ] && [ "$7" != "-" ] && {
# check if we have a board config name in the options field
# the options field mave have a board config name and a list
# of options, both separated by a colon (':'); the options are
# separated by commas (',').
#
# Check for board name
tmp="${7%:*}"
if [ "$tmp" ] ; then
CONFIG_NAME="$tmp"
fi
# Check if we only have a colon...
if [ "${tmp}" != "$7" ] ; then
options=${7#*:}
TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"
fi
}
if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
exit 1
fi
if [ "$options" ] ; then
echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
echo "Configuring for ${BOARD_NAME} board..."
fi
主要是对板子的基本信息进行处理。target:tiny4412, arch: arm , cpu: armv7, board name: tiny4412, vendor:samsung, soc:exynos
接下来判断"$SRCTREE" != "$OBJTREE"是否成立,显然不成立(参考顶层Makefile),所以略过没必要的行,如下:
if [ "$SRCTREE" != "$OBJTREE" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/arch/${arch}/include/asm asm
LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
cd ../include
rm -f asm
ln -s ${SRCTREE}/arch/${arch}/include/asm asm
else
cd ./include
rm -f asm
ln -s ../arch/${arch}/include/asm asm
fi
else分支中先进入inlcude目录,然后删除上一次编译时配置生成的asm文件,最后生成链接文件asm指向asm
rm -f asm/arch
删除arch/arm/include/asm/arch链接文件
if [ -z "${soc}" ] ; then
ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
ln -s ${LNPREFIX}arch-${soc} asm/arch
fi
如果soc参数字符串长度为0或者为NULL,那么条件成立,但是实际上条件不成立,soc=exynos,所以生成一个链接文件asm/arch--->arch-exynos
if[ "${arch}" = "arm" ] ; then
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc
fi
创建链接文件asm/proc--->proc-armv
#
# Create include file for Make
#
echo "ARCH = ${arch}" > config.mk
echo "CPU = ${cpu}" >> config.mk
echo "BOARD = ${board}" >> config.mk
[ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk
[ "${soc}" ] && echo "SOC = ${soc}" >> config.mk
在include目录中创建config.mk文件,内容如下:
ARCH = arm
CPU = armv7
BOARD= tiny4412
SOC = exynos
# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
BOARDDIR=${board}
else
BOARDDIR=${vendor}/${board}
fi
#
# Create board specific header file
#
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
for i in ${TARGETS} ; do
i="`echo ${i} | sed '/=/ {s/=/\t/;q } ; { s/$/\t1/ }'`"
echo "#define CONFIG_${i}" >>config.h ;
done
在include目录中创建头文件config.h,内容为:
/* Automatically generated - do not edit */
#include <configs/tiny4412.h>
cat << EOF >> config.h
#define CONFIG_BOARDDIR board/$BOARDDIR
#include <config_defaults.h>
#include <configs/${CONFIG_NAME}.h>
#include <asm/config.h>
EOF
BOARDDIR=${vendor}/${board}
所以BOARDDIR=samsung/tiny4412
插讲:
cat << EOF:
两个都是获取stdin,并在EOF处结束stdin,输出stdout。
但是<<-是什么意思呢?
先来看man中的说明:
If the redirection operator is <<-, then all leading tab characters are stripped from input lines and the line containing delimiter.
翻译过来的意思就是:如果重定向的操作符是<<-,那么分界符(EOF)所在行的开头部分的制表符(Tab)都将被去除。
这可以解决由于脚本中的自然缩进产生的制表符。
通俗一点的解释:
在我们使用cat <<EOF时,我们输入完成后,需要在一个新的一行输入EOF结束stdin的输入。EOF必须顶行写,前面不能用制表符或者空格。
比如,下面的语句就不会出错:
cat <<EOF
Hello,world!
EOF
如果结束分解符EOF前有制表符或者空格,则EOF不会被当做结束分界符,只会继续被当做stdin来输入。
而<<-就是为了解决这一问题:
cat <<-EOF
Hello,world!
EOF
上面的写法,虽然最后的EOF前面有多个制表符和空格,但仍然会被当做结束分界符,表示stdin的结束。
这就是<<和<<-的区别。exit 0
总结:
1. 打印 Configuring for fs2410 board...
2. 在include目录下创建3个链接文件 Create link to architecture specific headers
./include
asm--->asm
./include/asm
arch--->arch-exynos
proc--->proc-armv
3. 在include目录中创建config.mk文件 Create include file for Make
ARCH = arm
CPU = armv7
BOARD= tiny4412
SOC = exynos
4. 创建板级特殊头文件config.h Create board specific header file
/* Automatically generated - do not edit */
#include <configs/tiny4412.h>
#define CONFIG_BOARDDIR board/samsung/tiny4412
#include <config_defaults.h>
#include <configs/tiny4412.h>
#include <asm/config.h>