| # 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="undef" | |
| LD="undef" | |
| NM="undef" | |
| OBJCOPY="undef" | |
| cc=`cat ${build_config} | grep ^CC= | cut -d'=' -f 2` | |
| ld=`cat ${build_config} | grep ^LD= | cut -d'=' -f 2` | |
| nm=`cat ${build_config} | grep ^NM= | cut -d'=' -f 2` | |
| objcopy=`cat ${build_config} | grep ^OBJCOPY= | 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}" | |
| NM="${PWD}/../${toolchain}/${nm}" | |
| OBJCOPY="${PWD}/../${toolchain}/${objcopy}" | |
| 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}" | |
| NM_ARM64="${NM}" | |
| OBJCOPY_ARM64="${OBJCOPY}" | |
| 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= | |
| NM= | |
| OBJCOPY= | |
| CC_ARM= | |
| CC_ARM64= | |
| CC_ARM64_GCC= | |
| CC_KASAN= | |
| CC_UBSAN= | |
| LD_ARM= | |
| LD_ARM64= | |
| LD_ARM64_GCC= | |
| LD_KASAN= | |
| LD_UBSAN= | |
| NM_ARM64= | |
| OBJCOPY_ARM64= | |
| 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='0014e4514e0c2cffb2338f47710f9a3d44275c8d' | |
| 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}" | |
| echo "NM_ARM64=${NM_ARM64}" | |
| echo "OBJCOPY_ARM64=${OBJCOPY_ARM64}" | |
| 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=`ls -d arch/arm/configs/* arch/arm64/configs/* | grep _defconfig | grep gki` | |
| 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 | |
| CONFIGS="${CONFIGS//_defconfig/.config}" | |
| 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} $*" | |
| CONFIGS="${CONFIGS//_defconfig/.config}" | |
| 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} | |
| NM_ARM64=${13} | |
| OBJCOPY_ARM64=${14} | |
| TYPE=${15} | |
| FAIL=0 | |
| if [ ! -e ${CONFIG} ]; then | |
| # echo warning: defconfig file $CONFIG not found | |
| return | |
| fi | |
| echo "Checking ${CONFIG} ${TYPE}" | |
| 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} | |
| NM=${NM_ARM64} | |
| OBJCOPY=${OBJCOPY_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 | |
| if [ -n "${NM}" ]; then | |
| ARGS+=("NM=${NM}") | |
| fi | |
| if [ -n "${OBJCOPY}" ]; then | |
| ARGS+=("OBJCOPY=${OBJCOPY}") | |
| fi | |
| case ${TYPE} in | |
| eng) | |
| TYPE="eng.config" | |
| ;; | |
| userdebug) | |
| TYPE="userdebug.config" | |
| ;; | |
| user) | |
| TYPE="" | |
| ;; | |
| esac | |
| CMD="make ARCH=${ARCH} ${ARGS[@]} O=${OUT} gki_defconfig `basename ${CONFIG}` ${TYPE} 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 | |
| rm -rf ${OUT} | |
| return $FAIL | |
| } | |
| export -f check_defconfig | |
| if [ ${CHECK_SERVICE} == 1 ]; then | |
| toolchain_check | |
| fi | |
| #for TYPE in "eng userdebug user" | |
| for TYPE in "user" | |
| do | |
| 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 ::: $NM_ARM64 ::: $OBJCOPY_ARM64 ::: $TYPE | |
| 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 | |
| done |