configure
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Thu May 19 22:29:49 2011 +0200 (2011-05-19)
changeset 2468 90595d1c1017
parent 2026 a8a4d5c97738
child 2479 bce8b2a4bf8f
child 2559 af44455a6567
permissions -rwxr-xr-x
scripts: munge .config to handle array variables

Transfrom array variables from pure strings (in the kconfig output)
into proper bash arrays declarations, for feeding to the build scripts.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Signed-off-by: "Benoît THÉBAUDEAU" <benoit.thebaudeau@advansee.com>
     1 #!/bin/sh
     2 
     3 myname="${0##*/}"
     4 
     5 VERSION=$( cat .version )
     6 DATE=$( date +%Y%m%d )
     7 
     8 PREFIX_DEFAULT=/usr/local
     9 
    10 BINDIR_set=
    11 LIBDIR_set=
    12 DOCDIR_set=
    13 MANDIR_set=
    14 LOCAL_set=
    15 FORCE=
    16 
    17 do_quit=
    18 
    19 # Simply print the error message, and exit. Obvious, he?
    20 do_error() {
    21     printf "${myname}: ${@}\n"
    22     exit 1
    23 }
    24 
    25 # Given an option string and the following argument,
    26 # echoes the value of the option.
    27 # If --var=val => echoes val and returns 0, meaning second arg was not consumed
    28 # If --var val => echoes val and returns non null, meaning second arg was used
    29 get_optval(){
    30     case "$1" in
    31         --*=?*)
    32             printf "${1#*=}"
    33             return 0
    34             ;;
    35         *)
    36             printf "${2}"
    37             return 1
    38             ;;
    39     esac
    40 }
    41 
    42 # The set_xxx functions will set the corresponding configuration variable
    43 # They return 0 if second arg was not consumed, and non-zero if it was consumed.
    44 set_prefix() {
    45     PREFIX="$( get_optval "$1" "$2" )"
    46 }
    47 set_bindir() {
    48     BINDIR_set=1
    49     BINDIR="$( get_optval "$1" "$2" )"
    50 }
    51 set_libdir() {
    52     LIBDIR_set=1
    53     LIBDIR="$( get_optval "$1" "$2" )"
    54 }
    55 set_docdir() {
    56     DOCDIR_set=1
    57     DOCDIR="$( get_optval "$1" "$2" )"
    58 }
    59 set_mandir() {
    60     MANDIR_set=1
    61     MANDIR="$( get_optval "$1" "$2" )"
    62 }
    63 set_tool() {
    64     local var_name="${1%%=*}"
    65     var_name="${var_name#--with-}"
    66     eval ${var_name}="\$( get_optval "$1" "$2" )"
    67 }
    68 
    69 # var_list is a list of variables, each one holding a path to a
    70 # tool, either detected by ./configure, or specified by the user.
    71 var_list=""
    72 
    73 # This function adds a variable name to the above list of variable names.
    74 # $1: the name of the variable to add to the list
    75 add_to_var_list() {
    76     var_list="${var_list} ${1}"
    77 }
    78 
    79 # A function to test for required tools/headers/libraries
    80 # Return 0 (true) if found, !0 (false) if not found
    81 #
    82 # $*: [prog|inc|lib]=<name[ name...]>
    83 #     the name(s) of tool(s) to test for
    84 #     mandatory
    85 #       eg: prog=bash   prog="curl wget"
    86 # $*: var=<var_name>
    87 #     the name of the variable to test and set
    88 #     optional
    89 #       eg: var=bash    if ${bash} is set and non-null, use that,
    90 #                       else check for bash and set bash=$(which bash)
    91 # $*: ver=<regexp>
    92 #     for each 'prog', test if $(prog --version) matches 'regexp'
    93 #     optional
    94 #       eg: ver='^GNU bash, version [34]\.'
    95 # $*: err=<error_message>
    96 #     the error message to print if tool is missing
    97 #     optional, defaults to: '${prog}: none found'
    98 #       eg: err="'bash' 3.x or above was not found"
    99 check_for() {
   100     local prog inc lib
   101     local var ver err
   102     local val
   103     local item
   104     local where
   105     local status
   106 
   107     for item in "${@}"; do
   108         case "${item}" in
   109             prog=*|inc=*|lib=*|var=*|ver=*|err=*)
   110                 eval ${item%%=*}="'${item#*=}'"
   111                 ;;
   112             *)  do_error "has_or_abort: incorrect parameters: '$@'";;
   113         esac
   114     done
   115 
   116     case "${prog}:${inc}:${lib}" in
   117         ?*::)
   118             for item in ${prog}; do
   119                 printf "Checking for '${item}'... "
   120                 if [ -n "${var}" ]; then
   121                     eval val="\${${var}}"
   122                     if [ -n "${val}" ]; then
   123                         printf "${val} (cached)\n"
   124                         add_to_var_list "${var}"
   125                         return 0
   126                     fi
   127                 fi
   128                 where="$( which "${item}" 2>/dev/null )"
   129                 if [ -z "${where}" ]; then
   130                     printf "no\n"
   131                     continue
   132                 elif [ -n "${ver}" ]; then
   133                     str=$( LC_ALL=C "${where}" --version 2>&1   \
   134                            |grep -E "${ver}"                    \
   135                            |head -n 1
   136                          )
   137                     if [ -z "${str}" ]; then
   138                         printf "no\n"
   139                         unset where
   140                         continue
   141                     fi
   142                 fi
   143                 status="${where}"
   144                 break
   145             done
   146             ;;
   147         :?*:)
   148             for item in ${inc}; do
   149                 printf "Checking for '${item}'... "
   150                 if printf "#include \"${item}\"" |gcc -x c -c - -o /dev/null >/dev/null 2>&1; then
   151                     where="${item}"
   152                     status=yes
   153                     break;
   154                 fi
   155                 printf "no\n"
   156             done
   157             ;;
   158         ::?*)
   159             for item in ${lib}; do
   160                 printf "Checking for '${item}'... "
   161                 where="$( gcc -print-file-name="${item}" )"
   162                 if [ "${where}" != "${item}" ]; then
   163                     where="$( readlink "${where}" )"
   164                     status=yes
   165                     break;
   166                 fi
   167                 printf "no\n"
   168             done
   169             ;;
   170     esac
   171 
   172     if [ -z "${status}" ]; then
   173         printf "\n${err:-${prog}${inc}${lib}: none found}\n\n"
   174         printf "Either you are missing entirely the needed tool,\n"
   175         printf "or the version you have is too old.\n"
   176         if [ -n "${var}" ]; then
   177             printf "You can give the path to this tool using: --with-${var}=PATH\n"
   178         fi
   179         printf "\n"
   180         return 1
   181     fi
   182 
   183     printf "${status}"
   184     if [ -n "${var}" ]; then
   185         eval ${var}='"'"${where}"'"'
   186         add_to_var_list "${var}"
   187     fi
   188     printf "\n"
   189 }
   190 
   191 # This function checks for a tool, and aborts if not found
   192 # See check_for(), above, for how to call has_or_abort
   193 has_or_abort() {
   194     if ! check_for "$@"; then
   195         # FORCE can be set in the environment
   196         [ -z "${FORCE}" ] && do_error "Bailing out..."
   197         printf "\n"
   198         printf "<*                                          *>\n"
   199         printf "<*            FORCE in action:              *>\n"
   200         printf "<* Continuing despite missing pre-requisite *>\n"
   201         printf "<*          Prepare for breakage            *>\n"
   202         printf "<*                                          *>\n"
   203         printf "\n"
   204     fi
   205 }
   206 
   207 do_help() {
   208     cat <<__EOF__
   209 \`configure' configures crosstool-NG-${VERSION} to adapt to many kind of systems.
   210 
   211 USAGE: ./configure [OPTION]...
   212 
   213 Defaults for the options are specified in brackets.
   214 
   215 Configuration:
   216   -h, --help              display this help and exit
   217       --force             force configure to continue, even in case
   218                           some pre-requisites are missing
   219 
   220 Installation directories:
   221   --prefix=PREFIX         install files in PREFIX [${PREFIX_DEFAULT}]
   222   --local                 don't install, and use current directory
   223 
   224 By default, \`make install' will install all the files in
   225 \`${PREFIX_DEFAULT}/bin', \`${PREFIX_DEFAULT}/lib' etc.  You can specify
   226 an installation prefix other than \`${PREFIX_DEFAULT}' using \`--prefix',
   227 for instance \`--prefix=\${HOME}'.
   228 
   229 For better control, use the options below.
   230 
   231 Fine tuning of the installation directories:
   232   --bindir=DIR            user executables [PREFIX/bin]
   233   --libdir=DIR            object code libraries [PREFIX/lib]
   234   --docdir=DIR            info documentation [PREFIX/share/doc]
   235   --mandir=DIR            man documentation [PREFIX/share/man]
   236 
   237 Optional Features:
   238   --with-install=PATH     Specify the full PATH to GNU install
   239   --with-make=PATH        Specify the full PATH to GNU make >= 3.80
   240   --with-grep=PATH        Specify the full PATH to GNU grep
   241   --with-sed=PATH         Specify the full PATH to GNU sed
   242   --with-bash=PATH        Specify the full PATH to bash >= 3.0
   243 __EOF__
   244 }
   245 
   246 #---------------------------------------------------------------------
   247 # Set user's options
   248 
   249 while [ $# -ne 0 ]; do
   250     case "$1" in
   251         --local)    LOCAL_set="y"; shift;;
   252         --prefix*)  set_prefix "$1" "$2" && shift || shift 2;;
   253         --bindir*)  set_bindir "$1" "$2" && shift || shift 2;;
   254         --libdir*)  set_libdir "$1" "$2" && shift || shift 2;;
   255         --docdir*)  set_docdir "$1" "$2" && shift || shift 2;;
   256         --mandir*)  set_mandir "$1" "$2" && shift || shift 2;;
   257         --with-*)   set_tool   "$1" "$2" && shift || shift 2;;
   258         --force)    FORCE=1; shift;;
   259         --help|-h)  do_help; exit 0;;
   260         # Skip, auto-stuff compatibility
   261         --build=*|--host=*|--infodir=*|--datadir=*|--sysconfdir=*|--localstatedir=*) shift;;
   262         --build|--host|--infodir|--datadir|--sysconfdir|--localstatedir)             shift 2;;
   263         *)          printf "Unrecognised option: '${1}'\n"; do_help; exit 1;;
   264     esac
   265 done
   266 
   267 # Use defaults
   268 [ -z "${PREFIX}" ] && set_prefix "" "${PREFIX_DEFAULT}"
   269 
   270 # Special case when installing locally
   271 if [ "${LOCAL_set}" = "y" ]; then
   272     set_prefix "" "$( pwd )"
   273     set_bindir "" "$( pwd )"
   274     set_libdir "" "$( pwd )"
   275     set_docdir "" "$( pwd )/docs"
   276     set_mandir "" "$( pwd )/docs"
   277 fi
   278 
   279 #---------------------------------------------------------------------
   280 # Some sanity checks, now
   281 
   282 # We check for grep and sed manually, because they are used in check_for()
   283 printf "Checking for 'grep'... "
   284 if [ -n "${grep}" ]; then
   285     printf "${grep} (cached)\n"
   286 else
   287     grep="$( which grep 2>/dev/null )"
   288     if [ -z "${grep}" ]; then
   289         printf "not found\n"
   290     else
   291         printf "${grep}\n"
   292         printf "Checking whether '${grep}' supports -E... "
   293         if echo 'foo' |"${grep}" -E 'foo' >/dev/null 2>&1; then
   294             printf "yes\n"
   295         else
   296             printf "no\n"
   297             grep=
   298         fi
   299     fi
   300 fi
   301 if [ -z "${grep}" ]; then
   302     printf "Either you are missing entirely the needed tool,\n"
   303     printf "or the version you have is too old.\n"
   304     printf "You can give the path to this tool using: --with-grep=PATH\n"
   305     do_error "Bailing out..."
   306 fi
   307 add_to_var_list grep
   308 
   309 printf "Checking for 'sed'... "
   310 if [ -n "${sed}" ]; then
   311     printf "${sed} (cached)\n"
   312 else
   313     sed="$( which sed 2>/dev/null )"
   314     if [ -z "${sed}" ]; then
   315         printf "not found\n"
   316     else
   317         printf "${sed}\n"
   318         printf "Checking whether '${sed}' supports -i and -e... "
   319         touch .ct-ng.sed.test
   320         if "${sed}" -r -i -e 's/foo/bar/' .ct-ng.sed.test >/dev/null 2>&1; then
   321             printf "yes\n"
   322         else
   323             printf "no\n"
   324             sed=
   325         fi
   326         rm -f .ct-ng.sed.test
   327     fi
   328 fi
   329 if [ -z "${sed}" ]; then
   330     printf "Either you are missing entirely the needed tool,\n"
   331     printf "or the version you have is too old.\n"
   332     printf "You can give the path to this tool using: --with-sed=PATH\n"
   333     do_error "Bailing out..."
   334 fi
   335 add_to_var_list sed
   336 
   337 # The regular list of tools we can now easily check for
   338 has_or_abort prog=bash                              \
   339              var=bash                               \
   340              ver='^GNU bash, version (3\.[1-9]|4)'  \
   341              err="'bash' 3.1 or above was not found"
   342 has_or_abort prog=cut
   343 has_or_abort prog=install var=install
   344 has_or_abort prog=make                                  \
   345              var=make                                   \
   346              ver='^GNU Make (3.[89][[:digit:]]|[4-9])'  \
   347              err="GNU 'make' 3.80 or above was not found"
   348 has_or_abort prog=gcc
   349 has_or_abort prog="awk gawk" ver='^GNU Awk' err="GNU 'awk' was not found"
   350 has_or_abort prog=bison
   351 has_or_abort prog=flex
   352 has_or_abort prog=makeinfo
   353 has_or_abort prog=automake                                                      \
   354              ver='\(GNU automake\) (1\.[[:digit:]]{2,}|[2-9][[:digit:]]*\.)'    \
   355              err="'automake' 1.10 or above was not found"
   356 has_or_abort prog=libtool                                                                           \
   357              var=libtool                                                                            \
   358              ver='\(GNU libtool.*\) (2[[:digit:]]*\.|1\.6[[:digit:]]*\.|1\.5\.[2-9][[:digit:]]+)'   \
   359              err="'libtool' 1.5.26 or above was not found"
   360 has_or_abort prog=stat
   361 has_or_abort prog="curl wget"
   362 has_or_abort prog=cvs
   363 has_or_abort prog=patch
   364 has_or_abort prog=tar
   365 has_or_abort prog=gzip
   366 has_or_abort prog=bzip2
   367 has_or_abort prog=lzma
   368 has_or_abort prog=readlink
   369 has_or_abort prog=objcopy var=objcopy
   370 has_or_abort prog=objdump var=objdump
   371 has_or_abort prog=readelf var=readelf
   372 has_or_abort prog=patch var=patch
   373 
   374 has_or_abort inc="ncurses/ncurses.h ncurses/curses.h ncurses.h curses.h"    \
   375              err="'ncurses' headers files were not found"
   376 
   377 ncurses_libs="$( for l in ncursesw ncurses curses; do   \
   378                      for x in so a dylib; do            \
   379                          printf "lib$l.$x ";            \
   380                      done;                              \
   381                  done                                   \
   382                )"
   383 has_or_abort lib="${ncurses_libs}"                  \
   384              err="'ncurses' library was not found"
   385 
   386 #---------------------------------------------------------------------
   387 # Compute the version string
   388 
   389 # If this version is n hg clone, try to get the revision number
   390 # If we can't get the revision number, use date
   391 printf "Computing version string... "
   392 case "${VERSION}" in
   393     *+hg|hg)
   394         REVISION="$( hg id -n 2>/dev/null || true )"
   395         case "${REVISION}" in
   396             "")
   397                 VERSION="${VERSION}_unknown@$( date +%Y%m%d.%H%M%S )";;
   398             *)
   399                 VERSION="${VERSION}_$( hg id -b )@${REVISION%%+}_$( hg id -i )"
   400                 ;;
   401         esac
   402         # Arrange to have no / in the directory name, no need to create an
   403         # arbitrarily deep directory structure
   404         VERSION="$( printf "${VERSION}\n" |"${sed}" -r -e 's|/+|_|g;' )"
   405         ;;
   406 esac
   407 printf "${VERSION}\n"
   408 
   409 #---------------------------------------------------------------------
   410 # Compute and check install paths
   411 
   412 # Now we have the version string, we can build up the paths
   413 [ -z "${BINDIR_set}" ] && BINDIR="${PREFIX}/bin"
   414 [ -z "${LIBDIR_set}" ] && LIBDIR="${PREFIX}/lib"
   415 [ -z "${DOCDIR_set}" ] && DOCDIR="${PREFIX}/share/doc"
   416 [ -z "${MANDIR_set}" ] && MANDIR="${PREFIX}/share/man"
   417 
   418 # Install support files in our own sub-dir, so as not to mangle (system)
   419 # files and dirs, but only if not --local
   420 if [ -z "${LOCAL_set}" ]; then
   421     LIBDIR="${LIBDIR}/ct-ng-${VERSION}"
   422     DOCDIR="${DOCDIR}/ct-ng-${VERSION}"
   423 fi
   424 
   425 # Check that install PATHs are absolute
   426 for p in BIN LIB DOC MAN; do
   427     var="${p}DIR"
   428     eval v='"${'"${var}"'}"'
   429     case "${v}" in
   430         /*) ;;
   431         *)  do_error "'${var}' is not an absolute path: '${v}'"
   432     esac
   433 done
   434 
   435 #---------------------------------------------------------------------
   436 # That's all, folks!
   437 
   438 printf "Building up Makefile... "
   439 var_sed="$( for var_name in ${var_list}; do
   440                 eval echo 's,@@${var_name}@@,${'"${var_name}"'},g'
   441             done 
   442           )"
   443 "${sed}" -r -e "s,@@BINDIR@@,${BINDIR},g
   444                 s,@@LIBDIR@@,${LIBDIR},g
   445                 s,@@DOCDIR@@,${DOCDIR},g
   446                 s,@@MANDIR@@,${MANDIR},g
   447                 s,@@VERSION@@,${VERSION},g
   448                 s,@@DATE@@,${DATE},g
   449                 ${var_sed}
   450                 s,@@LOCAL@@,${LOCAL_set},g"  Makefile.in >Makefile
   451 echo "done"
   452 
   453 cat <<__EOF__
   454 
   455 crosstool-NG configured as follows:
   456   PREFIX='${PREFIX}'
   457   BINDIR='${BINDIR}'
   458   LIBDIR='${LIBDIR}'
   459   DOCDIR='${DOCDIR}'
   460   MANDIR='${MANDIR}'
   461 
   462 Now run:
   463   make
   464 __EOF__
   465 if [ "${LOCAL_set}" != "y" ]; then
   466     printf "  make install\n"
   467 fi