configure
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat Oct 10 16:41:12 2009 +0200 (2009-10-10)
changeset 1570 1d43b65599a4
parent 1560 79a609170a83
child 1571 2f44fac6b514
permissions -rwxr-xr-x
configure: fix --with-foo=/path/to/foo

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