Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add tests for the shell under which build.sh is run. If the



details:   https://anonhg.NetBSD.org/src/rev/d8e3df60b10d
branches:  trunk
changeset: 769432:d8e3df60b10d
user:      apb <apb%NetBSD.org@localhost>
date:      Fri Sep 09 18:48:34 2011 +0000

description:
Add tests for the shell under which build.sh is run.  If the
shell fails the tests, then build.sh tries to re-exec itself
under a more suitable shell.

diffstat:

 BUILDING          |   56 ++++++++---
 build.sh          |  248 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 doc/BUILDING.mdoc |   96 +++++++++++++++-----
 3 files changed, 347 insertions(+), 53 deletions(-)

diffs (truncated from 480 to 300 lines):

diff -r 8371d41ef10a -r d8e3df60b10d BUILDING
--- a/BUILDING  Fri Sep 09 18:41:16 2011 +0000
+++ b/BUILDING  Fri Sep 09 18:48:34 2011 +0000
@@ -82,17 +82,23 @@
    Environment variables
      Several environment variables control the behaviour of NetBSD builds.
 
-     HOST_SH           Path name to a POSIX-compliant shell.  If this is not
-                       set explicitly, then the default is set using heuris-
-                       tics dependent on the host platform, or from the shell
-                       under which build.sh is executed (if that can be deter-
-                       mined), or using the first copy of sh found in PATH.
-                       If the host system's /bin/sh is not POSIX-compliant, we
-                       suggest that you build using commands like
+     HOST_SH           Path name to a shell available on the host system and
+                       suitable for use during the build.  The NetBSD build
+                       system requires a modern Bourne-like shell with POSIX-
+                       compliant features, and also requires support for the
+                       ``local'' keyword to declare local variables in shell
+                       functions (which is a widely-implemented but non-stan-
+                       dardised feature).
 
-                             HOST_SH=/path/to/working/shell
-                             export HOST_SH
-                             ${HOST_SH} build.sh [options]
+                       Depending on the host system, a suitable shell may be
+                       /bin/sh, /usr/xpg4/bin/sh, /bin/ksh (provided it is a
+                       variant of ksh that supports the ``local'' keyword,
+                       such as ksh88, but not ksh93), or /usr/local/bin/bash.
+
+                       Most parts of the build require HOST_SH to be an abso-
+                       lute path; however, build.sh allows it to be a simple
+                       command name, which will be converted to an absolute
+                       path by searching the PATH.
 
      HOST_CC           Path name to C compiler used to create the toolchain.
 
@@ -629,11 +635,31 @@
                    those as well but currently does not.
 
    The "build.sh" script
-     This script file is a Bourne shell script designed to build the entire
-     NetBSD system on any host with a Bourne shell in /bin/sh, including many
-     that are not POSIX compliant.  Note that if a host system's /bin/sh is
-     unusually old and broken, the Korn Shell (/bin/ksh), if available, may be
-     a usable alternative.
+     This script file is a shell script designed to build the entire NetBSD
+     system on any host with a suitable modern shell and some common utili-
+     ties.  The required shell features are described under the HOST_SH vari-
+     able.
+
+     If a host system's default shell does support the required features, then
+     we suggest that you explicitly specify a suitable shell using a command
+     like
+
+           /path/to/suitable/shell build.sh [options]
+
+     The above command will usually enable build.sh to automatically set
+     HOST_SH=/path/to/suitable/shell, but if that fails, then the following
+     set of commands may be used instead:
+
+           HOST_SH=/path/to/suitable/shell
+           export HOST_SH
+           ${HOST_SH} build.sh [options]
+
+     If build.sh detects that it is being executed under an unsuitable shell,
+     it attempts to exec a suitable shell instead, or prints an error message.
+     If HOST_SH is not set explicitly, then build.sh sets a default using
+     heuristics dependent on the host platform, or from the shell under which
+     build.sh is executed (if that can be determined), or using the first copy
+     of sh found in PATH.
 
      All cross-compile builds, and most native builds, of the entire system
      should make use of build.sh rather than just running ``make''.  This way,
diff -r 8371d41ef10a -r d8e3df60b10d build.sh
--- a/build.sh  Fri Sep 09 18:41:16 2011 +0000
+++ b/build.sh  Fri Sep 09 18:48:34 2011 +0000
@@ -1,5 +1,5 @@
 #! /usr/bin/env sh
-#      $NetBSD: build.sh,v 1.248 2011/09/09 13:29:23 apb Exp $
+#      $NetBSD: build.sh,v 1.249 2011/09/09 18:48:34 apb Exp $
 #
 # Copyright (c) 2001-2011 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -29,15 +29,234 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 #
-# Top level build wrapper, for a system containing no tools.
+# Top level build wrapper, to build or cross-build NetBSD.
+#
+
+#
+# {{{ Begin shell feature tests.
+#
+# We try to determine whether or not this script is being run under
+# a shell that supports the features that we use.  If not, we try to
+# re-exec the script under another shell.  If we can't find another
+# suitable shell, then we print a message and exit.
+#
+
+errmsg=''              # error message, if not empty
+shelltest=false                # if true, exit after testing the shell
+re_exec_allowed=true   # if true, we may exec under another shell
+
+# Parse special command line options in $1.  These special options are
+# for internal use only, are not documented, and are not valid anywhere
+# other than $1.
+case "$1" in
+"--shelltest")
+    shelltest=true
+    re_exec_allowed=false
+    shift
+    ;;
+"--no-re-exec")
+    re_exec_allowed=false
+    shift
+    ;;
+esac
+
+# Solaris /bin/sh, and other SVR4 shells, do not support "!".
+# This is the first feature that we test, because subsequent
+# tests use "!".
+#
+if test -z "$errmsg"; then
+    if ( eval '! false' ) >/dev/null 2>&1 ; then
+       :
+    else
+       errmsg='Shell does not support "!".'
+    fi
+fi
+
+# Does the shell support functions?
+#
+if test -z "$errmsg"; then
+    if ! (
+       eval 'somefunction() { : ; }'
+       ) >/dev/null 2>&1
+    then
+       errmsg='Shell does not support functions.'
+    fi
+fi
+
+# Does the shell support the "local" keyword for variables in functions?
+#
+# Local variables are not required by SUSv3, but some scripts run during
+# the NetBSD build use them.
+#
+# ksh93 fails this test; it uses an incompatible syntax involving the
+# keywords 'function' and 'typeset'.
+#
+if test -z "$errmsg"; then
+    if ! (
+       eval 'f() { local v=2; }; v=1; f && test x"$v" = x"1"'
+       ) >/dev/null 2>&1
+    then
+       errmsg='Shell does not support the "local" keyword in functions.'
+    fi
+fi
+
+# Does the shell support ${var%suffix}, ${var#prefix}, and their variants?
+#
+# We don't bother testing for ${var+value}, ${var-value}, or their variants,
+# since shells without those are sure to fail other tests too.
+#
+if test -z "$errmsg"; then
+    if ! (
+       eval 'var=a/b/c ;
+             test x"${var#*/};${var##*/};${var%/*};${var%%/*}" = \
+                  x"b/c;c;a/b;a" ;'
+       ) >/dev/null 2>&1
+    then
+       errmsg='Shell does not support "${var%suffix}" or "${var#prefix}".'
+    fi
+fi
+
+# Does the shell support IFS?
+#
+# zsh in normal mode (as opposed to "emulate sh" mode) fails this test.
+#
+if test -z "$errmsg"; then
+    if ! (
+       eval 'IFS=: ; v=":a b::c" ; set -- $v ; IFS=+ ;
+               test x"$#;$1,$2,$3,$4;$*" = x"4;,a b,,c;+a b++c"'
+       ) >/dev/null 2>&1
+    then
+       errmsg='Shell does not support IFS word splitting.'
+    fi
+fi
+
+# Does the shell support ${1+"$@"}?
+#
+# Some versions of zsh fail this test, even in "emulate sh" mode.
 #
-# This script should run on any POSIX-compliant shell.  If the
-# first "sh" found in the PATH is a POSIX-compliant shell, then
-# you should not need to take any special action.  Otherwise, you
-# should set the environment variable HOST_SH to a POSIX-compliant
-# shell, and invoke build.sh with that shell.  (Depending on your
-# system, one of /bin/ksh, /usr/local/bin/bash, or /usr/xpg4/bin/sh
-# might be a suitable shell.)
+if test -z "$errmsg"; then
+    if ! (
+       eval 'set -- "a a a" "b b b"; set -- ${1+"$@"};
+             test x"$#;$1;$2" = x"2;a a a;b b b";'
+       ) >/dev/null 2>&1
+    then
+       errmsg='Shell does not support ${1+"$@"}.'
+    fi
+fi
+
+# Does the shell support $(...) command substitution?
+#
+if test -z "$errmsg"; then
+    if ! (
+       eval 'var=$(echo abc); test x"$var" = x"abc"'
+       ) >/dev/null 2>&1
+    then
+       errmsg='Shell does not support "$(...)" command substitution.'
+    fi
+fi
+
+# Does the shell support $(...) command substitution with
+# unbalanced parentheses?
+#
+# Some shells known to fail this test are:  NetBSD /bin/ksh (as of 2009-12),
+# bash-3.1, pdksh-5.2.14, zsh-4.2.7 in "emulate sh" mode.
+#
+if test -z "$errmsg"; then
+    if ! (
+       eval 'var=$(case x in x) echo abc;; esac); test x"$var" = x"abc"'
+       ) >/dev/null 2>&1
+    then
+       # XXX: This test is ignored because so many shells fail it; instead,
+       #      the NetBSD build avoids using the problematic construct.
+       : ignore 'Shell does not support "$(...)" with unbalanced ")".'
+    fi
+fi
+
+# Does the shell support getopts or getopt?
+#
+if test -z "$errmsg"; then
+    if ! (
+       eval 'type getopts || type getopt'
+       ) >/dev/null 2>&1
+    then
+       errmsg='Shell does not support getopts or getopt.'
+    fi
+fi
+
+#
+# If shelltest is true, exit now, reporting wheher or not the shell is good.
+#
+if $shelltest; then
+    if test -n "$errmsg"; then
+       echo >&2 "$0: $errmsg"
+       exit 1
+    else
+       exit 0
+    fi
+fi
+
+#
+# If the shell was bad, try to exec a better shell, or report an error.
+#
+# Loops are broken by passing an extra "--no-re-exec" flag to the new
+# instance of this script.
+#
+if test -n "$errmsg"; then
+    if $re_exec_allowed; then
+       for othershell in \
+           "${HOST_SH}" /usr/xpg4/bin/sh ksh ksh88 mksh pdksh bash dash
+           # NOTE: some shells known not to work are:
+           # any shell using csh syntax;
+           # Solaris /bin/sh (missing many modern features);
+           # ksh93 (incompatible syntax for local variables);
+           # zsh (many differences, unless run in compatibility mode).
+       do
+           test -n "$othershell" || continue
+           if eval 'type "$othershell"' >/dev/null 2>&1 \
+               && "$othershell" "$0" --shelltest >/dev/null 2>&1
+           then
+               cat <<EOF
+$0: $errmsg
+$0: Retrying under $othershell
+EOF
+               HOST_SH="$othershell"
+               export HOST_SH
+               exec $othershell "$0" --no-re-exec "$@" # avoid ${1+"$@"}
+           fi
+           # If HOST_SH was set, but failed the test above,
+           # then give up without trying any other shells.
+           test x"${othershell}" = x"${HOST_SH}" && break
+       done
+    fi
+
+    #
+    # If we get here, then the shell is bad, and we either could not
+    # find a replacement, or were not allowed to try a replacement.
+    #



Home | Main Index | Thread Index | Old Index