#!/bin/bash
###############################################################################
#Variables
#查找project目录,以及子目录的所有文档!其中以"GCC/Makefile"结尾的!
export PROJECT_LIST=$(find project | grep
"GCC/Makefile$")
#project下边所有的目录
export BOARD_LIST=
"project/*"
export OUT=
"$PWD/out"
export FLASHGENERATOR=
"tools/flashgen/flashgen.pl"
feature_mk=
""
platform=$
(uname)
# uname 得到 "Linux"
if [[
"$platform" =~
"MINGW" ]]; then
# =~表示包含子串
export EXTRA_VAR=-
j
else
export EXTRA_VAR=-j`cat /proc/cpuinfo |grep ^processor|wc -
l`
fi
###############################################################################
#Functions
show_usage () {
echo "==============================================================="
echo "Build Project"
echo "==============================================================="
echo "Usage: $0 <board> <project> [bl|clean] <argument>"
echo ""
echo "Example:"
echo " $0 mt7687_hdk iot_sdk_demo"
echo " $0 mt7687_hdk iot_sdk_demo bl (build with bootloader)"
echo " $0 clean (clean folder: out)"
echo " $0 mt7687_hdk clean (clean folder: out/mt7687_hdk)"
echo " $0 mt7687_hdk iot_sdk_demo clean (clean folder: out/mt7687_hdk/iot_sdk_demo)"
echo ""
echo "Argument:"
echo " -f=<feature makefile> or --feature=<feature makefile>"
echo " Replace feature.mk with other makefile. For example, "
echo " the feature_example.mk is under project folder, -f=feature_example.mk"
echo " will replace feature.mk with feature_example.mk."
echo ""
echo " -o=<make option> or --option=<make option>"
echo " Assign additional make option. For example, "
echo " to compile module sequentially, use -o=-j1."
echo " to turn on specific feature in feature makefile, use -o=<feature_name>=y"
echo " to assign more than one options, use -o=<option_1> -o=<option_2>."
echo ""
echo "==============================================================="
echo "List Available Example Projects"
echo "==============================================================="
echo "Usage: $0 list"
echo ""
}
show_available_proj () {
echo "==============================================================="
echo "Available Build Projects:"
echo "==============================================================="
for b
in $BOARD_LIST
do
project_path=
""
project_name_list=
""
p=$(echo
$PROJECT_LIST | tr
" " "\n" | grep
"$b")
if [ ! -z
"$p" ]; then
echo " "`basename
$b`
fi
for q
in $p
do
if [ -e
"$q" ]; then
project_path=$(echo
$q | sed 's/GCC\/Makefile//
')
project_name_list=
"${project_name_list} $(basename $project_path)" #project_name_list一直在叠加
fi
done
for i
in `echo
$project_name_list | tr
" " "\n" |
sort`
do
echo " "" "$i
done
done
}
#当输入./build mt2523_hdk headset_ref_design时
use_new_out_folder=
"FALSE"
target_check () {
for p
in $PROJECT_LIST # $p是PROJECT_LIST中的一个
do
q=$(echo
$p | grep
"project/$1/")
if [ ! -z
"$q" ]; then
r=$(echo
$q | sed 's/GCC\/Makefile//
')
s=`basename
$r`
if [
"$s" ==
"$2" ]; then
echo "Build board:$1 project:$2"
if [
$use_new_out_folder ==
"FALSE" ]; then
OUT=
$OUT/
$1/
$2
fi
BUILD=project/
$1/
$2
export TARGET_PATH=$(dirname
$q)
return 0
fi
fi
done
return 1
}
# support MinGW
mingw_check () {
echo "platform=$platform"
if [[
"$platform" =~
"MINGW" ]]; then
pwdpath=$
(pwd)
echo $pwdpath
if [[
"$pwdpath" =~
"\[|\]| " ]]; then
# "\[|\]| "表示有[或]或空格
echo
"Build.sh Exception: The codebase folder name should not have spacing, [ or ]."
exit 1
fi
fi
}
clean_out () {
rm -rf
$1
echo "rm -rf $1"
}
###############################################################################
#Begin here
if [
"$#" -eq "0" ]; then
show_usage
exit 1
fi
# parsing arguments
declare -a argv=(
$0)
ori_argv=$@
do_make_clean=
"FALSE"
for i
in $@
do
case $i in
-o=*|--option=*
)
opt=
" ${i#*=}" # 变量的删除替换!删除从开始到等号之间的东西
echo
"$opt" | grep -q -E
" OUT="
if [[ $?
-eq 0 ]]; then
# 上一步匹配到了,返回0
# grep -o只显示匹配到的部分:OUT=后边,以空格或Tab开头的东东
# cut -d 分隔符为=
# tr -d 删掉
OUT=`echo
$opt | grep -o
"OUT=[^ |^ ]*" | cut -d '=' -f2 | tr -
d ' '`
if [ -z
"$OUT" ]; then
echo "Error: -o=OUT= cannot be empty!"
show_usage
exit 1
fi
OUT=
$PWD/
$OUT # 更新设置了out目录
use_new_out_folder=
"TRUE"
echo "output folder change to: $OUT"
fi
extra_opt+=
$opt #字符串变量的追加,也可以写成 extra_opt=${extra_opt}$opt
do_make_clean=
"TRUE"
shift
;;
-blo=*|--bloption=*
)
opt=
" ${i#*=}"
echo "$opt" | grep -q -E
" OUT="
if [[ $?
-eq 0
]]; then
echo "Error: Unsupported -o=OUT= in [-blo|-bloption]."
exit 1
fi
bl_extra_opt+=
$opt
do_make_clean=
"TRUE"
shift
;;
-f=*|--feature=*
)
feature_mk=
"${i#*=}"
shift
;;
list)
show_available_proj
exit 0
;;
-*
)
echo "Error: unknown parameter \"$i\
""
show_usage
exit 1
;;
*
)
argv+=(
$i)
;;
esac
done
export PROJ_NAME=${argv[2
]}
###############################################################################
# 附带编译Bootloader时执行: ./build mt2523_hdk headset_ref_design bl
if [
"${argv[3]}" ==
"bl" ]; then
if [
"${#argv[@]}" !=
"4" ]; then
show_usage
exit 1
fi
target_check ${argv[1]} ${argv[2
]}
if [
"$?" -ne "0" ]; then
echo "Error: ${argv[1]} ${argv[2]} is not available board & project"
show_usage
exit 1
fi
if [
$do_make_clean ==
"TRUE" ]; then
clean_out $OUT
fi
mingw_check
where_to_find_feature_mk=
$TARGET_PATH
if [ ! -z
$feature_mk ]; then
if [ ! -e
"$TARGET_PATH/$feature_mk" ]; then
echo "Error: cannot find $feature_mk under $TARGET_PATH."
exit 1
fi
EXTRA_VAR+=
" FEATURE=$feature_mk"
else
# 举例 $TARGET_PATH=project/mt2523_hdk/apps/headset_ref_design/GCC
# 在Makefile中搜索TARGET_PATH开头 \ *表示多个空格,也是防止表达式断了 [?:]表示?或: \{0,1\}表示0个或1个
# tail只查看1行
where_to_find_feature_mk=`grep
"^TARGET_PATH\ *[?:]\{0,1\}=\ *" $TARGET_PATH/Makefile | cut -d '=' -f2 | tr -d ' ' | tail -1
`
if [ -z
$where_to_find_feature_mk ]; then
where_to_find_feature_mk=
$TARGET_PATH
fi
feature_mk=`grep
"^FEATURE\ *[?:]\{0,1\}=\ *" $TARGET_PATH/Makefile | cut -d '=' -f2 | tr -d ' ' | tail -1
`
echo "FEATURE=$feature_mk"
fi
if [ -e
"$OUT/obj/$TARGET_PATH/tmp.mk" ]; then
# -q仅显示有无差异,不显示结果
diff -q
$where_to_find_feature_mk/
$feature_mk $OUT/obj/
$TARGET_PATH/
tmp.mk
if [ $?
-ne 0
]; then
clean_out $OUT
fi
fi
mkdir -p
$OUT/obj/
$TARGET_PATH
cp $where_to_find_feature_mk/
$feature_mk $OUT/obj/
$TARGET_PATH/
tmp.mk
CM4_TARGET_PATH_BAK=
$TARGET_PATH
TARGET_PATH=
"project/${argv[1]}/apps/bootloader/GCC"
# 创建log目录
mkdir -p
$OUT/
log
echo "$0 $ori_argv" >
$OUT/log/
build_time.log
echo "Start Build: "`date` >>
$OUT/log/
build_time.log
echo "Build bootloader..."
# Check if the source dir is existed
if [ ! -d
"project/${argv[1]}/apps/bootloader" ]; then
echo "Error: no bootloader source in project/${argv[1]}/apps/bootloader"
exit 1
fi
# 开始编译bootloader
mkdir -p
$OUT
make -C
$TARGET_PATH BUILD_DIR=
$OUT/obj/bootloader OUTPATH=
$OUT BL_MAIN_PROJECT=${argv[2]}
$extra_opt $bl_extra_opt 2>>
$OUT/
err.log
BUILD_RESULT=$?
mkdir -p
$OUT/
lib
mv -f $OUT/*.a
$OUT/lib/ 2> /dev/
null
mkdir -p
$OUT/
log
mv -f $OUT/*.log
$OUT/log/ 2> /dev/
null
if [
$BUILD_RESULT -ne 0
]; then
echo "Error: bootloader build failed!!"
echo "BOOTLOADER BUILD : FAIL" >>
$OUT/log/
build_time.log
exit 2
;
else
echo "BOOTLOADER BUILD : PASS" >>
$OUT/log/
build_time.log
fi
echo "Build bootloader...Done"
# build cm4 firmware 编译M4固件
echo
"Build CM4 Firmware..."
TARGET_PATH=
$CM4_TARGET_PATH_BAK
mkdir -p
$OUT/
autogen
EXTRA_VAR+=
"$extra_opt"
#echo "make -C $TARGET_PATH BUILD_DIR=$OUT/obj OUTPATH=$OUT $EXTRA_VAR"
make -C
$TARGET_PATH BUILD_DIR=
$OUT/obj OUTPATH=
$OUT $EXTRA_VAR 2>>
$OUT/
err.log
BUILD_RESULT=$?
mkdir -p
$OUT/
lib
mv -f $OUT/*.a
$OUT/lib/ 2> /dev/
null
mkdir -p
$OUT/
log
mv -f $OUT/*.log
$OUT/log/ 2> /dev/
null
echo "Build CM4 Firmware...Done"
echo "End Build: "`date` >>
$OUT/log/
build_time.log
cat $OUT/log/build.log | grep
"MODULE BUILD" >>
$OUT/log/
build_time.log
if [
"$BUILD_RESULT" -eq "0" ]; then
echo "TOTAL BUILD: PASS" >>
$OUT/log/
build_time.log
else
echo "TOTAL BUILD: FAIL" >>
$OUT/log/
build_time.log
fi
echo "=============================================================="
cat $OUT/log/
build_time.log
exit $BUILD_RESULT
elif [ "${argv[3]}" ==
"clean" ]; then
if [
"${#argv[@]}" !=
"4" ]; then
show_usage
exit 1
fi
if [
"$use_new_out_folder" ==
"TRUE" ]; then
rm -rf
$OUT
else
rm -rf
$OUT/${argv[1]}/${argv[2
]}
fi
elif [ "${argv[2]}" ==
"clean" ]; then
if [
"${#argv[@]}" !=
"3" ]; then
show_usage
exit 1
fi
if [
"$use_new_out_folder" ==
"TRUE" ]; then
rm -rf
$OUT
else
rm -rf
$OUT/${argv[1
]}
fi
elif [ "${argv[1]}" ==
"clean" ]; then
if [
"${#argv[@]}" !=
"2" ]; then
show_usage
exit 1
fi
rm -rf
$OUT
else
# 最后这里是只编译M4内核的部分
if [
"${#argv[@]}" !=
"3" ]; then
show_usage
exit 1
fi
target_check ${argv[1]} ${argv[2
]}
if [
"$?" -ne "0" ]; then
echo "Error: ${argv[1]} ${argv[2]} is not available board & project or module"
show_usage
exit 1
fi
if [
$do_make_clean ==
"TRUE" ]; then
clean_out $OUT
fi
mingw_check
where_to_find_feature_mk=
$TARGET_PATH
if [ ! -z
$feature_mk ]; then
if [ ! -e
"$TARGET_PATH/$feature_mk" ]; then
echo "Error: cannot find $feature_mk under $TARGET_PATH."
exit 1
fi
EXTRA_VAR+=
" FEATURE=$feature_mk"
else
where_to_find_feature_mk=`grep
"^TARGET_PATH\ *[?:]\{0,1\}=\ *" $TARGET_PATH/Makefile | cut -d '=' -f2 | tr -d ' ' | tail -1
`
if [ -z
$where_to_find_feature_mk ]; then
where_to_find_feature_mk=
$TARGET_PATH
fi
feature_mk=`grep
"^FEATURE\ *[?:]\{0,1\}=\ *" $TARGET_PATH/Makefile | cut -d '=' -f2 | tr -d ' ' | tail -1
`
echo "FEATURE=$feature_mk"
fi
if [ -e
"$OUT/obj/$TARGET_PATH/tmp.mk" ]; then
diff -q
$where_to_find_feature_mk/
$feature_mk $OUT/obj/
$TARGET_PATH/
tmp.mk
if [ $?
-ne 0
]; then
clean_out $OUT
fi
fi
mkdir -p
$OUT/obj/
$TARGET_PATH
cp $where_to_find_feature_mk/
$feature_mk $OUT/obj/
$TARGET_PATH/
tmp.mk
mkdir -p
$OUT/
autogen
mkdir -p
$OUT/
log
echo "$0 $ori_argv" >
$OUT/log/
build_time.log
echo "Start Build: "`date` >>
$OUT/log/
build_time.log
if [ ! -z
$feature_mk ]; then
EXTRA_VAR+=
" FEATURE=$feature_mk"
fi
EXTRA_VAR+=
"$extra_opt"
#echo "make -C $TARGET_PATH BUILD_DIR=$OUT/obj OUTPATH=$OUT $EXTRA_VAR"
make -C
$TARGET_PATH BUILD_DIR=
$OUT/obj OUTPATH=
$OUT $EXTRA_VAR 2>>
$OUT/
err.log
BUILD_RESULT=$?
mkdir -p
$OUT/
lib
mv -f $OUT/*.a
$OUT/lib/ 2> /dev/
null
mv -f $OUT/*.log
$OUT/log/ 2> /dev/
null
echo "End Build: "`date` >>
$OUT/log/
build_time.log
cat $OUT/log/build.log | grep
"MODULE BUILD" >>
$OUT/log/
build_time.log
if [
"$BUILD_RESULT" -eq "0" ]; then
echo "TOTAL BUILD: PASS" >>
$OUT/log/
build_time.log
else
echo "TOTAL BUILD: FAIL" >>
$OUT/log/
build_time.log
fi
echo "=============================================================="
cat $OUT/log/
build_time.log
exit $BUILD_RESULT
fi
分析过程中,单独摘出来试验某个语句的意思,尤其是正则表达式复杂的时候,做试验更直观一些。
还有shell的调试方法,-x -n -v,要把整个脚本截短一点再调试,不然太庞大了。
纵观下来,最有意思的部分是,获得各个文件文件夹、搜索和截取路径、basename/dirname、处理输入变量。
最后肯定会调用make啦~~~
啊
转载于:https://www.cnblogs.com/WMCH/p/8615814.html