configure
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Thu May 26 18:40:53 2011 +0200 (2011-05-26)
changeset 2479 bce8b2a4bf8f
parent 2203 ac3e215141a1
child 2480 b2591fe701ef
permissions -rwxr-xr-x
configure: move error message down to has_or_abort

When has_or_warn will come, we do want to print the error message
only in has_or_abort, so move it down there.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     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 val
   101     local item
   102     local where
   103     local status
   104 
   105     # Note: prog/inc/lib and var/ver/err are set here,
   106     # but declared by the caller (because it needs it)
   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         return 1
   174     fi
   175 
   176     printf "${status}"
   177     if [ -n "${var}" ]; then
   178         eval ${var}='"'"${where}"'"'
   179         add_to_var_list "${var}"
   180     fi
   181     printf "\n"
   182 }
   183 
   184 # This function checks for a tool, and aborts if not found
   185 # See check_for(), above, for how to call has_or_abort
   186 has_or_abort() {
   187     # We declare these 6 variables here, although they are
   188     # set in check_for(), called below
   189     local prog inc lib
   190     local var ver err
   191 
   192     if ! check_for "$@"; then
   193         printf "\n${err:-${prog}${inc}${lib}: none found}\n\n"
   194         printf "Either you are missing entirely the needed tool,\n"
   195         printf "or the version you have is too old.\n"
   196         if [ -n "${var}" ]; then
   197             printf "You can give the path to this tool using: --with-${var}=PATH\n"
   198         fi
   199         printf "\n"
   200         # Bail out if --force is not specified
   201         [ -z "${FORCE}" ] && do_error "Bailing out..."
   202         printf "<*                                          *>\n"
   203         printf "<*            FORCE in action:              *>\n"
   204         printf "<* Continuing despite missing pre-requisite *>\n"
   205         printf "<*          Prepare for breakage            *>\n"
   206         printf "<*                                          *>\n"
   207         printf "\n"
   208     fi
   209 }
   210 
   211 do_help() {
   212     cat <<__EOF__
   213 \`configure' configures crosstool-NG-${VERSION} to adapt to many kind of systems.
   214 
   215 USAGE: ./configure [OPTION]...
   216 
   217 Defaults for the options are specified in brackets.
   218 
   219 Configuration:
   220   -h, --help              display this help and exit
   221       --force             force configure to continue, even in case
   222                           some pre-requisites are missing
   223 
   224 Installation directories:
   225   --prefix=PREFIX         install files in PREFIX [${PREFIX_DEFAULT}]
   226   --local                 don't install, and use current directory
   227 
   228 By default, \`make install' will install all the files in
   229 \`${PREFIX_DEFAULT}/bin', \`${PREFIX_DEFAULT}/lib' etc.  You can specify
   230 an installation prefix other than \`${PREFIX_DEFAULT}' using \`--prefix',
   231 for instance \`--prefix=\${HOME}'.
   232 
   233 For better control, use the options below.
   234 
   235 Fine tuning of the installation directories:
   236   --bindir=DIR            user executables [PREFIX/bin]
   237   --libdir=DIR            object code libraries [PREFIX/lib]
   238   --docdir=DIR            info documentation [PREFIX/share/doc]
   239   --mandir=DIR            man documentation [PREFIX/share/man]
   240 
   241 Optional Features:
   242   --with-install=PATH     Specify the full PATH to GNU install
   243   --with-make=PATH        Specify the full PATH to GNU make >= 3.80
   244   --with-grep=PATH        Specify the full PATH to GNU grep
   245   --with-sed=PATH         Specify the full PATH to GNU sed
   246   --with-bash=PATH        Specify the full PATH to bash >= 3.0
   247 __EOF__
   248 }
   249 
   250 #---------------------------------------------------------------------
   251 # Set user's options
   252 
   253 while [ $# -ne 0 ]; do
   254     case "$1" in
   255         --local)    LOCAL_set="y"; shift;;
   256         --prefix*)  set_prefix "$1" "$2" && shift || shift 2;;
   257         --bindir*)  set_bindir "$1" "$2" && shift || shift 2;;
   258         --libdir*)  set_libdir "$1" "$2" && shift || shift 2;;
   259         --docdir*)  set_docdir "$1" "$2" && shift || shift 2;;
   260         --mandir*)  set_mandir "$1" "$2" && shift || shift 2;;
   261         --with-*)   set_tool   "$1" "$2" && shift || shift 2;;
   262         --force)    FORCE=1; shift;;
   263         --help|-h)  do_help; exit 0;;
   264         # Skip, auto-stuff compatibility
   265         --build=*|--host=*|--infodir=*|--datadir=*|--sysconfdir=*|--localstatedir=*) shift;;
   266         --build|--host|--infodir|--datadir|--sysconfdir|--localstatedir)             shift 2;;
   267         *)          printf "Unrecognised option: '${1}'\n"; do_help; exit 1;;
   268     esac
   269 done
   270 
   271 # Use defaults
   272 [ -z "${PREFIX}" ] && set_prefix "" "${PREFIX_DEFAULT}"
   273 
   274 # Special case when installing locally
   275 if [ "${LOCAL_set}" = "y" ]; then
   276     set_prefix "" "$( pwd )"
   277     set_bindir "" "$( pwd )"
   278     set_libdir "" "$( pwd )"
   279     set_docdir "" "$( pwd )/docs"
   280     set_mandir "" "$( pwd )/docs"
   281 fi
   282 
   283 #---------------------------------------------------------------------
   284 # Some sanity checks, now
   285 
   286 # We check for grep and sed manually, because they are used in check_for()
   287 printf "Checking for 'grep'... "
   288 if [ -n "${grep}" ]; then
   289     printf "${grep} (cached)\n"
   290 else
   291     grep="$( which grep 2>/dev/null )"
   292     if [ -z "${grep}" ]; then
   293         printf "not found\n"
   294     else
   295         printf "${grep}\n"
   296         printf "Checking whether '${grep}' supports -E... "
   297         if echo 'foo' |"${grep}" -E 'foo' >/dev/null 2>&1; then
   298             printf "yes\n"
   299         else
   300             printf "no\n"
   301             grep=
   302         fi
   303     fi
   304 fi
   305 if [ -z "${grep}" ]; then
   306     printf "Either you are missing entirely the needed tool,\n"
   307     printf "or the version you have is too old.\n"
   308     printf "You can give the path to this tool using: --with-grep=PATH\n"
   309     do_error "Bailing out..."
   310 fi
   311 add_to_var_list grep
   312 
   313 printf "Checking for 'sed'... "
   314 if [ -n "${sed}" ]; then
   315     printf "${sed} (cached)\n"
   316 else
   317     sed="$( which sed 2>/dev/null )"
   318     if [ -z "${sed}" ]; then
   319         printf "not found\n"
   320     else
   321         printf "${sed}\n"
   322         printf "Checking whether '${sed}' supports -i and -e... "
   323         touch .ct-ng.sed.test
   324         if "${sed}" -r -i -e 's/foo/bar/' .ct-ng.sed.test >/dev/null 2>&1; then
   325             printf "yes\n"
   326         else
   327             printf "no\n"
   328             sed=
   329         fi
   330         rm -f .ct-ng.sed.test
   331     fi
   332 fi
   333 if [ -z "${sed}" ]; then
   334     printf "Either you are missing entirely the needed tool,\n"
   335     printf "or the version you have is too old.\n"
   336     printf "You can give the path to this tool using: --with-sed=PATH\n"
   337     do_error "Bailing out..."
   338 fi
   339 add_to_var_list sed
   340 
   341 # The regular list of tools we can now easily check for
   342 has_or_abort prog=bash                              \
   343              var=bash                               \
   344              ver='^GNU bash, version (3\.[1-9]|4)'  \
   345              err="'bash' 3.1 or above was not found"
   346 has_or_abort prog=cut
   347 has_or_abort prog=install var=install
   348 has_or_abort prog=make                                  \
   349              var=make                                   \
   350              ver='^GNU Make (3.[89][[:digit:]]|[4-9])'  \
   351              err="GNU 'make' 3.80 or above was not found"
   352 has_or_abort prog=gcc
   353 has_or_abort prog="awk gawk" ver='^GNU Awk' err="GNU 'awk' was not found"
   354 has_or_abort prog=bison
   355 has_or_abort prog=flex
   356 has_or_abort prog=makeinfo
   357 has_or_abort prog=automake                                                      \
   358              ver='\(GNU automake\) (1\.[[:digit:]]{2,}|[2-9][[:digit:]]*\.)'    \
   359              err="'automake' 1.10 or above was not found"
   360 has_or_abort prog=libtool                                                                           \
   361              var=libtool                                                                            \
   362              ver='\(GNU libtool.*\) (2[[:digit:]]*\.|1\.6[[:digit:]]*\.|1\.5\.[2-9][[:digit:]]+)'   \
   363              err="'libtool' 1.5.26 or above was not found"
   364 has_or_abort prog=stat
   365 has_or_abort prog="curl wget"
   366 has_or_abort prog=cvs
   367 has_or_abort prog=patch
   368 has_or_abort prog=tar
   369 has_or_abort prog=gzip
   370 has_or_abort prog=bzip2
   371 has_or_abort prog=lzma
   372 has_or_abort prog=readlink
   373 has_or_abort prog=objcopy var=objcopy
   374 has_or_abort prog=objdump var=objdump
   375 has_or_abort prog=readelf var=readelf
   376 has_or_abort prog=patch var=patch
   377 
   378 has_or_abort inc="ncurses/ncurses.h ncurses/curses.h ncurses.h curses.h"    \
   379              err="'ncurses' headers files were not found"
   380 
   381 ncurses_libs="$( for l in ncursesw ncurses curses; do   \
   382                      for x in so a dylib; do            \
   383                          printf "lib$l.$x ";            \
   384                      done;                              \
   385                  done                                   \
   386                )"
   387 has_or_abort lib="${ncurses_libs}"                  \
   388              err="'ncurses' library was not found"
   389 
   390 #---------------------------------------------------------------------
   391 # Compute the version string
   392 
   393 # If this version is n hg clone, try to get the revision number
   394 # If we can't get the revision number, use date
   395 printf "Computing version string... "
   396 case "${VERSION}" in
   397     *+hg|hg)
   398         REVISION="$( hg id -n 2>/dev/null || true )"
   399         case "${REVISION}" in
   400             "")
   401                 VERSION="${VERSION}_unknown@$( date +%Y%m%d.%H%M%S )";;
   402             *)
   403                 VERSION="${VERSION}_$( hg id -b )@${REVISION%%+}_$( hg id -i )"
   404                 ;;
   405         esac
   406         # Arrange to have no / in the directory name, no need to create an
   407         # arbitrarily deep directory structure
   408         VERSION="$( printf "${VERSION}\n" |"${sed}" -r -e 's|/+|_|g;' )"
   409         ;;
   410 esac
   411 printf "${VERSION}\n"
   412 
   413 #---------------------------------------------------------------------
   414 # Compute and check install paths
   415 
   416 # Now we have the version string, we can build up the paths
   417 [ -z "${BINDIR_set}" ] && BINDIR="${PREFIX}/bin"
   418 [ -z "${LIBDIR_set}" ] && LIBDIR="${PREFIX}/lib"
   419 [ -z "${DOCDIR_set}" ] && DOCDIR="${PREFIX}/share/doc"
   420 [ -z "${MANDIR_set}" ] && MANDIR="${PREFIX}/share/man"
   421 
   422 # Install support files in our own sub-dir, so as not to mangle (system)
   423 # files and dirs, but only if not --local
   424 if [ -z "${LOCAL_set}" ]; then
   425     LIBDIR="${LIBDIR}/ct-ng-${VERSION}"
   426     DOCDIR="${DOCDIR}/ct-ng-${VERSION}"
   427 fi
   428 
   429 # Check that install PATHs are absolute
   430 for p in BIN LIB DOC MAN; do
   431     var="${p}DIR"
   432     eval v='"${'"${var}"'}"'
   433     case "${v}" in
   434         /*) ;;
   435         *)  do_error "'${var}' is not an absolute path: '${v}'"
   436     esac
   437 done
   438 
   439 #---------------------------------------------------------------------
   440 # That's all, folks!
   441 
   442 printf "Building up Makefile... "
   443 var_sed="$( for var_name in ${var_list}; do
   444                 eval echo 's,@@${var_name}@@,${'"${var_name}"'},g'
   445             done 
   446           )"
   447 "${sed}" -r -e "s,@@BINDIR@@,${BINDIR},g
   448                 s,@@LIBDIR@@,${LIBDIR},g
   449                 s,@@DOCDIR@@,${DOCDIR},g
   450                 s,@@MANDIR@@,${MANDIR},g
   451                 s,@@VERSION@@,${VERSION},g
   452                 s,@@DATE@@,${DATE},g
   453                 ${var_sed}
   454                 s,@@LOCAL@@,${LOCAL_set},g"  Makefile.in >Makefile
   455 echo "done"
   456 
   457 cat <<__EOF__
   458 
   459 crosstool-NG configured as follows:
   460   PREFIX='${PREFIX}'
   461   BINDIR='${BINDIR}'
   462   LIBDIR='${LIBDIR}'
   463   DOCDIR='${DOCDIR}'
   464   MANDIR='${MANDIR}'
   465 
   466 Now run:
   467   make
   468 __EOF__
   469 if [ "${LOCAL_set}" != "y" ]; then
   470     printf "  make install\n"
   471 fi