| #! /bin/sh |
| # |
| # This script is used to configure BusyBox. |
| # |
| # It was inspired by the challenge in the original Configure script |
| # to ``do something better'', combined with the actual need to ``do |
| # something better'' because the old configure script wasn't flexible |
| # enough. |
| # |
| # Raymond Chen was the original author of Configure. |
| # Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. |
| # |
| # 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13 |
| # with an empty IFS. |
| # |
| # 030995 (storner@osiris.ping.dk) - added support for tri-state answers, |
| # for selecting modules to compile. |
| # |
| # 180995 Bernhard Kaindl (bkaindl@ping.at) - added dummy functions for |
| # use with a config.in modified for make menuconfig. |
| # |
| # 301195 (boldt@math.ucsb.edu) - added help text support |
| # |
| # 281295 Paul Gortmaker - make tri_state functions collapse to boolean |
| # if module support is not enabled. |
| # |
| # 010296 Aaron Ucko (ucko@vax1.rockhurst.edu) - fix int and hex to accept |
| # arbitrary ranges |
| # |
| # 150296 Dick Streefland (dicks@tasking.nl) - report new configuration |
| # items and ask for a value even when doing a "make oldconfig" |
| # |
| # 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is |
| # chosen for an item, define the macro <option_name>_MODULE |
| # |
| # 090397 Axel Boldt (boldt@math.ucsb.edu) - avoid ? and + in regular |
| # expressions for GNU expr since version 1.15 and up use \? and \+. |
| # |
| # 300397 Phil Blundell (pjb27@cam.ac.uk) - added support for min/max |
| # arguments to "int", allow dep_tristate to take a list of dependencies |
| # rather than just one. |
| # |
| # 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help |
| # texts. |
| # |
| # 102598 Michael Chastain (mec@shout.net) - put temporary files in |
| # current directory, not in /tmp. |
| # |
| # 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
| # - Improve the exit message (Jeff Ronne). |
| # |
| # 7 October 2000, Ghozlane Toumi, <gtoumi@messel.emse.fr> |
| # added switches for "random" , "all yes" and "all modules" |
| # |
| |
| # |
| # Make sure we're really running bash. |
| # |
| # I would really have preferred to write this script in a language with |
| # better string handling, but alas, bash is the only scripting language |
| # that I can be reasonable sure everybody has on their linux machine. |
| # |
| [ -z "$BASH" ] && { echo "Configure requires bash" 1>&2; exit 1; } |
| |
| # Disable filename globbing once and for all. |
| # Enable function cacheing. |
| set -f -h |
| |
| # |
| # Dummy functions for use with a config.in modified for menuconf |
| # |
| function mainmenu_option () { |
| : |
| } |
| function mainmenu_name () { |
| : |
| } |
| function endmenu () { |
| : |
| } |
| |
| # |
| # returns a random number between 1 and $1 |
| # |
| function rnd () { |
| rnd=$[ $RANDOM % $1 + 1 ] |
| } |
| |
| # |
| # randomly chose a number in a config list (LIST_CONFIG_NAME) |
| # or in a range ( MIN_CONFIG_NAME MAX_CONFIG_NAME ) |
| # ONLY if there is no forced default (and we are in an "auto" mode) |
| # we are limited by the range of values taken by "$RANDOM" |
| # |
| # rndval CONFIG_NAME |
| # |
| |
| function rndval () { |
| [ "$AUTO" != "yes" -o -n "$old" ] && return |
| def_list=$(eval echo "\${LIST_$1}") |
| def_min=$(eval echo "\${MIN_$1}") |
| def_max=$(eval echo "\${MAX_$1}") |
| |
| if [ -n "$def_list" ]; then |
| set -- $(echo $def_list | sed 's/,/ /g') |
| rnd $# |
| while [ $rnd -le $# ] ; do |
| def=$1 |
| shift |
| done |
| return |
| fi |
| if [ -n "$def_min" -a -n "$def_max" ]; then |
| rnd $[ $def_max - $def_min ] |
| def=$[ $def_min + $rnd ] |
| fi |
| } |
| |
| # |
| # help prints the corresponding help text from Configure.help to stdout |
| # |
| # help variable |
| # |
| function help () { |
| if [ -f docs/Configure.help ] |
| then |
| #first escape regexp special characters in the argument: |
| var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g') |
| #now pick out the right help text: |
| text=$(sed -n "/^$var[ ]*\$/,\${ |
| /^$var[ ]*\$/c\\ |
| ${var}:\\ |
| |
| /^#/b |
| /^[^ ]/q |
| /<file:\\([^>]*\\)>/s//\\1/g |
| p |
| }" docs/Configure.help) |
| if [ -z "$text" ] |
| then |
| echo; echo " Sorry, no help available for this option yet.";echo |
| else |
| (echo; echo "$text") | ${PAGER:-more} |
| fi |
| else |
| echo; |
| echo " Can't access the file docs/Configure.help which" |
| echo " should contain the help texts." |
| echo |
| fi |
| } |
| |
| |
| # |
| # readln reads a line into $ans. |
| # |
| # readln prompt default oldval |
| # |
| function readln () { |
| if [ "$AUTO" = "yes" ]; then |
| echo -n "$1" |
| ans=$2 |
| echo $ans |
| elif [ "$DEFAULT" = "-d" -a -n "$3" ]; then |
| echo "$1" |
| ans=$2 |
| else |
| echo -n "$1" |
| [ -z "$3" ] && echo -n "(NEW) " |
| IFS='@' read ans || exit 1 |
| [ -z "$ans" ] && ans=$2 |
| fi |
| } |
| |
| # |
| # comment does some pretty-printing |
| # |
| # comment 'xxx' |
| # |
| function comment () { |
| echo "*"; echo "* $1" ; echo "*" |
| (echo "" ; echo "#"; echo "# $1" ; echo "#") >>$CONFIG |
| (echo "" ; echo "/*"; echo " * $1" ; echo " */") >>$CONFIG_H |
| } |
| |
| # |
| # define_bool sets the value of a boolean argument |
| # |
| # define_bool define value |
| # |
| function define_bool () { |
| define_tristate $1 $2 |
| } |
| |
| function define_tristate () { |
| case "$2" in |
| "y") |
| echo "$1=y" >>$CONFIG |
| echo "#define $1 1" >>$CONFIG_H |
| ;; |
| |
| "m") |
| echo "$1=m" >>$CONFIG |
| echo "#undef $1" >>$CONFIG_H |
| echo "#define $1_MODULE 1" >>$CONFIG_H |
| ;; |
| |
| "n") |
| echo "# $1 is not set" >>$CONFIG |
| echo "#undef $1" >>$CONFIG_H |
| ;; |
| esac |
| eval "$1=$2" |
| } |
| |
| # |
| # bool processes a boolean argument |
| # |
| # bool question define |
| # |
| function bool () { |
| old=$(eval echo "\${$2}") |
| def=${old:-'n'} |
| if [ "$AUTO" = "yes" -a -z "$old" ]; then |
| if [ "$RND" = "-r" ]; then |
| rnd 2 |
| case $rnd in |
| "1") def="y" ;; |
| "2") def="n" ;; |
| esac |
| else |
| def=$DEF_ANS; |
| fi |
| fi |
| case "$def" in |
| "y" | "m") defprompt="Y/n/?" |
| def="y" |
| ;; |
| "n") defprompt="N/y/?" |
| ;; |
| esac |
| while :; do |
| readln "$1 ($2) [$defprompt] " "$def" "$old" |
| case "$ans" in |
| [yY] | [yY]es ) define_bool "$2" "y" |
| break;; |
| [nN] | [nN]o ) define_bool "$2" "n" |
| break;; |
| * ) help "$2" |
| ;; |
| esac |
| done |
| } |
| |
| # |
| # tristate processes a tristate argument |
| # |
| # tristate question define |
| # |
| function tristate () { |
| if [ "$CONFIG_MODULES" != "y" ]; then |
| bool "$1" "$2" |
| else |
| old=$(eval echo "\${$2}") |
| def=${old:-'n'} |
| if [ "$AUTO" = "yes" -a -z "$old" ]; then |
| if [ "$RND" = "-r" ]; then |
| rnd 3 |
| case $rnd in |
| "1") def="y" ;; |
| "2") def="n" ;; |
| "3") def="m" ;; |
| esac |
| else |
| def=$DEF_ANS |
| fi |
| fi |
| case "$def" in |
| "y") defprompt="Y/m/n/?" |
| ;; |
| "m") defprompt="M/n/y/?" |
| ;; |
| "n") defprompt="N/y/m/?" |
| ;; |
| esac |
| while :; do |
| readln "$1 ($2) [$defprompt] " "$def" "$old" |
| case "$ans" in |
| [yY] | [yY]es ) define_tristate "$2" "y" |
| break ;; |
| [nN] | [nN]o ) define_tristate "$2" "n" |
| break ;; |
| [mM] ) define_tristate "$2" "m" |
| break ;; |
| * ) help "$2" |
| ;; |
| esac |
| done |
| fi |
| } |
| |
| # |
| # dep_tristate processes a tristate argument that depends upon |
| # another option or options. If any of the options we depend upon is a |
| # module, then the only allowable options are M or N. If all are Y, then |
| # this is a normal tristate. This is used in cases where modules |
| # are nested, and one module requires the presence of something |
| # else in the kernel. |
| # |
| # dep_tristate question define default ... |
| # |
| function dep_tristate () { |
| old=$(eval echo "\${$2}") |
| def=${old:-'n'} |
| ques=$1 |
| var=$2 |
| need_module=0 |
| shift 2 |
| while [ $# -gt 0 ]; do |
| case "$1" in |
| n) |
| define_tristate "$var" "n" |
| return |
| ;; |
| m) |
| need_module=1 |
| ;; |
| esac |
| shift |
| done |
| |
| if [ $need_module = 1 ]; then |
| if [ "$CONFIG_MODULES" = "y" ]; then |
| if [ "$AUTO" = "yes" -a -z "$old" ]; then |
| if [ "$RND" = "-r" ]; then |
| rnd 2 |
| case $rnd in |
| "1") def="m" ;; |
| "2") def="n" ;; |
| esac |
| else |
| def=$DEF_ANS |
| fi |
| fi |
| case "$def" in |
| "y" | "m") defprompt="M/n/?" |
| def="m" |
| ;; |
| "n") defprompt="N/m/?" |
| ;; |
| esac |
| while :; do |
| readln "$ques ($var) [$defprompt] " "$def" "$old" |
| case "$ans" in |
| [nN] | [nN]o ) define_tristate "$var" "n" |
| break ;; |
| [mM] ) define_tristate "$var" "m" |
| break ;; |
| [yY] | [yY]es ) echo |
| echo " This answer is not allowed, because it is not consistent with" |
| echo " your other choices." |
| echo " This driver depends on another one which you chose to compile" |
| echo " as a module. This means that you can either compile this one" |
| echo " as a module as well (with M) or leave it out altogether (N)." |
| echo |
| ;; |
| * ) help "$var" |
| ;; |
| esac |
| done |
| fi |
| else |
| tristate "$ques" "$var" |
| fi |
| } |
| |
| function dep_bool () { |
| ques=$1 |
| var=$2 |
| shift 2 |
| while [ $# -gt 0 ]; do |
| case "$1" in |
| m | n) |
| define_bool "$var" "n" |
| return |
| ;; |
| esac |
| shift |
| done |
| |
| bool "$ques" "$var" |
| } |
| |
| function dep_mbool () { |
| ques=$1 |
| var=$2 |
| shift 2 |
| while [ $# -gt 0 ]; do |
| case "$1" in |
| n) |
| define_bool "$var" "n" |
| return |
| ;; |
| esac |
| shift |
| done |
| |
| bool "$ques" "$var" |
| } |
| |
| # |
| # define_int sets the value of a integer argument |
| # |
| # define_int define value |
| # |
| function define_int () { |
| echo "$1=$2" >>$CONFIG |
| echo "#define $1 ($2)" >>$CONFIG_H |
| eval "$1=$2" |
| } |
| |
| # |
| # int processes an integer argument with optional limits |
| # |
| # int question define default [min max] |
| # |
| function int () { |
| old=$(eval echo "\${$2}") |
| def=${old:-$3} |
| if [ $# -gt 3 ]; then |
| min=$4 |
| else |
| min=-10000000 # !! |
| fi |
| if [ $# -gt 4 ]; then |
| max=$5 |
| else |
| max=10000000 # !! |
| fi |
| rndval $2 |
| while :; do |
| readln "$1 ($2) [$def] " "$def" "$old" |
| if expr \( \( $ans + 0 \) \>= $min \) \& \( $ans \<= $max \) >/dev/null 2>&1 ; then |
| define_int "$2" "$ans" |
| break |
| else |
| help "$2" |
| fi |
| done |
| } |
| |
| # |
| # define_hex sets the value of a hexadecimal argument |
| # |
| # define_hex define value |
| # |
| function define_hex () { |
| echo "$1=$2" >>$CONFIG |
| echo "#define $1 0x${2#*[x,X]}" >>$CONFIG_H |
| eval "$1=$2" |
| } |
| |
| # |
| # hex processes an hexadecimal argument |
| # |
| # hex question define default |
| # |
| function hex () { |
| old=$(eval echo "\${$2}") |
| def=${old:-$3} |
| def=${def#*[x,X]} |
| rndval $2 |
| while :; do |
| readln "$1 ($2) [$def] " "$def" "$old" |
| ans=${ans#*[x,X]} |
| if expr "$ans" : '[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then |
| define_hex "$2" "$ans" |
| break |
| else |
| help "$2" |
| fi |
| done |
| } |
| |
| # |
| # define_string sets the value of a string argument |
| # |
| # define_string define value |
| # |
| function define_string () { |
| echo "$1=\"$2\"" >>$CONFIG |
| echo "#define $1 \"$2\"" >>$CONFIG_H |
| eval "$1=\"$2\"" |
| } |
| |
| # |
| # string processes a string argument |
| # |
| # string question define default |
| # |
| function string () { |
| old=$(eval echo "\${$2}") |
| def=${old:-$3} |
| while :; do |
| if [ "$old" = "?" ]; then |
| readln "$1 ($2) [$def] " "$def" "" |
| else |
| readln "$1 ($2) [$def] " "$def" "$old" |
| fi |
| if [ "$ans" = "?" ]; then |
| help "$2" |
| else |
| break |
| fi |
| done |
| define_string "$2" "$ans" |
| } |
| # |
| # choice processes a choice list (1-out-of-n) |
| # |
| # choice question choice-list default |
| # |
| # The choice list has a syntax of: |
| # NAME WHITESPACE VALUE { WHITESPACE NAME WHITESPACE VALUE } |
| # The user may enter any unique prefix of one of the NAMEs and |
| # choice will define VALUE as if it were a boolean option. |
| # VALUE must be in all uppercase. Normally, VALUE is of the |
| # form CONFIG_<something>. Thus, if the user selects <something>, |
| # the CPP symbol CONFIG_<something> will be defined and the |
| # shell variable CONFIG_<something> will be set to "y". |
| # |
| function choice () { |
| question="$1" |
| choices="$2" |
| old= |
| def=$3 |
| |
| # determine default answer: |
| names="" |
| set -- $choices |
| firstvar=$2 |
| while [ -n "$2" ]; do |
| if [ -n "$names" ]; then |
| names="$names, $1" |
| else |
| names="$1" |
| fi |
| if [ "$(eval echo \"\${$2}\")" = "y" ]; then |
| old=$1 |
| def=$1 |
| fi |
| shift; shift |
| done |
| |
| if [ "$RND" = "-r" -a -z "$old" ] ; then |
| set -- $choices |
| rnd $# |
| while [ $rnd -le $# ] ; do |
| def=$1 |
| shift ; shift |
| done |
| fi |
| |
| val="" |
| while [ -z "$val" ]; do |
| ambg=n |
| readln "$question ($names) [$def] " "$def" "$old" |
| ans=$(echo $ans | tr a-z A-Z) |
| set -- $choices |
| while [ -n "$1" ]; do |
| name=$(echo $1 | tr a-z A-Z) |
| case "$name" in |
| "$ans"* | */"$ans"* ) |
| case "$name" in |
| "$ans" | */"$ans"/* | \ |
| "$ans"/* | */"$ans" ) |
| val="$2" |
| break # exact match |
| ;; |
| esac |
| if [ -n "$val" ]; then |
| echo;echo \ |
| " Sorry, \"$ans\" is ambiguous; please enter a longer string." |
| echo |
| val="" |
| ambg=y |
| break |
| else |
| val="$2" |
| fi;; |
| esac |
| shift; shift |
| done |
| if [ "$val" = "" -a "$ambg" = "n" ]; then |
| help "$firstvar" |
| fi |
| done |
| set -- $choices |
| while [ -n "$2" ]; do |
| if [ "$2" = "$val" ]; then |
| echo " defined $val" |
| define_bool "$2" "y" |
| else |
| define_bool "$2" "n" |
| fi |
| shift; shift |
| done |
| } |
| |
| CONFIG=.tmpconfig |
| CONFIG_H=.tmpconfig.h |
| FORCE_DEFAULT=.force_default |
| trap "rm -f $CONFIG $CONFIG_H ; exit 1" 1 2 |
| |
| # |
| # Make sure we start out with a clean slate. |
| # |
| echo "#" > $CONFIG |
| echo "# Automatically generated make config: don't edit" >> $CONFIG |
| echo "#" >> $CONFIG |
| |
| echo "/*" > $CONFIG_H |
| echo " * Automatically generated C config: don't edit" >> $CONFIG_H |
| echo " */" >> $CONFIG_H |
| echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H |
| |
| DEFAULT="" |
| if [ "$1" = "-d" ] ; then |
| DEFAULT="-d" |
| shift |
| fi |
| |
| RND="" |
| DEF_ANS="" |
| AUTO="" |
| case "$1" in |
| -r) RND="-r" ; AUTO="yes" ; shift ;; |
| -y) DEF_ANS="y" ; AUTO="yes" ; shift ;; |
| -m) DEF_ANS="m" ; AUTO="yes" ; shift ;; |
| -n) DEF_ANS="n" ; AUTO="yes" ; shift ;; |
| esac |
| |
| CONFIG_IN=./config.in |
| if [ "$1" != "" ] ; then |
| CONFIG_IN=$1 |
| fi |
| |
| DEFAULTS=sysdeps/$TARGET_OS/defconfig |
| if [ -f .config ]; then |
| DEFAULTS=.config |
| fi |
| |
| if [ "$AUTO" != "yes" ]; then |
| if [ -f $DEFAULTS ]; then |
| echo "#" |
| echo "# Using defaults found in" $DEFAULTS |
| echo "#" |
| . $DEFAULTS |
| sed -e 's/# \(CONFIG_[^ ]*\) is not.*/\1=n/' <$DEFAULTS >.config-is-not.$$ |
| . .config-is-not.$$ |
| rm .config-is-not.$$ |
| else |
| echo "#" |
| echo "# No defaults found" |
| echo "#" |
| fi |
| else |
| if [ -f $FORCE_DEFAULT ]; then |
| echo "#" |
| echo "# Forcing defaults found in $FORCE_DEFAULT" |
| echo "#" |
| sed -e ' |
| s/# \(CONFIG_[^ ]*\) is not.*/\1=n/; |
| s/# range \(CONFIG_[^ ]*\) \([^ ][^ ]*\) \([^ ][^ ]*\)/MIN_\1=\2; MAX_\1=\3/; |
| s/# list \(CONFIG_[^ ]*\) \([^ ][^ ]*\)/LIST_\1=\2/ |
| ' <$FORCE_DEFAULT >.default_val.$$ |
| . .default_val.$$ |
| rm .default_val.$$ |
| else |
| echo "#" |
| echo "# No defaults found" |
| echo "#" |
| fi |
| fi |
| |
| . $CONFIG_IN |
| |
| rm -f .config.old |
| if [ -f .config ]; then |
| mv .config .config.old |
| fi |
| mv .tmpconfig .config |
| mv .tmpconfig.h include/config.h |
| |
| echo |
| echo "*** End of BusyBox configuration." |
| echo "*** Check the top-level Makefile for additional configuration." |
| if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then |
| echo "*** Next, you must run 'make dep'." |
| else |
| echo "*** Next, you may run 'make', or 'make install'." |
| fi |
| echo |
| |
| exit 0 |