| # SPDX-License-Identifier: GPL-2.0 |
| # |
| #!/bin/bash |
| |
| function usage () |
| { |
| echo $0 'Check for kernel defconfig mismacth' |
| echo 'Usage:' |
| echo ' '$0' [-c] [-u] [defconfig-files]' |
| echo ' -c Check changed defconfigs from last git commit' |
| echo ' -u Update defconfig if no mismatch is found' |
| echo ' -h This help' |
| exit 0 |
| } |
| |
| function build_config_parse () |
| { |
| build_config=$1 |
| |
| CC= |
| LD= |
| cc=`cat ${build_config} | grep ^CC= | cut -d'=' -f 2` |
| ld=`cat ${build_config} | grep ^LD= | cut -d'=' -f 2` |
| |
| if [ $cc == clang ]; then |
| toolchain=`cat ${build_config} | grep CLANG_PREBUILT_BIN | cut -d'=' -f 2` |
| CC="${PWD}/../${toolchain}/${cc}" |
| LD="${PWD}/../${toolchain}/${ld}" |
| else |
| toolchain=`cat ${build_config} | grep LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN | cut -d'=' -f 2` |
| cross_compile=`cat ${build_config} | grep ^CROSS_COMPILE | cut -d'=' -f 2` |
| CC="${PWD}/../${toolchain}/${cross_compile}${cc}" |
| fi |
| } |
| |
| function build_config_read () |
| { |
| build_config_parse ${ARM_CONFIG} |
| CC_ARM="${CC}" |
| LD_ARM="${LD}" |
| |
| build_config_parse ${ARM64_CONFIG} |
| CC_ARM64="${CC}" |
| LD_ARM64="${LD}" |
| |
| build_config_parse ${ARM64_GCC_CONFIG} |
| CC_ARM64_GCC="${CC}" |
| LD_ARM64_GCC="${LD}" |
| |
| build_config_parse ${KASAN_CONFIG} |
| CC_KASAN="${CC}" |
| LD_KASAN="${LD}" |
| |
| build_config_parse ${UBSAN_CONFIG} |
| CC_UBSAN="${CC}" |
| LD_UBSAN="${LD}" |
| } |
| |
| function toolchain_check () |
| { |
| if [ ! -d "../${TOOLCHAIN_CLANG_PATH}/linux-x86" ]; then |
| echo "CLANG does not exist, clone it" |
| mkdir -p "../${TOOLCHAIN_CLANG_PATH}" |
| cd "../${TOOLCHAIN_CLANG_PATH}" |
| git clone "http://gerrit.mediatek.inc:8080/${TOOLCHAIN_CLANG_REPO}" |
| cd linux-x86 |
| git reset --hard ${TOOLCHAIN_CLANG_COMMIT} |
| else |
| echo "update CLANG to specific commit" |
| cd "../${TOOLCHAIN_CLANG_PATH}/linux-x86" |
| git reset --hard ${TOOLCHAIN_CLANG_COMMIT} |
| fi |
| cd ${KERNEL_PATH} |
| |
| if [ ! -d "../${TOOLCHAIN_GCC_PATH}/bin" ]; then |
| echo "GCC does not exist, clone it" |
| rm -rf "../${TOOLCHAIN_GCC_PATH}" |
| mkdir -p "../prebuilts/gcc/linux-x86/aarch64" |
| cd "../prebuilts/gcc/linux-x86/aarch64" |
| git clone "http://gerrit.mediatek.inc:8080/${TOOLCHAIN_GCC_REPO}" -b alps-trunk-r0.basic |
| else |
| echo "update GCC to the latest codebase" |
| cd "../${TOOLCHAIN_GCC_PATH}" |
| git pull |
| fi |
| cd ${KERNEL_PATH} |
| } |
| |
| CONFIGS= |
| UPDATE=0 |
| CHECK_COMMIT=0 |
| CHECK_SERVICE=0 |
| CC= |
| LD= |
| CC_ARM= |
| CC_ARM64= |
| CC_ARM64_GCC= |
| CC_KASAN= |
| CC_UBSAN= |
| LD_ARM= |
| LD_ARM64= |
| LD_ARM64_GCC= |
| LD_KASAN= |
| LD_UBSAN= |
| ARM_CONFIG='build.config.mtk.arm' |
| ARM64_CONFIG='build.config.mtk.aarch64' |
| ARM64_GCC_CONFIG='build.config.mtk.aarch64.gcc' |
| KASAN_CONFIG='build.config.mtk.aarch64.kasan' |
| UBSAN_CONFIG='build.config.mtk.aarch64.ubsan' |
| TOOLCHAIN_CLANG_PATH='prebuilts/clang/host' |
| TOOLCHAIN_GCC_PATH='prebuilts/gcc/linux-x86/aarch64/aarch64-linux-gnu-6.3.1' |
| TOOLCHAIN_CLANG_REPO='platform/prebuilts/clang/host/linux-x86' |
| TOOLCHAIN_GCC_REPO='alps/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-gnu-6.3.1' |
| TOOLCHAIN_CLANG_COMMIT='252aba16f513a857bc923172f67b0e55e23de35f' |
| KERNEL_PATH=${PWD} |
| build_config_read |
| |
| echo "CC_ARM=${CC_ARM}" |
| echo "CC_ARM64=${CC_ARM64}" |
| echo "CC_ARM64_GCC=${CC_ARM64_GCC}" |
| echo "CC_KASAN=${CC_KASAN}" |
| echo "CC_UBSAN=${CC_UBSAN}" |
| echo "LD_ARM=${LD_ARM}" |
| echo "LD_ARM64=${LD_ARM64}" |
| echo "LD_ARM64_GCC=${LD_ARM64_GCC}" |
| echo "LD_KASAN=${LD_KASAN}" |
| echo "LD_UBSAN=${LD_UBSAN}" |
| |
| while getopts "cuh" opt; do |
| case $opt in |
| c) |
| if [ $# == 2 ]; then |
| CHECK_COMMIT=$2 |
| if [ ${CHECK_COMMIT} == FETCH_HEAD ]; then |
| CHECK_SERVICE=1 |
| echo Checking from check service |
| fi |
| else |
| CHECK_COMMIT="HEAD" |
| fi |
| |
| KCONFIG=`git show ${CHECK_COMMIT} --stat | gawk '/\/Kconfig.* +\| +[0-9]*/{print $1}'` |
| if [ ".$KCONFIG" != "." ]; then |
| echo From git commit: Checking all defconfig due to Kconfig is changed. |
| CONFIGS=`grep -rl "CONFIG_MTK_PLATFORM" arch/arm/configs arch/arm64/configs` |
| fi |
| |
| CONFIGS+=" `git show ${CHECK_COMMIT} --stat-width=500 | gawk '/arch\/(arm64|arm)\/configs\/.*_defconfig +\| +[0-9]*/{print $1}'`" |
| CONFIGS=`echo $CONFIGS | xargs -n1 | sort -u | xargs` |
| if [ ".$CONFIGS" != "." ]; then |
| echo From git commit: Checking $CONFIGS |
| else |
| echo "Nothing to check" |
| exit 0 |
| fi |
| ;; |
| u) |
| UPDATE=1 |
| ;; |
| h) |
| usage |
| ;; |
| esac |
| done |
| |
| if [ $# == 0 ]; then |
| usage |
| fi |
| |
| if [ $CHECK_COMMIT == 0 ]; then |
| shift $((OPTIND-1)) |
| CONFIGS="${CONFIGS} $*" |
| fi |
| |
| check_defconfig() { |
| CONFIG=${1} |
| UPDATE=${2} |
| CC_ARM=${3} |
| CC_ARM64=${4} |
| CC_ARM64_GCC=${5} |
| CC_KASAN=${6} |
| CC_UBSAN=${7} |
| LD_ARM=${8} |
| LD_ARM64=${9} |
| LD_ARM64_GCC=${10} |
| LD_KASAN=${11} |
| LD_UBSAN=${12} |
| FAIL=0 |
| echo "Checking ${CONFIG}" |
| |
| if [ ! -e ${CONFIG} ]; then |
| echo warning: defconfig file $CONFIG not found |
| return $FAIL |
| fi |
| |
| echo $CONFIG | grep arch/arm64 > /dev/null |
| RETVAL=$? |
| if [ $RETVAL != 0 ]; then |
| ARCH=arm |
| CC=${CC_ARM} |
| LD=${LD_ARM} |
| else |
| ARCH=arm64 |
| CC=${CC_ARM64} |
| LD=${LD_ARM64} |
| fi |
| |
| echo $CONFIG | grep kasan > /dev/null |
| RETVAL=$? |
| if [ $RETVAL == 0 ]; then |
| CC=${CC_KASAN} |
| LD=${LD_KASAN} |
| fi |
| |
| echo $CONFIG | grep ubsan > /dev/null |
| RETVAL=$? |
| if [ $RETVAL == 0 ]; then |
| CC=${CC_UBSAN} |
| LD=${LD_UBSAN} |
| fi |
| |
| OUT=out-$$ |
| mkdir ${OUT} |
| |
| ARGS=() |
| |
| if [ -n "${CC}" ]; then |
| ARGS+=("CC=${CC}") |
| fi |
| |
| if [ -n "${LD}" ]; then |
| ARGS+=("LD=${LD}") |
| fi |
| |
| CMD="make ARCH=${ARCH} ${ARGS[@]} O=${OUT} `basename ${CONFIG}` savedefconfig 2>&1" |
| echo $CMD |
| |
| OUTPUT="$(${CMD})" |
| RETVAL=$? |
| echo "$OUTPUT" |
| |
| if [ $RETVAL != 0 ]; then |
| echo error: Make ${CONFIG} error |
| rm -rf ${OUT} |
| FAIL=1 |
| return $FAIL |
| fi |
| |
| # Check if there is a warning message |
| if echo "$OUTPUT" | grep -q "^warning:"; then |
| echo error: there is a warning message with Kconfig |
| rm -rf ${OUT} |
| FAIL=1 |
| return $FAIL |
| fi |
| |
| # Check option mismatch |
| gawk 'BEGIN{lastf="";} { if (lastf != FILENAME) { if (lastf != "") CHECK=1; lastf=FILENAME; } } \ |
| /CONFIG_/ { match($0, /CONFIG_[^ =]*/); option=substr($0, RSTART, RLENGTH); \ |
| if (CHECK==1) { if (option in opts && opts[option]==$0) delete opts[option]; } \ |
| else { if (option in opts && opts[option]!=$0) dups[option]=$0; opts[option]=$0; } } \ |
| END { C=0; RET=0; for (i in dups) { RET=1; C++; printf("error: %s duplicate in defconfig\n", i); } \ |
| for (i in opts) { RET=1; C++; printf("error: %s mismatch\n", i); } exit(RET);}' ${CONFIG} ${OUT}/.config |
| RETVAL=$? |
| |
| if [ $RETVAL != 0 ]; then |
| echo error: ${CONFIG}: defconfig mismatch. Please check Kconfig and follow SOP to update _defconfig. |
| rm -rf ${OUT} |
| FAIL=1 |
| return $FAIL |
| fi |
| |
| if [ $UPDATE == 0 ]; then |
| # Compare output, make sure format is correct |
| OUTPUT="$(diff -u ${OUT}/defconfig ${CONFIG} 2>&1)" |
| RETVAL=$? |
| if [ $RETVAL != 0 ]; then |
| echo error: ${CONFIG} compare error. Please follow SOP to update _defconfig |
| echo "$OUTPUT" |
| rm -rf ${OUT} |
| FAIL=1 |
| return $FAIL |
| fi |
| else |
| cp ${OUT}/defconfig ${CONFIG} |
| fi |
| |
| rm -rf ${OUT} |
| return $FAIL |
| } |
| export -f check_defconfig |
| |
| toolchain_check |
| parallel check_defconfig ::: $CONFIGS ::: $UPDATE ::: $CC_ARM ::: $CC_ARM64 ::: $CC_ARM64_GCC ::: $CC_KASAN ::: $CC_UBSAN ::: $LD_ARM ::: $LD_ARM64 ::: $LD_ARM64_GCC ::: $LD_KASAN ::: $LD_UBSAN |
| RETVAL=$? |
| |
| if [ $RETVAL != 0 ]; then |
| echo |
| echo Please check the following wiki for detail, thanks! |
| echo http://wiki.mediatek.inc/display/KernelStandardization/Check+defconfig+in+kernel+preflight |
| echo http://wiki.mediatek.inc/display/KernelStandardization/SOP+to+update+kernel+config |
| fi |
| |
| if [ ${CHECK_SERVICE} == 1 ]; then |
| rm -rf /tmp/prebuilts |
| echo Remove toolchain in check service |
| fi |
| |
| exit $RETVAL |