configure
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Dec 23 22:20:25 2008 +0000 (2008-12-23)
changeset 1106 2051ee3d1b75
parent 1105 3ba2a43353df
child 1132 c232833120c1
permissions -rwxr-xr-x
Further enhance the check for needed tools:
- update the tool_pattern to use ' || ' as a pattern separator
- which allows using | in regexp
- add checks for cut and xargs
- manually check for grep and sed because they are needed when checking for tools
- print why a test failed, with each tested tool and regexp
- move tools checks before options parsing
- apply conttibutions before computing the version string
- inform user to run make && make install

/trunk/configure | 173 111 62 0 ++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 111 insertions(+), 62 deletions(-)
yann@182
     1
#!/bin/sh
yann@182
     2
yann@1105
     3
VERSION=$( cat .version )
yann@1105
     4
DATE=$( date +%Y%m%d )
yann@182
     5
yann@673
     6
# All absolutely required tools, one per line to ease diff.
yann@673
     7
# See function 'has_or_abort, below, for syntax
yann@673
     8
#  - Hopefully, if gcc is present, then all associated tools will be
yann@673
     9
#  - awk must be GNU awk
yann@673
    10
#  - makeinfo for building docs, even if discarded later on
yann@673
    11
#  - others obvious... :-/
yann@876
    12
#
yann@876
    13
# Format of a pattern to check for, one per line:
yann@1106
    14
#   pattern := tool_test  OR  pattern || tool_test
yann@1105
    15
#   tool_test := tool=regexp OR tool
yann@1105
    16
#   tool := basename of the tool  OR  absolute pathname to the tool
yann@1105
    17
#   regexp := valid grep(1) extended regular expression, $( tool --version)
yann@1105
    18
#             will be matched against this regexp.
yann@876
    19
#
yann@1106
    20
# In case a pattern list is given (eg foo || bar || buz), then tests are performed
yann@876
    21
# from left to right, stopping at the first matching test (like the shell
yann@876
    22
# would parse 'foo || bar || buz' ).
yann@876
    23
#
yann@876
    24
# Examples:
yann@1105
    25
#    /bin/bash=^GNU bash, version 3\.
yann@1105
    26
#       will ensure that /bin/bash exists, and that $( /bin/bash --version )
yann@876
    27
#       matches the regexp '^GNU bash, version 3\.'
yann@1106
    28
#    autoconf=(GNU Autoconf) || autoconf2.50
yann@876
    29
#       will ensure that:
yann@1105
    30
#         - 'autoconf' is to be found in the PATH, and that $( autoconf --version )
yann@1105
    31
#           matches the regexp '(GNU Autoconf)' (which btw is the signature of
yann@1105
    32
#           autoconf >= 2.50),
yann@876
    33
#       OR that:
yann@876
    34
#         - 'autoconf2.50' is to be found in the PATH
yann@876
    35
#
yann@673
    36
TOOLS_TO_CHECK='
yann@1105
    37
/bin/bash=^GNU bash, version 3\.
yann@1106
    38
cut
yann@1106
    39
xargs
yann@1105
    40
make=^GNU Make
yann@1105
    41
gcc
yann@1105
    42
gawk=^GNU Awk
yann@1105
    43
bison
yann@1105
    44
flex
yann@1105
    45
makeinfo
yann@1106
    46
automake=\(GNU automake\) (1\.[[:digit:]]{2,}\.|[2-9][[:digit:]]*\.)
yann@1106
    47
libtool=\(GNU libtool\) (2[[:digit:]]*\.|1\.6[[:digit:]]*\.|1\.5\.[2-9][[:digit:]]+)
yann@1106
    48
curl || wget
yann@1105
    49
patch
yann@1105
    50
tar
yann@1105
    51
gzip
yann@1105
    52
bzip2
yann@673
    53
'
yann@673
    54
yann@183
    55
PREFIX_DEFAULT=/usr/local
yann@182
    56
yann@182
    57
BINDIR_set=
yann@182
    58
LIBDIR_set=
yann@182
    59
DOCDIR_set=
yann@182
    60
MANDIR_set=
yann@285
    61
LOCAL_set=
yann@182
    62
yann@680
    63
FORCE=0
yann@680
    64
yann@641
    65
do_quit=
yann@614
    66
CONTRIB_list=
yann@614
    67
yann@673
    68
# Simply print the error message, and exit. Obvious, he?
yann@673
    69
do_error() {
yann@673
    70
    echo "${@}"
yann@673
    71
    exit 1
yann@673
    72
}
yann@673
    73
yann@673
    74
# A small function to test for existence of various tools
yann@876
    75
# Usage: has_or_abort test_pattern (see top of file, TOOLS_TO_CHECK, for
yann@876
    76
#                                   complete pattern format)
yann@673
    77
has_or_abort() {
yann@1105
    78
    save_IFS="${IFS}"
yann@1106
    79
    tool_pattern="$( echo "${1}" |"${sed}" -r -e 's/ *\|\| */\n/g;' )"
yann@1106
    80
    IFS='
yann@1106
    81
'
yann@1106
    82
    for item in ${tool_pattern}; do
yann@1105
    83
        case "${item}" in
yann@1105
    84
            *=*)
yann@1105
    85
                tool="${item%%=*}"
yann@1105
    86
                regexp="${item#*=}"
yann@1105
    87
                ;;
yann@1105
    88
            *)  tool="${item}"
yann@1105
    89
                regexp=
yann@1105
    90
                ;;
yann@1105
    91
        esac
yann@1105
    92
        printf "Checking for '${tool}'... "
yann@1105
    93
        where=$( which "${tool}" 2>/dev/null )
yann@1105
    94
        if [ -z "${where}" ]; then
yann@1105
    95
            echo "not found"
yann@1105
    96
            where=
yann@1105
    97
            continue
yann@1106
    98
        elif [ -n "${regexp}" ]; then
yann@1106
    99
            tool_version=$( ${tool} --version 2>&1 )
yann@1106
   100
            str=$( echo "${tool_version}" |"${grep}" -E "${regexp}" |head -n 1 )
yann@1106
   101
            if [ -z "${str}" ]; then
yann@1106
   102
                echo "not found"
yann@1106
   103
                where=""
yann@1106
   104
                continue
yann@1105
   105
            fi
yann@1105
   106
        fi
yann@1106
   107
        echo "${where}"
yann@1106
   108
        break
yann@1105
   109
    done;
yann@1106
   110
    if [ -z "${where}" ]; then
yann@1106
   111
        for item in ${tool_pattern}; do
yann@1106
   112
            case "${item}" in
yann@1106
   113
                *=*)
yann@1106
   114
                    tool="${item%%=*}"
yann@1106
   115
                    regexp="${item#*=}"
yann@1106
   116
                    ;;
yann@1106
   117
                *)  tool="${item}"
yann@1106
   118
                    regexp=
yann@1106
   119
                    ;;
yann@1106
   120
            esac
yann@1106
   121
            echo "  could not find '${tool}' matching regexp '${regexp}'"
yann@1106
   122
        done
yann@1106
   123
        echo "Either you are missing entirely the needed tool,"
yann@1106
   124
        echo "or the version you have is tool old."
yann@1106
   125
        [ ${FORCE} -eq 0 ] && do_error "Bailing out..."
yann@1106
   126
    fi
yann@1105
   127
    IFS="${save_IFS}"
yann@673
   128
    return 0
yann@673
   129
}
yann@673
   130
yann@641
   131
# Given an option string and the following argument,
yann@641
   132
# echoes the value of the option.
yann@641
   133
# If --var=val => echoes val and returns 0, meaning second arg was not consumed
yann@641
   134
# If --var val => echoes val and returns non null, meaning second arg was used
yann@182
   135
get_optval(){
yann@182
   136
    case "$1" in
yann@182
   137
        --*=?*)
yann@193
   138
            echo "${1}" |cut -d '=' -f 2-
yann@1105
   139
            return 0
yann@182
   140
            ;;
yann@182
   141
        *)
yann@182
   142
            echo "${2}"
yann@1105
   143
            return 1
yann@182
   144
            ;;
yann@182
   145
    esac
yann@182
   146
}
yann@182
   147
yann@641
   148
# The set_xxx functions will set the corresponding configuration variable
yann@641
   149
# They return 0 if second arg was not consumed, and non-zero if it was consumed.
yann@182
   150
set_prefix() {
yann@1105
   151
    PREFIX="$( get_optval "$1" "$2" )"
yann@182
   152
}
yann@182
   153
set_bindir() {
yann@376
   154
    BINDIR_set=1
yann@1105
   155
    BINDIR="$( get_optval "$1" "$2" )"
yann@182
   156
}
yann@182
   157
set_libdir() {
yann@376
   158
    LIBDIR_set=1
yann@1105
   159
    LIBDIR="$( get_optval "$1" "$2" )"
yann@182
   160
}
yann@182
   161
set_docdir() {
yann@376
   162
    DOCDIR_set=1
yann@1105
   163
    DOCDIR="$( get_optval "$1" "$2" )"
yann@182
   164
}
yann@182
   165
set_mandir() {
yann@376
   166
    MANDIR_set=1
yann@1105
   167
    MANDIR="$( get_optval "$1" "$2" )"
yann@182
   168
}
yann@182
   169
yann@641
   170
# The set_contrib function is different in that it will work like the others,
yann@641
   171
# except in two cases:
yann@641
   172
# If all => replaces all with the list of all available contribs
yann@641
   173
# If list => just echoes the list of all available contribs, and instructs
yann@641
   174
# caller to quit immediately by setting do_quit to non null.
yann@641
   175
# (can't use the return code, see above).
yann@614
   176
set_contrib() {
yann@1105
   177
    opt_val="$( get_optval "$1" "$2" )"
yann@1105
   178
    ret=$?
yann@614
   179
    case "${opt_val}" in
yann@614
   180
        all)
yann@1106
   181
            CONTRIB_list="$( LC_ALL=C ls -1 contrib/*.patch.lzma                \
yann@1106
   182
                                      |xargs -I {} basename {} .patch.lzma      \
yann@1106
   183
                                      |"${sed}" -r -e ':a; /$/N; s/\n/,/; ta;'  \
yann@1105
   184
                           )"
yann@614
   185
            ;;
yann@614
   186
        list)
yann@614
   187
            do_quit=1
yann@614
   188
            echo "Available contributions:"
yann@1105
   189
            LC_ALL=C ls -1 contrib/*.patch.lzma             \
yann@1105
   190
                     |xargs -I {} basename {} .patch.lzma   \
yann@1106
   191
                     |"${sed}" -r -e 's/^/  /;'
yann@614
   192
            ;;
yann@614
   193
        *)  CONTRIB_list="${CONTRIB_list},${opt_val}";;
yann@614
   194
    esac
yann@614
   195
    return $ret
yann@614
   196
}
yann@614
   197
yann@183
   198
do_help() {
yann@183
   199
    cat <<__EOF__
yann@197
   200
\`configure' configures crosstool-NG ${VERSION} to adapt to many kind of systems.
yann@183
   201
yann@183
   202
USAGE: ./configure [OPTION]...
yann@183
   203
yann@183
   204
Defaults for the options are specified in brackets.
yann@183
   205
yann@183
   206
Configuration:
yann@1105
   207
  -h, --help              display this help and exit
yann@683
   208
      --force             force ./configure to complete, even if one or more
yann@683
   209
                          tools were not found. Use at your own risk, only if
yann@683
   210
                          you know what you are doing!
yann@615
   211
yann@615
   212
Installation directories:
yann@185
   213
  --prefix=PREFIX         install files in PREFIX [${PREFIX_DEFAULT}]
yann@285
   214
  --local                 don't install, and use current directory
yann@183
   215
yann@183
   216
By default, \`make install' will install all the files in
yann@183
   217
\`${PREFIX_DEFAULT}/bin', \`${PREFIX_DEFAULT}/lib' etc.  You can specify
yann@183
   218
an installation prefix other than \`${PREFIX_DEFAULT}' using \`--prefix',
yann@183
   219
for instance \`--prefix=\${HOME}'.
yann@183
   220
yann@183
   221
For better control, use the options below.
yann@183
   222
yann@183
   223
Fine tuning of the installation directories:
yann@683
   224
  --bindir=DIR            user executables [PREFIX/bin]
yann@683
   225
  --libdir=DIR            object code libraries [PREFIX/lib]
yann@683
   226
  --docdir=DIR            info documentation [PREFIX/share/doc]
yann@683
   227
  --mandir=DIR            man documentation [PREFIX/share/man]
yann@614
   228
yann@614
   229
Optional Features:
yann@683
   230
  --with-contrib=XXX      Include externally contributed features found in the
yann@683
   231
                          contrib/ sub-directory. Set to a comma-separated list
yann@683
   232
                          of features. Use 'all' to use all contributions, and
yann@683
   233
                          'list' to see which are available.
yann@183
   234
__EOF__
yann@183
   235
}
yann@183
   236
yann@376
   237
#---------------------------------------------------------------------
yann@1106
   238
# Some sanity checks, now
yann@1106
   239
yann@1106
   240
# We check for grep and sed manually, because it is used in has_or_abort
yann@1106
   241
printf "Checking for 'grep'... "
yann@1106
   242
grep="$( which grep 2>/dev/null )"
yann@1106
   243
[ -z "${grep}" ] && do_error "not found"
yann@1106
   244
echo "${grep}"
yann@1106
   245
printf "Checking whether '${grep}' supports -E... "
yann@1106
   246
if echo 'foo' |"${grep}" -E 'foo' >/dev/null 2>&1; then
yann@1106
   247
    echo "yes"
yann@1106
   248
else
yann@1106
   249
    do_error "no"
yann@1106
   250
fi
yann@1106
   251
printf "Checking for 'sed'... "
yann@1106
   252
sed="$( which sed 2>/dev/null )"
yann@1106
   253
[ -z "${sed}" ] && do_error "not found"
yann@1106
   254
echo "${sed}"
yann@1106
   255
yann@1106
   256
# Check the existence of absolutely required tools
yann@1106
   257
save_IFS="${IFS}"
yann@1106
   258
IFS='
yann@1106
   259
'
yann@1106
   260
for tool in ${TOOLS_TO_CHECK}; do
yann@1106
   261
    has_or_abort "${tool}"
yann@1106
   262
done
yann@1106
   263
IFS="${save_IFS}"
yann@1106
   264
yann@1106
   265
#---------------------------------------------------------------------
yann@376
   266
# Set user's options
yann@376
   267
yann@182
   268
while [ $# -ne 0 ]; do
yann@182
   269
    case "$1" in
yann@182
   270
        --prefix*)  set_prefix "$1" "$2" && shift || shift 2;;
yann@182
   271
        --bindir*)  set_bindir "$1" "$2" && shift || shift 2;;
yann@182
   272
        --libdir*)  set_libdir "$1" "$2" && shift || shift 2;;
yann@182
   273
        --docdir*)  set_docdir "$1" "$2" && shift || shift 2;;
yann@182
   274
        --mandir*)  set_mandir "$1" "$2" && shift || shift 2;;
yann@285
   275
        --local)    LOCAL_set=1; shift;;
yann@680
   276
        --force)    FORCE=1; shift;;
yann@614
   277
        --with-contrib*)
yann@614
   278
                    set_contrib "$1" "$2" && shift || shift 2
yann@614
   279
                    [ "${do_quit}" = "1" ] && exit 0
yann@614
   280
                    ;;
yann@183
   281
        --help|-h)  do_help; exit 0;;
yann@183
   282
        *)          do_help; exit 1;;
yann@182
   283
    esac
yann@182
   284
done
yann@182
   285
yann@641
   286
# Use defaults
yann@185
   287
[ -z "${PREFIX}" ] && set_prefix "" "${PREFIX_DEFAULT}"
yann@641
   288
yann@641
   289
# Special case when installing locally
yann@285
   290
if [ "${LOCAL_set}" = "1" ]; then
yann@1105
   291
    set_prefix "" "$( pwd )"
yann@1105
   292
    set_bindir "" "$( pwd )"
yann@1105
   293
    set_libdir "" "$( pwd )"
yann@1105
   294
    set_docdir "" "$( pwd )/docs"
yann@1105
   295
    set_mandir "" "$( pwd )/docs"
yann@285
   296
fi
yann@183
   297
yann@376
   298
#---------------------------------------------------------------------
yann@1106
   299
# Apply contributed code
yann@1106
   300
yann@1106
   301
# It's safer to change all ',' to spaces rather than setting IFS
yann@1106
   302
CONTRIB_list="$( echo "${CONTRIB_list}"                                     \
yann@1106
   303
                 |"${sed}" -r -e 's/,+/ /g; s/ +/ /g; s/^ //g; s/ $//g;'    \
yann@1106
   304
               )"
yann@1106
   305
if [ -n "${CONTRIB_list}" ]; then
yann@1106
   306
    has_or_abort 'lzcat'
yann@1106
   307
    printf "Applying contributed code: "
yann@1106
   308
    for c in ${CONTRIB_list}; do
yann@1106
   309
        printf "${c}, "
yann@1106
   310
        if [ ! -f "contrib/${c}.patch.lzma" ]; then
yann@1106
   311
            do_error "Contribution '${c}' does not exist"
yann@1106
   312
        fi
yann@1106
   313
        lzcat "contrib/${c}.patch.lzma" |patch -p1 >/dev/null 2>&1
yann@1106
   314
    done
yann@1106
   315
    echo "done"
yann@1106
   316
fi
yann@1106
   317
yann@1106
   318
#---------------------------------------------------------------------
yann@1106
   319
# Compute the version string
yann@376
   320
yann@435
   321
# If this version is a svn snapshot, try to get the revision number
yann@435
   322
# If we can't get the revision number, use date
yann@641
   323
printf "Computing version string... "
yann@435
   324
case "${VERSION}" in
yann@1105
   325
    *+svn|svn)
yann@1105
   326
        REVISION="$( LC_ALL=C svnversion )"
yann@1105
   327
        case "${REVISION}" in
yann@1105
   328
            exported)
yann@1105
   329
                VERSION="${VERSION}_unknown@$( date +%Y%m%d.%H%M%S )";;
yann@1105
   330
            *)
yann@1105
   331
                URL="$( LC_ALL=C svn info 2>/dev/null   \
yann@1105
   332
                                 |egrep 'URL: '         \
yann@1105
   333
                                 |cut -d ' ' -f 2-      \
yann@1105
   334
                      )"
yann@1106
   335
                ROOT="$( LC_ALL=C svn info 2>/dev/null      \
yann@1106
   336
                         |"${grep}" '^Repository Root: '    \
yann@1106
   337
                         |cut -d ' ' -f 3-                  \
yann@1105
   338
                       )"
yann@1105
   339
                VERSION="${VERSION}${URL#${ROOT}}@${REVISION}"
yann@1105
   340
                ;;
yann@1105
   341
        esac
yann@1105
   342
        # Arrange to have no / in the directory name, no need to create an
yann@1105
   343
        # arbitrarily deep directory structure
yann@1106
   344
        VERSION="$( echo "${VERSION}" |"${sed}" -r -e 's|/+|_|g;' )"
yann@444
   345
        ;;
yann@435
   346
esac
yann@553
   347
echo "${VERSION}"
yann@435
   348
yann@1106
   349
#---------------------------------------------------------------------
yann@1106
   350
# Compute and check install paths
yann@1106
   351
yann@614
   352
# Now we have the version string, we can build up the paths
yann@554
   353
[ -z "${BINDIR_set}" ] && BINDIR="${PREFIX}/bin"
yann@554
   354
[ -z "${LIBDIR_set}" ] && LIBDIR="${PREFIX}/lib/ct-ng-${VERSION}"
yann@554
   355
[ -z "${DOCDIR_set}" ] && DOCDIR="${PREFIX}/share/doc/ct-ng-${VERSION}"
yann@554
   356
[ -z "${MANDIR_set}" ] && MANDIR="${PREFIX}/share/man/man1"
yann@554
   357
yann@1047
   358
# Check that install PATHs are absolute
yann@1047
   359
for p in BIN LIB DOC MAN; do
yann@1105
   360
    var="${p}DIR"
yann@1105
   361
    eval v='"${'"${var}"'}"'
yann@1105
   362
    case "${v}" in
yann@1105
   363
        /*) ;;
yann@1105
   364
        *)  do_error "'${var}' is not an absolute path: '${v}'"
yann@1105
   365
    esac
yann@1047
   366
done
yann@1047
   367
yann@1106
   368
#---------------------------------------------------------------------
yann@1106
   369
# That's all, folks!
yann@614
   370
yann@641
   371
printf "Building up Makefile... "
yann@1106
   372
"${sed}" -r -e "s,@@BINDIR@@,${BINDIR},g
yann@1106
   373
                s,@@LIBDIR@@,${LIBDIR},g
yann@1106
   374
                s,@@DOCDIR@@,${DOCDIR},g
yann@1106
   375
                s,@@MANDIR@@,${MANDIR},g
yann@1106
   376
                s,@@VERSION@@,${VERSION},g
yann@1106
   377
                s,@@DATE@@,${DATE},g
yann@1106
   378
                s,@@LOCAL@@,${LOCAL_set},g"  Makefile.in >Makefile
yann@673
   379
echo "done"
yann@185
   380
yann@185
   381
cat <<__EOF__
yann@673
   382
yann@197
   383
crosstool-NG configured as follows:
yann@554
   384
  PREFIX='${PREFIX}'
yann@554
   385
  BINDIR='${BINDIR}'
yann@554
   386
  LIBDIR='${LIBDIR}'
yann@554
   387
  DOCDIR='${DOCDIR}'
yann@554
   388
  MANDIR='${MANDIR}'
yann@641
   389
  CONTRIB='${CONTRIB_list}'
yann@1106
   390
yann@1106
   391
Now run:
yann@1106
   392
  make
yann@1106
   393
  make install
yann@185
   394
__EOF__