configure
author Titus von Boxberg <titus@v9g.de>
Mon May 17 14:11:08 2010 +0200 (2010-05-17)
changeset 1962 88fa6f1df207
parent 1959 a86d3c6ad7fe
child 1969 618a1ffd1ea2
permissions -rwxr-xr-x
ct-ng: Add ability to configure and use some GNU tools

Make the paths to libtool, objcopy, objdump, readelf, patch configurable.
     1 #!/bin/sh
     2 
     3 myname="${0##*/}"
     4 
     5 VERSION=$( cat .version )
     6 DATE=$( date +%Y%m%d )
     7 
     8 PREFIX_DEFAULT=/usr/local
     9 
    10 BINDIR_set=
    11 LIBDIR_set=
    12 DOCDIR_set=
    13 MANDIR_set=
    14 LOCAL_set=
    15 FORCE=
    16 
    17 do_quit=
    18 
    19 # Simply print the error message, and exit. Obvious, he?
    20 do_error() {
    21     printf "${myname}: ${@}\n"
    22     exit 1
    23 }
    24 
    25 # Given an option string and the following argument,
    26 # echoes the value of the option.
    27 # If --var=val => echoes val and returns 0, meaning second arg was not consumed
    28 # If --var val => echoes val and returns non null, meaning second arg was used
    29 get_optval(){
    30     case "$1" in
    31         --*=?*)
    32             printf "${1#*=}"
    33             return 0
    34             ;;
    35         *)
    36             printf "${2}"
    37             return 1
    38             ;;
    39     esac
    40 }
    41 
    42 # The set_xxx functions will set the corresponding configuration variable
    43 # They return 0 if second arg was not consumed, and non-zero if it was consumed.
    44 set_prefix() {
    45     PREFIX="$( get_optval "$1" "$2" )"
    46 }
    47 set_bindir() {
    48     BINDIR_set=1
    49     BINDIR="$( get_optval "$1" "$2" )"
    50 }
    51 set_libdir() {
    52     LIBDIR_set=1
    53     LIBDIR="$( get_optval "$1" "$2" )"
    54 }
    55 set_docdir() {
    56     DOCDIR_set=1
    57     DOCDIR="$( get_optval "$1" "$2" )"
    58 }
    59 set_mandir() {
    60     MANDIR_set=1
    61     MANDIR="$( get_optval "$1" "$2" )"
    62 }
    63 set_tool() {
    64     local var_name="${1%%=*}"
    65     var_name="${var_name#--with-}"
    66     eval ${var_name}="\$( get_optval "$1" "$2" )"
    67 }
    68 
    69 # var_list is a list of variables, each one holding a path to a
    70 # tool, either detected by ./configure, or specified by the user.
    71 var_list=""
    72 
    73 # This function adds a variable name to the above list of variable names.
    74 # $1: the name of the variable to add to the list
    75 add_to_var_list() {
    76     var_list="${var_list} ${1}"
    77 }
    78 
    79 # A function to test for required tools/headers/libraries
    80 # Return 0 (true) if found, !0 (false) if not found
    81 #
    82 # $*: [prog|inc|lib]=<name[ name...]>
    83 #     the name(s) of tool(s) to test for
    84 #     mandatory
    85 #       eg: prog=bash   prog="curl wget"
    86 # $*: var=<var_name>
    87 #     the name of the variable to test and set
    88 #     optional
    89 #       eg: var=bash    if ${bash} is set and non-null, use that,
    90 #                       else check for bash and set bash=$(which bash)
    91 # $*: ver=<regexp>
    92 #     for each 'prog', test if $(prog --version) matches 'regexp'
    93 #     optional
    94 #       eg: ver='^GNU bash, version [34]\.'
    95 # $*: err=<error_message>
    96 #     the error message to print if tool is missing
    97 #     optional, defaults to: '${prog}: none found'
    98 #       eg: err="'bash' 3.x or above was not found"
    99 check_for() {
   100     local prog inc lib
   101     local var ver err
   102     local val
   103     local item
   104     local where
   105     local status
   106 
   107     for item in "${@}"; do
   108         case "${item}" in
   109             prog=*|inc=*|lib=*|var=*|ver=*|err=*)
   110                 eval ${item%%=*}="'${item#*=}'"
   111                 ;;
   112             *)  do_error "has_or_abort: incorrect parameters: '$@'";;
   113         esac
   114     done
   115 
   116     case "${prog}:${inc}:${lib}" in
   117         ?*::)
   118             for item in ${prog}; do
   119                 printf "Checking for '${item}'... "
   120                 if [ -n "${var}" ]; then
   121                     eval val="\${${var}}"
   122                     if [ -n "${val}" ]; then
   123                         printf "${val} (cached)\n"
   124                         add_to_var_list "${var}"
   125                         return 0
   126                     fi
   127                 fi
   128                 where="$( which "${item}" 2>/dev/null )"
   129                 if [ -z "${where}" ]; then
   130                     printf "no\n"
   131                     continue
   132                 elif [ -n "${ver}" ]; then
   133                     str=$( LC_ALL=C "${where}" --version 2>&1   \
   134                            |grep -E "${ver}"                    \
   135                            |head -n 1
   136                          )
   137                     if [ -z "${str}" ]; then
   138                         printf "no\n"
   139                         unset where
   140                         continue
   141                     fi
   142                 fi
   143                 status="${where}"
   144                 break
   145             done
   146             ;;
   147         :?*:)
   148             for item in ${inc}; do
   149                 printf "Checking for '${item}'... "
   150                 if printf "#include \"${item}\"" |gcc -x c -c - -o /dev/null >/dev/null 2>&1; then
   151                     where="${item}"
   152                     status=yes
   153                     break;
   154                 fi
   155                 printf "no\n"
   156             done
   157             ;;
   158         ::?*)
   159             for item in ${lib}; do
   160                 printf "Checking for '${item}'... "
   161                 where="$( gcc -print-file-name="${item}" )"
   162                 if [ "${where}" != "${item}" ]; then
   163                     where="$( readlink "${where}" )"
   164                     status=yes
   165                     break;
   166                 fi
   167                 printf "no\n"
   168             done
   169             ;;
   170     esac
   171 
   172     if [ -z "${status}" ]; then
   173         printf "\n${err:-${prog}${inc}${lib}: none found}\n\n"
   174         printf "Either you are missing entirely the needed tool,\n"
   175         printf "or the version you have is too old.\n"
   176         if [ -n "${var}" ]; then
   177             printf "You can give the path to this tool using: --with-${var}=PATH\n"
   178         fi
   179         printf "\n"
   180         return 1
   181     fi
   182 
   183     printf "${status}"
   184     if [ -n "${var}" ]; then
   185         eval ${var}='"'"${where}"'"'
   186         add_to_var_list "${var}"
   187     fi
   188     printf "\n"
   189 }
   190 
   191 # This function checks for a tool, and aborts if not found
   192 # See check_for(), above, for how to call has_or_abort
   193 has_or_abort() {
   194     if ! check_for "$@"; then
   195         # FORCE can be set in the environment
   196         [ -z "${FORCE}" ] && do_error "Bailing out..."
   197         printf "\n"
   198         printf "<*                                          *>\n"
   199         printf "<*            FORCE in action:              *>\n"
   200         printf "<* Continuing despite missing pre-requisite *>\n"
   201         printf "<*          Prepare for breakage            *>\n"
   202         printf "<*                                          *>\n"
   203         printf "\n"
   204     fi
   205 }
   206 
   207 do_help() {
   208     cat <<__EOF__
   209 \`configure' configures crosstool-NG-${VERSION} to adapt to many kind of systems.
   210 
   211 USAGE: ./configure [OPTION]...
   212 
   213 Defaults for the options are specified in brackets.
   214 
   215 Configuration:
   216   -h, --help              display this help and exit
   217       --force             force configure to continue, even in case
   218                           some pre-requisites are missing
   219 
   220 Installation directories:
   221   --prefix=PREFIX         install files in PREFIX [${PREFIX_DEFAULT}]
   222   --local                 don't install, and use current directory
   223 
   224 By default, \`make install' will install all the files in
   225 \`${PREFIX_DEFAULT}/bin', \`${PREFIX_DEFAULT}/lib' etc.  You can specify
   226 an installation prefix other than \`${PREFIX_DEFAULT}' using \`--prefix',
   227 for instance \`--prefix=\${HOME}'.
   228 
   229 For better control, use the options below.
   230 
   231 Fine tuning of the installation directories:
   232   --bindir=DIR            user executables [PREFIX/bin]
   233   --libdir=DIR            object code libraries [PREFIX/lib]
   234   --docdir=DIR            info documentation [PREFIX/share/doc]
   235   --mandir=DIR            man documentation [PREFIX/share/man]
   236 
   237 Optional Features:
   238   --with-install=PATH     Specify the full PATH to GNU install
   239   --with-make=PATH        Specify the full PATH to GNU make >= 3.80
   240   --with-grep=PATH        Specify the full PATH to GNU grep
   241   --with-sed=PATH         Specify the full PATH to GNU sed
   242   --with-bash=PATH        Specify the full PATH to bash >= 3.0
   243 __EOF__
   244 }
   245 
   246 #---------------------------------------------------------------------
   247 # Set user's options
   248 
   249 while [ $# -ne 0 ]; do
   250     case "$1" in
   251         --local)    LOCAL_set="y"; shift;;
   252         --prefix*)  set_prefix "$1" "$2" && shift || shift 2;;
   253         --bindir*)  set_bindir "$1" "$2" && shift || shift 2;;
   254         --libdir*)  set_libdir "$1" "$2" && shift || shift 2;;
   255         --docdir*)  set_docdir "$1" "$2" && shift || shift 2;;
   256         --mandir*)  set_mandir "$1" "$2" && shift || shift 2;;
   257         --with-*)   set_tool   "$1" "$2" && shift || shift 2;;
   258         --force)    FORCE=1; shift;;
   259         --help|-h)  do_help; exit 0;;
   260         # Skip, auto-stuff compatibility
   261         --build=*|--host=*|--infodir=*|--datadir=*|--sysconfdir=*|--localstatedir=*) shift;;
   262         --build|--host|--infodir|--datadir|--sysconfdir|--localstatedir)             shift 2;;
   263         *)          printf "Unrecognised option: '${1}'\n"; do_help; exit 1;;
   264     esac
   265 done
   266 
   267 # Use defaults
   268 [ -z "${PREFIX}" ] && set_prefix "" "${PREFIX_DEFAULT}"
   269 
   270 # Special case when installing locally
   271 if [ "${LOCAL_set}" = "y" ]; then
   272     set_prefix "" "$( pwd )"
   273     set_bindir "" "$( pwd )"
   274     set_libdir "" "$( pwd )"
   275     set_docdir "" "$( pwd )/docs"
   276     set_mandir "" "$( pwd )/docs"
   277 fi
   278 
   279 #---------------------------------------------------------------------
   280 # Some sanity checks, now
   281 
   282 # We check for grep and sed manually, because they are used in check_for()
   283 printf "Checking for 'grep'... "
   284 if [ -n "${grep}" ]; then
   285     printf "${grep} (cached)\n"
   286 else
   287     grep="$( which grep 2>/dev/null )"
   288     if [ -z "${grep}" ]; then
   289         printf "not found\n"
   290     else
   291         printf "${grep}\n"
   292         printf "Checking whether '${grep}' supports -E... "
   293         if echo 'foo' |"${grep}" -E 'foo' >/dev/null 2>&1; then
   294             printf "yes\n"
   295         else
   296             printf "no\n"
   297             grep=
   298         fi
   299     fi
   300 fi
   301 if [ -z "${grep}" ]; then
   302     printf "Either you are missing entirely the needed tool,\n"
   303     printf "or the version you have is too old.\n"
   304     printf "You can give the path to this tool using: --with-grep=PATH\n"
   305     do_error "Bailing out..."
   306 fi
   307 add_to_var_list grep
   308 
   309 printf "Checking for 'sed'... "
   310 if [ -n "${sed}" ]; then
   311     printf "${sed} (cached)\n"
   312 else
   313     sed="$( which sed 2>/dev/null )"
   314     if [ -z "${sed}" ]; then
   315         printf "not found\n"
   316     else
   317         printf "${sed}\n"
   318         printf "Checking whether '${sed}' supports -i and -e... "
   319         touch .ct-ng.sed.test
   320         if "${sed}" -r -i -e 's/foo/bar/' .ct-ng.sed.test >/dev/null 2>&1; then
   321             printf "yes\n"
   322         else
   323             printf "no\n"
   324             sed=
   325         fi
   326         rm -f .ct-ng.sed.test
   327     fi
   328 fi
   329 if [ -z "${sed}" ]; then
   330     printf "Either you are missing entirely the needed tool,\n"
   331     printf "or the version you have is too old.\n"
   332     printf "You can give the path to this tool using: --with-sed=PATH\n"
   333     do_error "Bailing out..."
   334 fi
   335 add_to_var_list sed
   336 
   337 # The regular list of tools we can now easily check for
   338 has_or_abort prog=bash                              \
   339              var=bash                               \
   340              ver='^GNU bash, version (3\.[1-9]|4)'  \
   341              err="'bash' 3.1 or above was not found"
   342 has_or_abort prog=cut
   343 has_or_abort prog=install var=install
   344 has_or_abort prog=make                                  \
   345              var=make                                   \
   346              ver='^GNU Make (3.[89][[:digit:]]|[4-9])'  \
   347              err="GNU 'make' 3.80 or above was not found"
   348 has_or_abort prog=gcc
   349 has_or_abort prog="awk gawk" ver='^GNU Awk' err="GNU 'awk' was not found"
   350 has_or_abort prog=bison
   351 has_or_abort prog=flex
   352 has_or_abort prog=makeinfo
   353 has_or_abort prog=automake                                                      \
   354              ver='\(GNU automake\) (1\.[[:digit:]]{2,}|[2-9][[:digit:]]*\.)'    \
   355              err="'automake' 1.10 or above was not found"
   356 has_or_abort prog=libtool                                                                           \
   357              ver='\(GNU libtool.*\) (2[[:digit:]]*\.|1\.6[[:digit:]]*\.|1\.5\.[2-9][[:digit:]]+)'   \
   358              err="'libtool' 1.5.26 or above was not found"
   359 has_or_abort prog=stat
   360 has_or_abort prog="aria2c curl wget"
   361 has_or_abort prog=cvs
   362 has_or_abort prog=patch
   363 has_or_abort prog=tar
   364 has_or_abort prog=gzip
   365 has_or_abort prog=bzip2
   366 has_or_abort prog=lzma
   367 has_or_abort prog=readlink
   368 has_or_abort prog=objcopy var=objcopy
   369 has_or_abort prog=objdump var=objdump
   370 has_or_abort prog=readelf var=readelf
   371 has_or_abort prog=patch var=patch
   372 
   373 has_or_abort inc="ncurses/ncurses.h ncurses/curses.h ncurses.h curses.h"    \
   374              err="'ncurses' headers files were not found"
   375 
   376 ncurses_libs="$( for l in ncursesw ncurses curses; do   \
   377                      for x in so a dylib; do            \
   378                          printf "lib$l.$x ";            \
   379                      done;                              \
   380                  done                                   \
   381                )"
   382 has_or_abort lib="${ncurses_libs}"                  \
   383              err="'ncurses' library was not found"
   384 
   385 #---------------------------------------------------------------------
   386 # Compute the version string
   387 
   388 # If this version is n hg clone, try to get the revision number
   389 # If we can't get the revision number, use date
   390 printf "Computing version string... "
   391 case "${VERSION}" in
   392     *+hg|hg)
   393         REVISION="$( hg id -n 2>/dev/null || true )"
   394         case "${REVISION}" in
   395             "")
   396                 VERSION="${VERSION}_unknown@$( date +%Y%m%d.%H%M%S )";;
   397             *)
   398                 VERSION="${VERSION}_$( hg id -b )@${REVISION%%+}_$( hg id -i )"
   399                 ;;
   400         esac
   401         # Arrange to have no / in the directory name, no need to create an
   402         # arbitrarily deep directory structure
   403         VERSION="$( printf "${VERSION}\n" |"${sed}" -r -e 's|/+|_|g;' )"
   404         ;;
   405 esac
   406 printf "${VERSION}\n"
   407 
   408 #---------------------------------------------------------------------
   409 # Compute and check install paths
   410 
   411 # Now we have the version string, we can build up the paths
   412 [ -z "${BINDIR_set}" ] && BINDIR="${PREFIX}/bin"
   413 [ -z "${LIBDIR_set}" ] && LIBDIR="${PREFIX}/lib"
   414 [ -z "${DOCDIR_set}" ] && DOCDIR="${PREFIX}/share/doc"
   415 [ -z "${MANDIR_set}" ] && MANDIR="${PREFIX}/share/man/man1"
   416 
   417 # Install support files in our own sub-dir, so as not to mangle (system)
   418 # files and dirs, but only if not --local
   419 if [ -z "${LOCAL_set}" ]; then
   420     LIBDIR="${LIBDIR}/ct-ng-${VERSION}"
   421     DOCDIR="${DOCDIR}/ct-ng-${VERSION}"
   422 fi
   423 
   424 # Check that install PATHs are absolute
   425 for p in BIN LIB DOC MAN; do
   426     var="${p}DIR"
   427     eval v='"${'"${var}"'}"'
   428     case "${v}" in
   429         /*) ;;
   430         *)  do_error "'${var}' is not an absolute path: '${v}'"
   431     esac
   432 done
   433 
   434 #---------------------------------------------------------------------
   435 # That's all, folks!
   436 
   437 printf "Building up Makefile... "
   438 var_sed="$( for var_name in ${var_list}; do
   439                 eval echo 's,@@${var_name}@@,${'"${var_name}"'},g'
   440             done 
   441           )"
   442 "${sed}" -r -e "s,@@BINDIR@@,${BINDIR},g
   443                 s,@@LIBDIR@@,${LIBDIR},g
   444                 s,@@DOCDIR@@,${DOCDIR},g
   445                 s,@@MANDIR@@,${MANDIR},g
   446                 s,@@VERSION@@,${VERSION},g
   447                 s,@@DATE@@,${DATE},g
   448                 ${var_sed}
   449                 s,@@LOCAL@@,${LOCAL_set},g"  Makefile.in >Makefile
   450 echo "done"
   451 
   452 cat <<__EOF__
   453 
   454 crosstool-NG configured as follows:
   455   PREFIX='${PREFIX}'
   456   BINDIR='${BINDIR}'
   457   LIBDIR='${LIBDIR}'
   458   DOCDIR='${DOCDIR}'
   459   MANDIR='${MANDIR}'
   460 
   461 Now run:
   462   make
   463 __EOF__
   464 if [ "${LOCAL_set}" != "y" ]; then
   465     printf "  make install\n"
   466 fi