configure
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Jul 03 12:00:37 2011 +0200 (2011-07-03)
changeset 2524 cdb5c36290f4
parent 2509 45a4393fa357
child 2525 00054087dab2
permissions -rwxr-xr-x
configure: indent error/warning message

Indent the error/warning message so that it is explicit that
the second line is giving details for the first general hint.

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