configure
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Jun 28 17:25:02 2011 +0200 (2011-06-28)
changeset 2525 00054087dab2
parent 2524 cdb5c36290f4
child 2526 e5fb003a354c
permissions -rwxr-xr-x
configure: check host system

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 kconfig_list=""
    73 
    74 # This function adds a variable name to the above list of variable names.
    75 # $1: the name of the variable to add to the list
    76 add_to_var_list() {
    77     local v
    78     for v in ${var_list}; do
    79         [ "${v}" = "${1}" ] && return 0
    80     done
    81     var_list="${var_list} ${1}"
    82 }
    83 add_to_kconfig_list() {
    84     local k
    85     for k in ${kconfig_list}; do
    86         [ "${k}" = "${1}" ] && return 0
    87     done
    88     kconfig_list="${kconfig_list} ${1}"
    89 }
    90 
    91 # A function to test for required tools/headers/libraries
    92 # Return 0 (true) if found, !0 (false) if not found
    93 #
    94 # $*: [prog|inc|lib]=<name[ name...]>
    95 #     the name(s) of tool(s) to test for
    96 #     mandatory
    97 #       eg: prog=bash   prog="curl wget"
    98 # $*: var=<var_name>
    99 #     the name of the variable to test and set
   100 #     optional
   101 #       eg: var=bash    if ${bash} is set and non-null, use that,
   102 #                       else check for bash and set bash=$(which bash)
   103 # $*: ver=<regexp>
   104 #     for each 'prog', test if $(prog --version) matches 'regexp'
   105 #     optional
   106 #       eg: ver='^GNU bash, version [34]\.'
   107 # $*: err=<error_message>
   108 #     the error message to print if tool is missing
   109 #     optional, defaults to: '${prog}: none found'
   110 #       eg: err="'bash' 3.x or above was not found"
   111 #     Note: err may be printed by caller, not us
   112 # $*: kconfig=<var_name>
   113 #     the name of a variable to pass down to kconfig if
   114 #     the prog/inc/lib was found
   115 #     optional, defaults to none
   116 #       eg: kconfig=has_libncurses
   117 check_for() {
   118     local val
   119     local item
   120     local where
   121     local status
   122 
   123     # Note: prog/inc/lib and var/kconfig/ver/err are set here,
   124     # but declared by the caller (because it needs it)
   125     for item in "${@}"; do
   126         case "${item}" in
   127             prog=*|inc=*|lib=*|var=*|ver=*|err=*|kconfig=*)
   128                 eval ${item%%=*}=\"${item#*=}\"
   129                 ;;
   130             *)  do_error "check_for: incorrect parameters: '$@'";;
   131         esac
   132     done
   133 
   134     case "${prog}:${inc}:${lib}" in
   135         ?*:?*:|?*::?*|:?*:?*|?*:?*:?*)
   136             if [ -n "${var}" ]; then
   137                 do_error "check_for: the use of var is not compatible with passing several of [prog|inc|lib] at once"
   138             fi
   139             ;;
   140         ::) do_error "check_for: [prog|inc|lib] is mandatory";;
   141     esac
   142 
   143     if [ -n "${kconfig}" ]; then
   144         add_to_kconfig_list "${kconfig}"
   145     fi
   146 
   147     if [ -n "${prog}" ]; then
   148         for item in ${prog}; do
   149             printf "Checking for '${item}'... "
   150             if [ -n "${var}" ]; then
   151                 eval val="\${${var}}"
   152                 if [ -n "${val}" ]; then
   153                     printf "${val} (cached)\n"
   154                     add_to_var_list "${var}"
   155                     return 0
   156                 fi
   157             fi
   158             where="$( which "${item}" 2>/dev/null )"
   159             if [ -z "${where}" ]; then
   160                 printf "no\n"
   161                 continue
   162             elif [ -n "${ver}" ]; then
   163                 str=$( LC_ALL=C "${where}" --version 2>&1   \
   164                        |grep -E "${ver}"                    \
   165                        |head -n 1
   166                      )
   167                 if [ -z "${str}" ]; then
   168                     printf "no\n"
   169                     unset where
   170                     continue
   171                 fi
   172             fi
   173             status="${where}"
   174             break
   175         done
   176         if [ -z "${status}" ]; then
   177             return 1
   178         fi
   179         printf "${status}\n"
   180         unset status
   181     fi
   182 
   183     if [ -n "${inc}" ]; then
   184         for item in ${inc}; do
   185             printf "Checking for '${item}'... "
   186             if printf "#include \"${item}\"" |gcc -x c -c - -o /dev/null >/dev/null 2>&1; then
   187                 where="${item}"
   188                 status=yes
   189                 break;
   190             fi
   191             printf "no\n"
   192         done
   193         if [ -z "${status}" ]; then
   194             return 1
   195         fi
   196         printf "${status}\n"
   197         unset status
   198     fi
   199 
   200     if [ -n "${lib}" ]; then
   201         for item in ${lib}; do
   202             printf "Checking for '${item}'... "
   203             where="$( gcc -print-file-name="${item}" )"
   204             if [ "${where}" != "${item}" ]; then
   205                 where="$( readlink "${where}" )"
   206                 status=yes
   207                 break;
   208             fi
   209             printf "no\n"
   210         done
   211         if [ -z "${status}" ]; then
   212             return 1
   213         fi
   214         printf "${status}\n"
   215         unset status
   216     fi
   217 
   218     if [ -n "${var}" ]; then
   219         eval ${var}='"'"${where}"'"'
   220         add_to_var_list "${var}"
   221     fi
   222     if [ -n "${kconfig}" ]; then
   223         eval ${kconfig}=y
   224     fi
   225 }
   226 
   227 # This function checks for a tool, and aborts if not found
   228 # See check_for(), above, for how to call has_or_abort
   229 has_or_abort() {
   230     # We declare these 6 variables here, although they are
   231     # set in check_for(), called below
   232     local prog inc lib
   233     local var ver err kconfig
   234 
   235     if ! check_for "$@"; then
   236         printf " * A mandatory dependency is missing, or version mis-match:\n"
   237         printf " * - ${err:-${prog}${inc}${lib}: none found}\n"
   238         if [ -n "${var}" ]; then
   239             printf " * --> You can give the path to this tool using: --with-${var}=PATH\n"
   240         fi
   241         printf "\n"
   242         # Bail out if --force is not specified
   243         [ -z "${FORCE}" ] && do_error "Bailing out..."
   244         printf "<*                                          *>\n"
   245         printf "<*            FORCE in action:              *>\n"
   246         printf "<* Continuing despite missing pre-requisite *>\n"
   247         printf "<*          Prepare for breakage            *>\n"
   248         printf "<*                                          *>\n"
   249         printf "\n"
   250     fi
   251 }
   252 
   253 # This function checks for a tool, and warns if not found
   254 # See check_for(), above, for how to call has_or_abort
   255 # Note: if err is not set, then no error message is printed
   256 has_or_warn() {
   257     # We declare these 6 variables here, although they are
   258     # set in check_for(), called below
   259     local prog inc lib
   260     local var ver err kconfig
   261 
   262     if ! check_for "$@"; then
   263         printf " * An optional dependency is missing, some features will be disabled"
   264         printf "${err:+:\n * - ${err}}\n"
   265         if [ -n "${var}" ]; then
   266             printf " * --> You can give the path to this tool using: --with-${var}=PATH\n"
   267         fi
   268     fi
   269 }
   270 
   271 do_help() {
   272     cat <<__EOF__
   273 \`configure' configures crosstool-NG-${VERSION} to adapt to many kind of systems.
   274 
   275 USAGE: ./configure [OPTION]...
   276 
   277 Defaults for the options are specified in brackets.
   278 
   279 Configuration:
   280   -h, --help              display this help and exit
   281       --force             force configure to continue, even in case
   282                           some pre-requisites are missing
   283 
   284 Installation directories:
   285   --prefix=PREFIX         install files in PREFIX [${PREFIX_DEFAULT}]
   286   --local                 don't install, and use current directory
   287 
   288 By default, \`make install' will install all the files in
   289 \`${PREFIX_DEFAULT}/bin', \`${PREFIX_DEFAULT}/lib' etc.  You can specify
   290 an installation prefix other than \`${PREFIX_DEFAULT}' using \`--prefix',
   291 for instance \`--prefix=\${HOME}'.
   292 
   293 For better control, use the options below.
   294 
   295 Fine tuning of the installation directories:
   296   --bindir=DIR            user executables [PREFIX/bin]
   297   --libdir=DIR            object code libraries [PREFIX/lib]
   298   --docdir=DIR            info documentation [PREFIX/share/doc]
   299   --mandir=DIR            man documentation [PREFIX/share/man]
   300 
   301 Optional Features:
   302   --with-install=PATH     Specify the full PATH to GNU install
   303   --with-make=PATH        Specify the full PATH to GNU make >= 3.80
   304   --with-grep=PATH        Specify the full PATH to GNU grep
   305   --with-sed=PATH         Specify the full PATH to GNU sed
   306   --with-bash=PATH        Specify the full PATH to bash >= 3.0
   307 __EOF__
   308 }
   309 
   310 #---------------------------------------------------------------------
   311 # Set user's options
   312 
   313 while [ $# -ne 0 ]; do
   314     case "$1" in
   315         --local)    LOCAL_set="y"; shift;;
   316         --prefix*)  set_prefix "$1" "$2" && shift || shift 2;;
   317         --bindir*)  set_bindir "$1" "$2" && shift || shift 2;;
   318         --libdir*)  set_libdir "$1" "$2" && shift || shift 2;;
   319         --docdir*)  set_docdir "$1" "$2" && shift || shift 2;;
   320         --mandir*)  set_mandir "$1" "$2" && shift || shift 2;;
   321         --with-*)   set_tool   "$1" "$2" && shift || shift 2;;
   322         --force)    FORCE=1; shift;;
   323         --help|-h)  do_help; exit 0;;
   324         # Skip, auto-stuff compatibility
   325         --build=*|--host=*|--infodir=*|--datadir=*|--sysconfdir=*|--localstatedir=*) shift;;
   326         --build|--host|--infodir|--datadir|--sysconfdir|--localstatedir)             shift 2;;
   327         *)          printf "Unrecognised option: '${1}'\n"; do_help; exit 1;;
   328     esac
   329 done
   330 
   331 # Use defaults
   332 [ -z "${PREFIX}" ] && set_prefix "" "${PREFIX_DEFAULT}"
   333 
   334 # Special case when installing locally
   335 if [ "${LOCAL_set}" = "y" ]; then
   336     set_prefix "" "$( pwd )"
   337     set_bindir "" "$( pwd )"
   338     set_libdir "" "$( pwd )"
   339     set_docdir "" "$( pwd )/docs"
   340     set_mandir "" "$( pwd )/docs"
   341 fi
   342 
   343 #---------------------------------------------------------------------
   344 # Some sanity checks, now
   345 
   346 # We check for grep and sed manually, because they are used in check_for()
   347 printf "Checking for 'grep'... "
   348 if [ -n "${grep}" ]; then
   349     printf "${grep} (cached)\n"
   350 else
   351     grep="$( which grep 2>/dev/null )"
   352     if [ -z "${grep}" ]; then
   353         printf "not found\n"
   354     else
   355         printf "${grep}\n"
   356         printf "Checking whether '${grep}' supports -E... "
   357         if echo 'foo' |"${grep}" -E 'foo' >/dev/null 2>&1; then
   358             printf "yes\n"
   359         else
   360             printf "no\n"
   361             grep=
   362         fi
   363     fi
   364 fi
   365 if [ -z "${grep}" ]; then
   366     printf "Either you are missing entirely the needed tool,\n"
   367     printf "or the version you have is too old.\n"
   368     printf "You can give the path to this tool using: --with-grep=PATH\n"
   369     do_error "Bailing out..."
   370 fi
   371 add_to_var_list grep
   372 
   373 printf "Checking for 'sed'... "
   374 if [ -n "${sed}" ]; then
   375     printf "${sed} (cached)\n"
   376 else
   377     sed="$( which sed 2>/dev/null )"
   378     if [ -z "${sed}" ]; then
   379         printf "not found\n"
   380     else
   381         printf "${sed}\n"
   382         printf "Checking whether '${sed}' supports -i and -e... "
   383         touch .ct-ng.sed.test
   384         if "${sed}" -r -i -e 's/foo/bar/' .ct-ng.sed.test >/dev/null 2>&1; then
   385             printf "yes\n"
   386         else
   387             printf "no\n"
   388             sed=
   389         fi
   390         rm -f .ct-ng.sed.test
   391     fi
   392 fi
   393 if [ -z "${sed}" ]; then
   394     printf "Either you are missing entirely the needed tool,\n"
   395     printf "or the version you have is too old.\n"
   396     printf "You can give the path to this tool using: --with-sed=PATH\n"
   397     do_error "Bailing out..."
   398 fi
   399 add_to_var_list sed
   400 
   401 # The regular list of tools we can now easily check for
   402 has_or_abort prog=bash                              \
   403              var=bash                               \
   404              ver='^GNU bash, version (3\.[1-9]|4)'  \
   405              err="'bash' 3.1 or above was not found"
   406 has_or_abort prog=cut
   407 has_or_abort prog=install var=install
   408 has_or_abort prog=make                                  \
   409              var=make                                   \
   410              ver='^GNU Make (3.[89][[:digit:]]|[4-9])'  \
   411              err="GNU 'make' 3.80 or above was not found"
   412 has_or_abort prog=gcc
   413 has_or_abort prog="awk gawk" ver='^GNU Awk' err="GNU 'awk' was not found"
   414 has_or_abort prog=bison
   415 has_or_abort prog=flex
   416 has_or_abort prog=makeinfo
   417 has_or_abort prog=automake                                                      \
   418              ver='\(GNU automake\) (1\.[[:digit:]]{2,}|[2-9][[:digit:]]*\.)'    \
   419              err="'automake' 1.10 or above was not found"
   420 has_or_abort prog=libtool                                                                           \
   421              var=libtool                                                                            \
   422              ver='\(GNU libtool.*\) (2[[:digit:]]*\.|1\.6[[:digit:]]*\.|1\.5\.[2-9][[:digit:]]+)'   \
   423              err="'libtool' 1.5.26 or above was not found"
   424 has_or_abort prog=stat
   425 has_or_abort prog="curl wget"
   426 has_or_abort prog=cvs
   427 has_or_abort prog=patch
   428 has_or_abort prog=tar
   429 has_or_abort prog=gzip
   430 has_or_abort prog=bzip2
   431 has_or_abort prog=lzma
   432 has_or_abort prog=readlink
   433 has_or_abort prog=objcopy var=objcopy
   434 has_or_abort prog=objdump var=objdump
   435 has_or_abort prog=readelf var=readelf
   436 has_or_abort prog=patch var=patch
   437 
   438 # Host system checks
   439 
   440 printf "Checking for host system... "
   441 host="$( uname -s )"
   442 printf "%s\n" "${host}"
   443 case "${host}" in
   444     Linux)  ;;
   445     Cygwin) ;;
   446     *)
   447         printf " * Runing under %s is not fully tested\n" "${host}"
   448         printf " * You may encounter some weird behavior\n"
   449         ;;
   450 esac
   451 
   452 ncurses_hdrs="ncurses/ncurses.h ncurses/curses.h ncurses.h curses.h"
   453 ncurses_libs="$( for l in ncursesw ncurses curses; do   \
   454                      for x in so a dylib; do            \
   455                          printf "lib$l.$x ";            \
   456                      done;                              \
   457                  done                                   \
   458                )"
   459 has_or_abort lib="${ncurses_libs}"                                          \
   460              inc="${ncurses_hdrs}"                                          \
   461              err="The 'ncurses' library is needed fo the menuconfig frontend"
   462 
   463 stdcxx_libs="$( for x in so dylib a; do \
   464                    printf "libstdc++.$x "; \
   465                done \
   466              )"
   467 has_or_abort lib="${stdcxx_libs}" \
   468              err="The 'libstdc++' library is needed to build gcc"
   469 
   470 # Yes, we may be checking twice for libstdc++.a
   471 # The first is because we need one instance of libstdc++ (shared or static)
   472 # because it is needed for PPL; the second is because the static version is
   473 # required for static-linking, and if missing, the option is removed.
   474 has_or_warn  lib="libstdc++.a" \
   475              err="static 'libstdc++' is needed to statically link the toolchain's executables" \
   476              kconfig=has_static_libstdcxx
   477 
   478 expat_libs="$( for x in so dylib a; do \
   479                    printf "libexpat.$x "; \
   480                done \
   481              )"
   482 has_or_warn  inc="expat.h" \
   483              lib="${expat_libs}" \
   484              err="The 'expat' header file and library are needed to link cross-gdb's executables" \
   485              kconfig=has_expat
   486 
   487 # Yes, we may be checking twice for libexpat.a
   488 # The first is because we need one instance of libexpat (shared or static)
   489 # because it is needed for cross-gdb; the second is because the static version
   490 # is required for static-linking, and if missing, the option is removed.
   491 has_or_warn  lib="libexpat.a" \
   492              err="static 'expat' is needed to statically link cross-gdb's executables" \
   493              kconfig=has_static_expat
   494 
   495 for v in 7 6 5 4; do
   496     python_incs="${python_incs}$( printf "python2.$v/Python.h " )"
   497     python_libs="${python_libs}$( for x in so dylib a; do \
   498                                       printf "libpython2.$v.$x "; \
   499                                   done \
   500                                 )"
   501 done
   502 has_or_warn  inc="${python_incs}" \
   503              lib="${python_libs}" \
   504              err="The 'python' header file and library are needed for some features of cross-gdb"
   505 
   506 #---------------------------------------------------------------------
   507 # Compute the version string
   508 
   509 # If this version is n hg clone, try to get the revision number
   510 # If we can't get the revision number, use date
   511 printf "\nComputing version string... "
   512 case "${VERSION}" in
   513     *+hg|hg)
   514         REVISION="$( hg id -n 2>/dev/null || true )"
   515         case "${REVISION}" in
   516             "")
   517                 VERSION="${VERSION}_unknown@$( date +%Y%m%d.%H%M%S )";;
   518             *)
   519                 VERSION="${VERSION}_$( hg id -b )@${REVISION%%+}_$( hg id -i )"
   520                 ;;
   521         esac
   522         # Arrange to have no / in the directory name, no need to create an
   523         # arbitrarily deep directory structure
   524         VERSION="$( printf "${VERSION}\n" |"${sed}" -r -e 's|/+|_|g;' )"
   525         ;;
   526 esac
   527 printf "${VERSION}\n"
   528 
   529 #---------------------------------------------------------------------
   530 # Compute and check install paths
   531 
   532 # Now we have the version string, we can build up the paths
   533 [ -z "${BINDIR_set}" ] && BINDIR="${PREFIX}/bin"
   534 [ -z "${LIBDIR_set}" ] && LIBDIR="${PREFIX}/lib"
   535 [ -z "${DOCDIR_set}" ] && DOCDIR="${PREFIX}/share/doc"
   536 [ -z "${MANDIR_set}" ] && MANDIR="${PREFIX}/share/man"
   537 
   538 # Install support files in our own sub-dir, so as not to mangle (system)
   539 # files and dirs, but only if not --local
   540 if [ -z "${LOCAL_set}" ]; then
   541     LIBDIR="${LIBDIR}/ct-ng-${VERSION}"
   542     DOCDIR="${DOCDIR}/ct-ng-${VERSION}"
   543 fi
   544 
   545 # Check that install PATHs are absolute
   546 for p in BIN LIB DOC MAN; do
   547     var="${p}DIR"
   548     eval v='"${'"${var}"'}"'
   549     case "${v}" in
   550         /*) ;;
   551         *)  do_error "'${var}' is not an absolute path: '${v}'"
   552     esac
   553 done
   554 
   555 #---------------------------------------------------------------------
   556 # That's all, folks!
   557 
   558 printf "Building up Makefile... "
   559 var_sed="$( for var_name in ${var_list}; do
   560                 eval echo 's,@@${var_name}@@,${'"${var_name}"'},g'
   561             done
   562           )"
   563 kconfig_sed="s/@@KCONFIG@@/$( for k_name in ${kconfig_list}; do
   564                                   eval printf \"${k_name}=\${${k_name}} \"
   565                               done
   566                             )/"
   567 "${sed}" -r -e "s,@@BINDIR@@,${BINDIR},g"       \
   568             -e "s,@@LIBDIR@@,${LIBDIR},g"       \
   569             -e "s,@@DOCDIR@@,${DOCDIR},g"       \
   570             -e "s,@@MANDIR@@,${MANDIR},g"       \
   571             -e "s,@@VERSION@@,${VERSION},g"     \
   572             -e "s,@@DATE@@,${DATE},g"           \
   573             -e "s,@@LOCAL@@,${LOCAL_set},g"     \
   574             -e "${var_sed}"                     \
   575             -e "${kconfig_sed}"                 \
   576          Makefile.in                            \
   577          >Makefile
   578 echo "done"
   579 
   580 cat <<__EOF__
   581 
   582 crosstool-NG configured as follows:
   583   PREFIX='${PREFIX}'
   584   BINDIR='${BINDIR}'
   585   LIBDIR='${LIBDIR}'
   586   DOCDIR='${DOCDIR}'
   587   MANDIR='${MANDIR}'
   588 
   589 Now run:
   590   make
   591 __EOF__
   592 if [ "${LOCAL_set}" != "y" ]; then
   593     printf "  make install\n"
   594 fi