configure
author Arnaud Vrac <avrac@freebox.fr>
Fri Oct 09 16:22:09 2009 +0200 (2009-10-09)
changeset 1569 a4e30d311569
parent 1485 d031a67fc494
child 1570 1d43b65599a4
child 1576 906b7509835e
permissions -rwxr-xr-x
eglibc: add support for user provided option groups

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