configure
author "Benoît THÉBAUDEAU" <benoit.thebaudeau@advansee.com>
Wed Jun 08 15:47:43 2011 +0200 (2011-06-08)
changeset 2508 9e2761e59a75
parent 2507 a5856225d851
child 2509 45a4393fa357
permissions -rwxr-xr-x
debug/cross-gdb: check host dependencies

Cross-gdb depends on expat and python. If either is missing, cross-gdb will
build successfully, but lacking some features.

Especially, if expat is missing, cross-gdb will be unable to parse the target
description, which may lead to runtime malfunctions and the following GDB
warning:
"Can not parse XML target description; XML support was disabled at compile time"

Hence, expat should be considered mandatory.

On the other hand, the features missing without python are not critical, so
python should not be considered mandatory.

This patch does the following:
- At configure time, warn the user if either expat or python is missing.
- In menuconfig, disable the static build options regarding cross-gdb if no
static version of expat is available, and disable cross-gdb if expat is
missing.

Signed-off-by: "Benoît THÉBAUDEAU" <benoit.thebaudeau@advansee.com>
[yann.morin.1998@anciens.enib.fr: add comment for impossible static cross-gdb]
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\n"
   264         printf "${err:+ * ${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 has_or_abort inc="ncurses/ncurses.h ncurses/curses.h ncurses.h curses.h"    \
   439              err="'ncurses' headers files were not found"
   440 
   441 ncurses_libs="$( for l in ncursesw ncurses curses; do   \
   442                      for x in so a dylib; do            \
   443                          printf "lib$l.$x ";            \
   444                      done;                              \
   445                  done                                   \
   446                )"
   447 has_or_abort lib="${ncurses_libs}"                  \
   448              err="The 'ncurses' library is needed fo the menuconfig frontend"
   449 
   450 stdcxx_libs="$( for x in so dylib a; do \
   451                    printf "libstdc++.$x "; \
   452                done \
   453              )"
   454 has_or_abort lib="${stdcxx_libs}" \
   455              err="The 'libstdc++' library is needed to build gcc"
   456 
   457 # Yes, we may be checking twice for libstdc++.a
   458 # The first is because we need one instance of libstdc++ (shared or static)
   459 # because it is needed for PPL; the second is because the static version is
   460 # required for static-linking, and if missing, the option is removed.
   461 has_or_warn  lib="libstdc++.a" \
   462              err="static 'libstdc++' is needed to statically link the toolchain's executables" \
   463              kconfig=has_static_libstdcxx
   464 
   465 expat_libs="$( for x in so dylib a; do \
   466                    printf "libexpat.$x "; \
   467                done \
   468              )"
   469 has_or_warn  inc="expat.h" \
   470              lib="${expat_libs}" \
   471              err="The 'expat' header file and library are needed to link cross-gdb's executables" \
   472              kconfig=has_expat
   473 
   474 # Yes, we may be checking twice for libexpat.a
   475 # The first is because we need one instance of libexpat (shared or static)
   476 # because it is needed for cross-gdb; the second is because the static version
   477 # is required for static-linking, and if missing, the option is removed.
   478 has_or_warn  lib="libexpat.a" \
   479              err="static 'expat' is needed to statically link cross-gdb's executables" \
   480              kconfig=has_static_expat
   481 
   482 for v in 7 6 5 4; do
   483     python_incs="${python_incs}$( printf "python2.$v/Python.h " )"
   484     python_libs="${python_libs}$( for x in so dylib a; do \
   485                                       printf "libpython2.$v.$x "; \
   486                                   done \
   487                                 )"
   488 done
   489 has_or_warn  inc="${python_incs}" \
   490              lib="${python_libs}" \
   491              err="The 'python' header file and library are needed for some features of cross-gdb"
   492 
   493 #---------------------------------------------------------------------
   494 # Compute the version string
   495 
   496 # If this version is n hg clone, try to get the revision number
   497 # If we can't get the revision number, use date
   498 printf "\nComputing version string... "
   499 case "${VERSION}" in
   500     *+hg|hg)
   501         REVISION="$( hg id -n 2>/dev/null || true )"
   502         case "${REVISION}" in
   503             "")
   504                 VERSION="${VERSION}_unknown@$( date +%Y%m%d.%H%M%S )";;
   505             *)
   506                 VERSION="${VERSION}_$( hg id -b )@${REVISION%%+}_$( hg id -i )"
   507                 ;;
   508         esac
   509         # Arrange to have no / in the directory name, no need to create an
   510         # arbitrarily deep directory structure
   511         VERSION="$( printf "${VERSION}\n" |"${sed}" -r -e 's|/+|_|g;' )"
   512         ;;
   513 esac
   514 printf "${VERSION}\n"
   515 
   516 #---------------------------------------------------------------------
   517 # Compute and check install paths
   518 
   519 # Now we have the version string, we can build up the paths
   520 [ -z "${BINDIR_set}" ] && BINDIR="${PREFIX}/bin"
   521 [ -z "${LIBDIR_set}" ] && LIBDIR="${PREFIX}/lib"
   522 [ -z "${DOCDIR_set}" ] && DOCDIR="${PREFIX}/share/doc"
   523 [ -z "${MANDIR_set}" ] && MANDIR="${PREFIX}/share/man"
   524 
   525 # Install support files in our own sub-dir, so as not to mangle (system)
   526 # files and dirs, but only if not --local
   527 if [ -z "${LOCAL_set}" ]; then
   528     LIBDIR="${LIBDIR}/ct-ng-${VERSION}"
   529     DOCDIR="${DOCDIR}/ct-ng-${VERSION}"
   530 fi
   531 
   532 # Check that install PATHs are absolute
   533 for p in BIN LIB DOC MAN; do
   534     var="${p}DIR"
   535     eval v='"${'"${var}"'}"'
   536     case "${v}" in
   537         /*) ;;
   538         *)  do_error "'${var}' is not an absolute path: '${v}'"
   539     esac
   540 done
   541 
   542 #---------------------------------------------------------------------
   543 # That's all, folks!
   544 
   545 printf "Building up Makefile... "
   546 var_sed="$( for var_name in ${var_list}; do
   547                 eval echo 's,@@${var_name}@@,${'"${var_name}"'},g'
   548             done
   549           )"
   550 kconfig_sed="s/@@KCONFIG@@/$( for k_name in ${kconfig_list}; do
   551                                   eval printf \"${k_name}=\${${k_name}} \"
   552                               done
   553                             )/"
   554 "${sed}" -r -e "s,@@BINDIR@@,${BINDIR},g"       \
   555             -e "s,@@LIBDIR@@,${LIBDIR},g"       \
   556             -e "s,@@DOCDIR@@,${DOCDIR},g"       \
   557             -e "s,@@MANDIR@@,${MANDIR},g"       \
   558             -e "s,@@VERSION@@,${VERSION},g"     \
   559             -e "s,@@DATE@@,${DATE},g"           \
   560             -e "s,@@LOCAL@@,${LOCAL_set},g"     \
   561             -e "${var_sed}"                     \
   562             -e "${kconfig_sed}"                 \
   563          Makefile.in                            \
   564          >Makefile
   565 echo "done"
   566 
   567 cat <<__EOF__
   568 
   569 crosstool-NG configured as follows:
   570   PREFIX='${PREFIX}'
   571   BINDIR='${BINDIR}'
   572   LIBDIR='${LIBDIR}'
   573   DOCDIR='${DOCDIR}'
   574   MANDIR='${MANDIR}'
   575 
   576 Now run:
   577   make
   578 __EOF__
   579 if [ "${LOCAL_set}" != "y" ]; then
   580     printf "  make install\n"
   581 fi