#!/bin/sh # # A wrapper script to adjust Kconfig for U-Boot # # Instead of touching various parts under the scripts/kconfig/ directory, # pushing necessary adjustments into this single script would be better # for code maintainance. All the make targets related to the configuration # (make %config) should be invoked via this script. # See doc/README.kconfig for further information of Kconfig. # # Copyright (C) 2014, Masahiro Yamada # # SPDX-License-Identifier: GPL-2.0+ # set -e # Set "DEBUG" enavironment variable to show debug messages debug () { if [ $DEBUG ]; then echo "$@" fi } # Useful shorthands build () { debug $progname: $MAKE -f $srctree/scripts/Makefile.build obj="$@" $MAKE -f $srctree/scripts/Makefile.build obj="$@" } autoconf () { debug $progname: $MAKE -f $srctree/scripts/Makefile.autoconf obj="$@" $MAKE -f $srctree/scripts/Makefile.autoconf obj="$@" } # Make a configuration target # Usage: # run_make_config # : Make target such as "config", "menuconfig", "defconfig", etc. # : Target directory where the make command is run. # Typically "", "spl", "tpl" for Normal, SPL, TPL, respectively. run_make_config () { target=$1 objdir=$2 # Linux expects defconfig files in arch/$(SRCARCH)/configs/ directory, # but U-Boot has them in configs/ directory. # Give SRCARCH=.. to fake scripts/kconfig/Makefile. options="SRCARCH=.. KCONFIG_OBJDIR=$objdir" if [ "$objdir" ]; then options="$options KCONFIG_CONFIG=$objdir/$KCONFIG_CONFIG" mkdir -p $objdir fi build scripts/kconfig $options $target } # Parse .config file to detect if CONFIG_SPL, CONFIG_TPL is enabled # and returns: # "" if neither CONFIG_SPL nor CONFIG_TPL is defined # "spl" if CONFIG_SPL is defined but CONFIG_TPL is not # "spl tpl" if both CONFIG_SPL and CONFIG_TPL are defined get_enabled_subimages() { if [ ! -r "$KCONFIG_CONFIG" ]; then # This should never happen echo "$progname: $KCONFIG_CONFIG not found" >&2 exit 1 fi # CONFIG_SPL=y -> spl # CONFIG_TPL=y -> tpl sed -n -e 's/^CONFIG_SPL=y$/spl/p' -e 's/^CONFIG_TPL=y$/tpl/p' \ $KCONFIG_CONFIG } do_silentoldconfig () { run_make_config silentoldconfig subimages=$(get_enabled_subimages) for obj in $subimages do mkdir -p $obj/include/config $obj/include/generated run_make_config silentoldconfig $obj done # If the following part fails, include/config/auto.conf should be # deleted so "make silentoldconfig" will be re-run on the next build. autoconf include include/autoconf.mk include/autoconf.mk.dep || { rm -f include/config/auto.conf exit 1 } # 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. touch include/config/auto.conf for obj in $subimages do autoconf $obj/include $obj/include/autoconf.mk || { rm -f include/config/auto.conf exit 1 } done } cleanup_after_defconfig () { rm -f configs/.tmp_defconfig # ignore 'Directory not empty' error # without using non-POSIX option '--ignore-fail-on-non-empty' rmdir arch configs 2>/dev/null || true } # Usage: # do_board_defconfig _defconfig do_board_defconfig () { defconfig_path=$srctree/configs/$1 tmp_defconfig_path=configs/.tmp_defconfig if [ ! -r $defconfig_path ]; then echo >&2 "***" echo >&2 "*** Can't find default configuration \"configs/$1\"!" echo >&2 "***" exit 1 fi mkdir -p arch configs # defconfig for Normal: # pick lines without prefixes and lines starting '+' prefix # and rip the prefixes off. sed -n -e '/^[+A-Z]*:/!p' -e 's/^+[A-Z]*://p' $defconfig_path \ > configs/.tmp_defconfig run_make_config .tmp_defconfig || { cleanup_after_defconfig exit 1 } for img in $(get_enabled_subimages) do symbol=$(echo $img | cut -c 1 | tr '[a-z]' '[A-Z]') # defconfig for SPL, TPL: # pick lines with 'S', 'T' prefix and rip the prefixes off sed -n -e 's/^[+A-Z]*'$symbol'[A-Z]*://p' $defconfig_path \ > configs/.tmp_defconfig run_make_config .tmp_defconfig $img || { cleanup_after_defconfig exit 1 } done cleanup_after_defconfig } do_defconfig () { if [ "$KBUILD_DEFCONFIG" ]; then do_board_defconfig $KBUILD_DEFCONFIG echo "*** Default configuration is based on '$KBUILD_DEFCONFIG'" else run_make_config defconfig fi } do_savedefconfig () { if [ -r "$KCONFIG_CONFIG" ]; then subimages=$(get_enabled_subimages) else subimages= fi run_make_config savedefconfig output_lines= # -r option is necessay because some string-type configs may include # backslashes as an escape character while read -r line do output_lines="$output_lines%$line" done < defconfig for img in $subimages do run_make_config savedefconfig $img symbol=$(echo $img | cut -c 1 | tr '[a-z]' '[A-Z]') unmatched= while read -r line do tmp= match= # "# CONFIG_FOO is not set" should not be divided. # Use "%" as a separator, instead of a whitespace. # "%" is unlikely to appear in defconfig context. save_IFS=$IFS IFS=% # coalesce common lines together for i in $output_lines do case "$i" in [+A-Z]*:$line) tmp="$tmp%$unmatched" i=$(echo "$i" | \ sed -e "s/^\([^:]*\)/\1$symbol/") tmp="$tmp%$i" match=1 ;; $line) tmp="$tmp%$unmatched" tmp="$tmp%+$symbol:$i" match=1 ;; *) tmp="$tmp%$i" ;; esac done # Restore the default separator for the outer for loop. IFS=$save_IFS if [ "$match" ]; then output_lines="$tmp" unmatched= else unmatched="$unmatched%$symbol:$line" fi done < defconfig output_lines="$output_lines%$unmatched" done rm -f defconfig touch defconfig save_IFS=$IFS IFS=% for line in $output_lines do case "$line" in "") # do not output blank lines ;; *) echo $line >> defconfig ;; esac done IFS=$save_IFS } # Some sanity checks before running "make /", # where should be either "spl" or "tpl". # Doing "make spl/menuconfig" etc. on a non-SPL board makes no sense. # It should be allowed only when ".config" exists and "CONFIG_SPL" is enabled. # # Usage: # check_enabled_sumbimage / check_enabled_subimage () { case $2 in spl|tpl) ;; *) echo >&2 "***" echo >&2 "*** \"make $1\" is not supported." echo >&2 "***" exit 1 ;; esac test -r "$KCONFIG_CONFIG" && get_enabled_subimages | grep -q $2 || { config=CONFIG_$(echo $2 | tr '[a-z]' '[A-Z]') echo >&2 "***" echo >&2 "*** Create \"$KCONFIG_CONFIG\" with \"$config\" enabled" echo >&2 "*** before \"make $1\"." echo >&2 "***" exit 1 } } # Usage: # do_others / # The field "/" is typically empy, "spl/", "tpl/" for Normal, SPL, TPL, # respectively. # The field "" is a configuration target such as "config", # "menuconfig", etc. do_others () { target=${1##*/} if [ "$target" = "$1" ]; then objdir= else objdir=${1%/*} check_enabled_subimage $1 $objdir if [ -f "$objdir/$KCONFIG_CONFIG" ]; then timestamp_before=$(stat --printf="%Y" \ $objdir/$KCONFIG_CONFIG) fi fi run_make_config $target $objdir if [ "$timestamp_before" -a -f "$objdir/$KCONFIG_CONFIG" ]; then timestamp_after=$(stat --printf="%Y" $objdir/$KCONFIG_CONFIG) if [ "$timestamp_after" -gt "$timestamp_before" ]; then # $objdir/.config has been updated. # touch .config to invoke "make silentoldconfig" touch $KCONFIG_CONFIG fi fi } progname=$(basename $0) target=$1 case $target in *_defconfig) do_board_defconfig $target;; *_config) # backward compatibility do_board_defconfig ${target%_config}_defconfig;; silentoldconfig) do_silentoldconfig;; defconfig) do_defconfig;; savedefconfig) do_savedefconfig;; *) do_others $target;; esac