configure
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Thu Jun 02 19:49:36 2011 +0200 (2011-06-02)
changeset 2499 56b7eab1391a
parent 2498 6b479665a053
child 2500 ba1e71fa72a9
permissions -rwxr-xr-x
configure: check for libstdc++.{so,dylib,a}

It's probably a good thing to check for at least one instance of
libstdc++.{so,dylib,a} at configure time. At least one is needed
by the companion libraries and gcc.

Original patch by Bryan Hundven <bryanhundven@gmail.com>

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