aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/change.sh10
-rwxr-xr-xscripts/genconfig.sh91
-rwxr-xr-xscripts/git-static-index.sh28
-rw-r--r--scripts/help.txt3
-rwxr-xr-xscripts/install.sh9
-rwxr-xr-xscripts/make.sh247
-rwxr-xr-xscripts/mcm-buildall.sh13
-rw-r--r--scripts/mkflags.c34
-rwxr-xr-xscripts/mkroot.sh293
-rwxr-xr-xscripts/mkstatus.py2
-rw-r--r--scripts/portability.sh22
-rwxr-xr-xscripts/record-commands42
-rwxr-xr-xscripts/root/dropbear58
-rwxr-xr-xscripts/root/plumbing45
-rw-r--r--scripts/runtest.sh224
-rwxr-xr-xscripts/single.sh10
-rwxr-xr-xscripts/test.sh20
17 files changed, 311 insertions, 840 deletions
diff --git a/scripts/change.sh b/scripts/change.sh
index 74889aa7..dda5ee14 100755
--- a/scripts/change.sh
+++ b/scripts/change.sh
@@ -9,15 +9,11 @@ ${HOSTCC:-cc} -I . scripts/install.c -o "$UNSTRIPPED"/instlist &&
export PREFIX=${PREFIX:-change/} &&
mkdir -p "$PREFIX" || exit 1
-# Build all the commands standalone except:
-
-# sh - shell builtins like "cd" and "exit" need the multiplexer
-# help - needs to know what other commands are enabled (use command --help)
-
-for i in $("$UNSTRIPPED"/instlist | egrep -vw "sh|help")
+# Build all the commands standalone
+for i in $("$UNSTRIPPED"/instlist)
do
echo -n " $i" &&
- scripts/single.sh $i > /dev/null 2>$PREFIX/${i}.bad &&
+ scripts/single.sh $i &>$PREFIX/${i}.bad &&
rm $PREFIX/${i}.bad || echo -n '*'
done
echo
diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh
index 034aa376..52a9c259 100755
--- a/scripts/genconfig.sh
+++ b/scripts/genconfig.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# This has to be a separate file from scripts/make.sh so it can be called
-# before menuconfig. (It's called again from scripts/make.sh just to be sure.)
+# before menuconfig. (It's called again from scripts/make.sh just to be sure.)
source scripts/portability.sh
@@ -18,55 +18,11 @@ probesymbol()
{
probecc "${@:2}" 2>/dev/null && DEFAULT=y || DEFAULT=n
rm a.out 2>/dev/null
- echo -e "config $1\n\tbool" || exit 1
- echo -e "\tdefault $DEFAULT\n" || exit 1
+ echo -e "config $1\n\tbool\n\tdefault $DEFAULT\n" || exit 1
}
probeconfig()
{
- # Probe for container support on target
- probesymbol TOYBOX_CONTAINER << EOF
- #include <stdio.h>
- #include <sys/syscall.h>
- #include <linux/sched.h>
- int x=CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET;
-
- int main(int argc, char *argv[]){printf("%d", x+SYS_unshare+ SYS_setns);}
-EOF
-
- probesymbol TOYBOX_FIFREEZE -c << EOF
- #include <linux/fs.h>
- #ifndef FIFREEZE
- #error nope
- #endif
-EOF
-
- # Work around some uClibc limitations
- probesymbol TOYBOX_ICONV -c << EOF
- #include "iconv.h"
-EOF
-
- # Android and some other platforms miss utmpx
- probesymbol TOYBOX_UTMPX -c << EOF
- #include <utmpx.h>
- #ifndef BOOT_TIME
- #error nope
- #endif
- int main(int argc, char *argv[]) {
- struct utmpx *a;
- if (0 != (a = getutxent())) return 0;
- return 1;
- }
-EOF
-
- # Android is missing shadow.h
- probesymbol TOYBOX_SHADOW -c << EOF
- #include <shadow.h>
- int main(int argc, char *argv[]) {
- struct spwd *a = getspnam("root"); return 0;
- }
-EOF
-
# Some commands are android-specific
probesymbol TOYBOX_ON_ANDROID -c << EOF
#ifndef __ANDROID__
@@ -74,45 +30,12 @@ EOF
#endif
EOF
- probesymbol TOYBOX_ANDROID_SCHEDPOLICY << EOF
- #include <processgroup/sched_policy.h>
-
- int main(int argc,char *argv[]) { get_sched_policy_name(0); }
-EOF
-
# nommu support
probesymbol TOYBOX_FORK << EOF
#include <unistd.h>
int main(int argc, char *argv[]) { return fork(); }
EOF
echo -e '\tdepends on !TOYBOX_FORCE_NOMMU'
-
- probesymbol TOYBOX_PRLIMIT << EOF
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- int prlimit(pid_t pid, int resource, const struct rlimit *new_limit,
- struct rlimit *old_limit);
- int main(int argc, char *argv[]) { prlimit(0, 0, 0, 0); }
-EOF
-
- probesymbol TOYBOX_GETRANDOM << EOF
- #include <sys/random.h>
- int main(void) { char buf[100]; getrandom(buf, 100, 0); }
-EOF
-
- # glibc requires #define GNU to get the wrapper for this Linux system call,
- # so just use syscall().
- probesymbol TOYBOX_COPYFILERANGE << EOF
- #include <sys/syscall.h>
- #include <unistd.h>
- int main(void) { syscall(__NR_copy_file_range, 0, 0, 1, 0, 123, 0); }
-EOF
- probesymbol TOYBOX_HASTIMERS << EOF
- #include <signal.h>
- #include <time.h>
- int main(void) {void *x=0;timer_create(CLOCK_MONOTONIC,x,x);}
-EOF
}
genconfig()
@@ -150,8 +73,7 @@ toys()
$SED -En 's/([^:]*):.*(OLD|NEW)TOY\( *([a-zA-Z][^,]*) *,.*/\1:\3/p'
}
-WORKING=
-PENDING=
+WORKING= PENDING= EXAMPLE=
toys toys/*/*.c | (
while IFS=":" read FILE NAME
do
@@ -160,12 +82,13 @@ do
[ "$NAME" == sh ] && FILE="toys/*/*.c"
echo -e "$NAME: $FILE *.[ch] lib/*.[ch]\n\tscripts/single.sh $NAME\n"
echo -e "test_$NAME:\n\tscripts/test.sh $NAME\n"
- [ "${FILE/pending//}" != "$FILE" ] &&
- PENDING="$PENDING $NAME" ||
+ [ "${FILE/example//}" != "$FILE" ] && EXAMPLE="$EXAMPLE $NAME" ||
+ [ "${FILE/pending//}" != "$FILE" ] && PENDING="$PENDING $NAME" ||
WORKING="$WORKING $NAME"
done &&
echo -e "clean::\n\t@rm -f $WORKING $PENDING" &&
echo -e "list:\n\t@echo $(echo $WORKING | tr ' ' '\n' | sort | xargs)" &&
-echo -e "list_pending:\n\t@echo $(echo $PENDING | tr ' ' '\n' | sort | xargs)" &&
+echo -e "list_example:\n\t@echo $(echo $EXAMPLE | tr ' ' '\n' | sort | xargs)"&&
+echo -e "list_pending:\n\t@echo $(echo $PENDING | tr ' ' '\n' | sort | xargs)"&&
echo -e ".PHONY: $WORKING $PENDING" | $SED 's/ \([^ ]\)/ test_\1/g'
) > .singlemake
diff --git a/scripts/git-static-index.sh b/scripts/git-static-index.sh
new file mode 100755
index 00000000..fb9ac4e5
--- /dev/null
+++ b/scripts/git-static-index.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Create very basic index.html and commit links for a static git archive
+
+mkdir -p commit
+git log --pretty=%H | while read i
+do
+ [ -e commit/$i ] && break
+ git format-patch -1 --stdout $i > commit/$i
+ ln -sf $i commit/${i::12}
+done
+
+echo '<html><body><font face=monospace><table border=1 cellpadding=2>'
+echo '<tr valign=top><td>commit</td><td>author</td><td>date</td><td>description</td></tr>'
+git log --pretty='%H%n%an<%ae>%n%ad%n%s' --date=format:'%r<br />%d-%m-%Y' | while read HASH
+do
+ HASH="${HASH::12}"
+ read AUTHOR
+ AUTHOR1="${AUTHOR/<*/}"
+ AUTHOR1="${AUTHOR1::17}"
+ AUTHOR2="&lt;${AUTHOR/*</}"
+ AUTHOR2="${AUTHOR2::20}"
+ read DATE
+ DATE="${DATE/ /&nbsp;}"
+ read DESC
+ echo "<tr valign=top><td><a href=commit/$HASH>$HASH</a></td><td>$AUTHOR1<br />$AUTHOR2</td><td>$DATE</td><td>$DESC</td></tr>"
+done
+echo "</table></body></html>"
diff --git a/scripts/help.txt b/scripts/help.txt
index d369e47a..feca0a8d 100644
--- a/scripts/help.txt
+++ b/scripts/help.txt
@@ -1,6 +1,7 @@
toybox - Build toybox.
COMMANDNAME - Build individual toybox command as a standalone binary.
list - List COMMANDNAMEs you can build standalone.
+ list_example - List example commands (often used by the test suite)
list_pending - List unfinished COMMANDNAMEs out of toys/pending.
change - Build each command standalone under change/.
baseline - Create toybox_old for use by bloatcheck.
@@ -22,6 +23,6 @@
LINUX= build kernel from this source, configured for qemu
run_root - boot toyroot under qemu, I.E. cd root/$CROSS && ./qemu-*.sh
-example: make defconfig toybox install CFLAGS="--static" CROSS_COMPILE=armv5l-
+example: make defconfig toybox install LDFLAGS="--static" CROSS_COMPILE=armv5l-
or : make root run_root CROSS=sh4 LINUX=~/linux
diff --git a/scripts/install.sh b/scripts/install.sh
index 842ff9b0..38d9dcec 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -31,7 +31,6 @@ done
echo "Compile instlist..."
-NOBUILD=1 scripts/make.sh
$DEBUG $HOSTCC -I . scripts/install.c -o "$UNSTRIPPED"/instlist || exit 1
COMMANDS="$("$UNSTRIPPED"/instlist $LONG_PATH)"
@@ -106,11 +105,9 @@ done
# The following are commands toybox should provide, but doesn't yet.
# For now symlink the host version. This list must go away by 1.0.
-PENDING="dd diff expr git tr vi wget bash sh xzcat bc ar gzip ftpd less awk unxz bison flex make nm"
-
-# "gcc" can go away if the kernel guys merge my patch:
-# http://lkml.iu.edu/hypermail/linux/kernel/2202.0/01505.html
-TOOLCHAIN="as cc ld gcc objdump"
+PENDING="expr git tr bash sh gzip awk bison flex make"
+TOOLCHAIN="as cc ld objdump"
+TOOLCHAIN+="bc gcc" # both patched out but not in vanilla yet
# Tools needed to build packages
for i in $TOOLCHAIN $PENDING $HOST_EXTRA
diff --git a/scripts/make.sh b/scripts/make.sh
index b7bb6930..9de74192 100755
--- a/scripts/make.sh
+++ b/scripts/make.sh
@@ -1,83 +1,105 @@
#!/bin/bash
# Grab default values for $CFLAGS and such.
-
set -o pipefail
source scripts/portability.sh
-# Default to running one more parallel cc instance than we have processors
-: ${CPUS:=$(($(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null)+1))}
+# Shell functions called by the build
+
+DASHN=-n
+true & wait -n 2>/dev/null || { wait; unset DASHN; }
+ratelimit()
+{
+ if [ "$#" -eq 0 ]
+ then
+ [ -z "$DASHN" ] && PIDS="$PIDS$! "
+ [ $((++COUNT)) -lt $CPUS ] && return 0
+ fi
+ ((--COUNT))
+ if [ -n "$DASHN" ]
+ then
+ wait -n
+ DONE=$(($DONE+$?))
+ else
+ # MacOS uses an ancient version of bash which hasn't got "wait -n", and
+ # wait without arguments always returns 0 instead of process exit code.
+ # This keeps $CPUS less busy when jobs finish out of order.
+ wait ${PIDS%% *}
+ DONE=$(($DONE+$?))
+ PIDS=${PIDS#* }
+ fi
+
+ return $DONE
+}
# Respond to V= by echoing command lines as well as running them
-DOTPROG=
do_loudly()
{
- [ ! -z "$V" ] && echo "$@" || echo -n "$DOTPROG"
+ { [ -n "$V" ] && echo "$@" || echo -n "$DOTPROG" ; } >&2
"$@"
}
-# Is anything under directory $2 newer than file $1
+# Is anything under directory $2 newer than generated/$1 (or does it not exist)?
isnewer()
{
- CHECK="$1"
- shift
- [ ! -z "$(find "$@" -newer "$CHECK" 2>/dev/null || echo yes)" ]
+ [ -e "$GENDIR/$1" ] && [ -z "$(find "${@:2}" -newer "$GENDIR/$1")" ] &&
+ return 1
+ echo -n "${DIDNEWER:-$GENDIR/{}$1"
+ DIDNEWER=,
}
-echo "Generate headers from toys/*/*.c..."
-
-mkdir -p "$UNSTRIPPED"
-
-if isnewer "$GENDIR"/Config.in toys || isnewer "$GENDIR"/Config.in Config.in
-then
- echo "Extract configuration information from toys/*.c files..."
- scripts/genconfig.sh
-fi
+# Build a tool that runs on the host
+hostcomp()
+{
+ if [ ! -f "$UNSTRIPPED"/$1 ] || [ "$UNSTRIPPED"/$1 -ot scripts/$1.c ]
+ then
+ do_loudly $HOSTCC scripts/$1.c -o "$UNSTRIPPED"/$1 || exit 1
+ fi
+}
-# Create a list of all the commands toybox can provide. Note that the first
-# entry is out of order on purpose (the toybox multiplexer command must be the
-# first element of the array). The rest must be sorted in alphabetical order
-# for fast binary search.
+# Set/record build environment information
+compflags()
+{
+ [ -z "$VERSION" ] && [ -d ".git" ] && [ -n "$(which git 2>/dev/null)" ] &&
+ VERSION="-DTOYBOX_VERSION=\"$(git describe --tags --abbrev=12 2>/dev/null)\""
-if isnewer "$GENDIR"/newtoys.h toys
-then
- echo -n "$GENDIR/newtoys.h "
+ # VERSION and LIBRARIES volatile, changing either does not require a rebuild
+ echo '#!/bin/sh'
+ echo
+ echo "VERSION='$VERSION'"
+ echo "LIBRARIES='$(xargs 2>/dev/null < "$GENDIR/optlibs.dat")'"
+ echo "BUILD='${CROSS_COMPILE}${CC} $CFLAGS -I . $OPTIMIZE '\"\$VERSION\""
+ echo "LINK='$LDOPTIMIZE $LDFLAGS '\"\$LIBRARIES\""
+ echo "PATH='$PATH'"
+ echo "# Built from $KCONFIG_CONFIG"
+ echo
+}
- echo "USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))" \
- > "$GENDIR"/newtoys.h
- $SED -n -e 's/^USE_[A-Z0-9_]*(/&/p' toys/*/*.c \
- | $SED 's/\(.*TOY(\)\([^,]*\),\(.*\)/\2 \1\2,\3/' | sort -s -k 1,1 \
- | $SED 's/[^ ]* //' >> "$GENDIR"/newtoys.h
- [ $? -ne 0 ] && exit 1
-fi
+# Make sure rm -rf isn't gonna go funny
+B="$(readlink -f "$PWD")/" A="$(readlink -f "$GENDIR")" A="${A%/}"/
+[ "$A" == "${B::${#A}}" ] &&
+ { echo "\$GENDIR=$GENDIR cannot include \$PWD=$PWD"; exit 1; }
+unset A B DOTPROG DIDNEWER
-[ ! -z "$V" ] && echo "Which C files to build..."
+# Force full rebuild if our compiler/linker options changed
+cmp -s <(compflags|sed '5,8!d') <($SED '5,8!d' "$GENDIR"/build.sh 2>/dev/null)||
+ rm -rf "$GENDIR"/* # Keep symlink, delete contents
+mkdir -p "$UNSTRIPPED" "$(dirname $OUTNAME)" || exit 1
# Extract a list of toys/*/*.c files to compile from the data in $KCONFIG_CONFIG
# (First command names, then filenames with relevant {NEW,OLD}TOY() macro.)
-[ -d ".git" ] && [ ! -z "$(which git 2>/dev/null)" ] &&
- GITHASH="-DTOYBOX_VERSION=\"$(git describe --tags --abbrev=12 2>/dev/null)\""
+[ -n "$V" ] && echo -e "\nWhich C files to build..."
TOYFILES="$($SED -n 's/^CONFIG_\([^=]*\)=.*/\1/p' "$KCONFIG_CONFIG" | xargs | tr ' [A-Z]' '|[a-z]')"
TOYFILES="main.c $(egrep -l "TOY[(]($TOYFILES)[ ,]" toys/*/*.c | xargs)"
-BUILD="$(echo ${CROSS_COMPILE}${CC} $CFLAGS -I . $OPTIMIZE $GITHASH)"
if [ "${TOYFILES/pending//}" != "$TOYFILES" ]
then
echo -e "\n\033[1;31mwarning: using unfinished code from toys/pending\033[0m"
fi
-genbuildsh()
-{
- # Write a canned build line for use on crippled build machines.
-
- LLINK="$(echo $LDOPTIMIZE $LDFLAGS $(cat "$GENDIR"/optlibs.dat))"
- echo -e "#!/bin/sh\n\nPATH='$PATH'\nBUILD='$BUILD'\nLINK='$LLINK'\n"
- echo -e "\$BUILD lib/*.c $TOYFILES \$LINK -o $OUTNAME"
-}
-
-if ! cmp -s <(genbuildsh 2>/dev/null | head -n 5) \
- <(head -n 5 "$GENDIR"/build.sh 2>/dev/null | $SED '5s/ -o .*//')
+# Probe library list if our compiler/linker options changed
+if [ ! -e "$GENDIR"/optlibs.dat ]
then
echo -n "Library probe"
@@ -85,25 +107,53 @@ then
# compiler has no way to ignore a library that doesn't exist, so detect
# and skip nonexistent libraries for it.
- > "$GENDIR"/optlibs.dat
+ > "$GENDIR"/optlibs.new
+ [ -z "$V" ] && X=/dev/null || X=/dev/stderr
for i in util crypt m resolv selinux smack attr crypto z log iconv tls ssl
do
- echo "int main(int argc, char *argv[]) {return 0;}" | \
- ${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc - -o "$GENDIR"/libprobe -l$i > /dev/null 2>/dev/null &&
- echo -l$i >> "$GENDIR"/optlibs.dat
- echo -n .
+ do_loudly ${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc - -l$i >>$X 2>&1 \
+ -o "$UNSTRIPPED"/libprobe <<<"int main(int argc,char*argv[]){return 0;}"&&
+ do_loudly echo -n ' '-l$i >> "$GENDIR"/optlibs.new
done
- rm -f "$GENDIR"/libprobe
+ unset X
+ rm -f "$UNSTRIPPED"/libprobe
+ mv "$GENDIR"/optlibs.{new,dat} || exit 1
echo
fi
-genbuildsh > "$GENDIR"/build.sh && chmod +x "$GENDIR"/build.sh || exit 1
+# Write build variables (and set them locally), then append build invocation.
+compflags > "$GENDIR"/build.sh && source "$GENDIR/build.sh" &&
+ echo -e "\$BUILD lib/*.c $TOYFILES \$LINK -o $OUTNAME" >> "$GENDIR"/build.sh&&
+ chmod +x "$GENDIR"/build.sh || exit 1
-#TODO: "make $SED && make" doesn't regenerate config.h because diff .config
-if true #isnewer "$GENDIR"/config.h "$KCONFIG_CONFIG"
+if isnewer Config.in toys || isnewer Config.in Config.in
then
- echo "Make $GENDIR/config.h from $KCONFIG_CONFIG."
+ scripts/genconfig.sh
+fi
+
+# Does .config need dependency recalculation because toolchain changed?
+A="$($SED -n '/^config .*$/h;s/default \(.\)/\1/;T;H;g;s/config \([^\n]*\)[^yn]*\(.\)/\1=\2/p' "$GENDIR"/Config.probed | sort)"
+B="$(egrep "^CONFIG_($(echo "$A" | sed 's/=[yn]//' | xargs | tr ' ' '|'))=" "$KCONFIG_CONFIG" | $SED 's/^CONFIG_//' | sort)"
+A="$(echo "$A" | grep -v =n)"
+[ "$A" != "$B" ] &&
+ { echo -e "\nWarning: Config.probed changed, run 'make oldconfig'" >&2; }
+unset A B
+
+# Create a list of all the commands toybox can provide.
+if isnewer newtoys.h toys
+then
+ # The multiplexer is the first element in the array
+ echo "USE_TOYBOX(NEWTOY(toybox, 0, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))" \
+ > "$GENDIR"/newtoys.h
+ # Sort rest by name for binary search (copy name to front, sort, remove copy)
+ $SED -n 's/^\(USE_[^(]*(.*TOY(\)\([^,]*\)\(,.*\)/\2 \1\2\3/p' toys/*/*.c \
+ | sort -s -k 1,1 | $SED 's/[^ ]* //' >> "$GENDIR"/newtoys.h
+ [ $? -ne 0 ] && exit 1
+fi
+#TODO: "make $SED && make" doesn't regenerate config.h because diff .config
+if true #isnewer config.h "$KCONFIG_CONFIG"
+then
# This long and roundabout sed invocation is to make old versions of sed
# happy. New ones have '\n' so can replace one line with two without all
# the branches and tedious mucking about with hyperspace.
@@ -130,20 +180,14 @@ then
$KCONFIG_CONFIG > "$GENDIR"/config.h || exit 1
fi
-if [ ! -f "$GENDIR"/mkflags ] || [ "$GENDIR"/mkflags -ot scripts/mkflags.c ]
-then
- do_loudly $HOSTCC scripts/mkflags.c -o "$UNSTRIPPED"/mkflags || exit 1
-fi
-
# Process config.h and newtoys.h to generate FLAG_x macros. Note we must
# always #define the relevant macro, even when it's disabled, because we
# allow multiple NEWTOY() in the same C file. (When disabled the FLAG is 0,
# so flags&0 becomes a constant 0 allowing dead code elimination.)
-if isnewer "$GENDIR"/flags.h toys "$KCONFIG_CONFIG"
+hostcomp mkflags
+if isnewer flags.h toys "$KCONFIG_CONFIG"
then
- echo -n "$GENDIR/flags.h "
-
# Parse files through C preprocessor twice, once to get flags for current
# .config and once to get flags for allyesconfig
for I in A B
@@ -187,18 +231,16 @@ function getglobals()
{
for i in toys/*/*.c
do
- # alas basename -s isn't in posix yet.
- NAME="$(echo $i | $SED 's@.*/\(.*\)\.c@\1@')"
+ NAME=${i##*/} NAME=${NAME%\.c}
DATA="$($SED -n -e '/^GLOBALS(/,/^)/b got;b;:got' \
-e 's/^GLOBALS(/_data {/' \
-e 's/^)/};/' -e 'p' $i)"
- [ ! -z "$DATA" ] && echo -e "// $i\n\nstruct $NAME$DATA\n"
+ [ -n "$DATA" ] && echo -e "// $i\n\nstruct $NAME$DATA\n"
done
}
-if isnewer "$GENDIR"/globals.h toys
+if isnewer globals.h toys
then
- echo -n "$GENDIR/globals.h "
GLOBSTRUCT="$(getglobals)"
(
echo "$GLOBSTRUCT"
@@ -210,53 +252,40 @@ then
) > "$GENDIR"/globals.h
fi
-if [ ! -f "$UNSTRIPPED"/mktags ] || [ "$UNSTRIPPED"/mktags -ot scripts/mktags.c ]
-then
- do_loudly $HOSTCC scripts/mktags.c -o "$UNSTRIPPED"/mktags || exit 1
-fi
-
-if isnewer "$GENDIR"/tags.h toys
+hostcomp mktags
+if isnewer tags.h toys
then
- echo -n "$GENDIR/tags.h "
-
$SED -n '/TAGGED_ARRAY(/,/^)/{s/.*TAGGED_ARRAY[(]\([^,]*\),/\1/;p}' \
toys/*/*.c lib/*.c | "$UNSTRIPPED"/mktags > "$GENDIR"/tags.h
fi
-if [ ! -f "$UNSTRIPPED"/config2help ] || [ "$UNSTRIPPED"/config2help -ot scripts/config2help.c ]
+hostcomp config2help
+if isnewer help.h "$GENDIR"/Config.in
then
- do_loudly $HOSTCC scripts/config2help.c -o "$UNSTRIPPED"/config2help || exit 1
-fi
-if isnewer "$GENDIR"/help.h "$GENDIR"/Config.in
-then
- echo "$GENDIR/help.h"
"$UNSTRIPPED"/config2help Config.in $KCONFIG_CONFIG > "$GENDIR"/help.h || exit 1
fi
+[ -z "$DIDNEWER" ] || echo }
-[ ! -z "$NOBUILD" ] && exit 0
+[ -n "$NOBUILD" ] && exit 0
-echo -n "Compile $OUTNAME"
-[ ! -z "$V" ] && echo
+echo "Compile $OUTNAME"
DOTPROG=.
-# This is a parallel version of: do_loudly $BUILD $FILES $LLINK || exit 1
+# This is a parallel version of: do_loudly $BUILD lib/*.c $TOYFILES $LINK
-# Any headers newer than the oldest generated/obj file?
+# Build all if oldest generated/obj file isn't newer than all header files.
X="$(ls -1t "$GENDIR"/obj/* 2>/dev/null | tail -n 1)"
-# TODO: redo this
-if [ ! -e "$X" ] || [ ! -z "$(find toys -name "*.h" -newer "$X")" ]
+if [ ! -e "$X" ] || [ -n "$(find toys -name "*.h" -newer "$X")" ]
then
rm -rf "$GENDIR"/obj && mkdir -p "$GENDIR"/obj || exit 1
else
+ # always redo toy_list[] and help_data[]
rm -f "$GENDIR"/obj/main.o || exit 1
fi
# build each generated/obj/*.o file in parallel
-unset PENDING LNKFILES CLICK
-DONE=0
-COUNT=0
-
+PENDING= LNKFILES= CLICK= DONE=0 COUNT=0
for i in lib/*.c click $TOYFILES
do
[ "$i" == click ] && CLICK=1 && continue
@@ -266,30 +295,25 @@ do
OUT="$GENDIR/obj/${X%%.c}.o"
LNKFILES="$LNKFILES $OUT"
- # Library files don't need to be rebuilt if older than .config.
- # ($TOYFILES contents can depend on CONFIG symbols, lib/*.c never should.)
-
+ # Library files don't get rebuilt if older than .config, but commands do.
[ "$OUT" -nt "$i" ] && [ -z "$CLICK" -o "$OUT" -nt "$KCONFIG_CONFIG" ] &&
continue
do_loudly $BUILD -c $i -o $OUT &
- # ratelimit to $CPUS many parallel jobs, detecting errors
- [ $((++COUNT)) -ge $CPUS ] && { wait $DASHN; DONE=$?; : $((--COUNT)); }
- [ $DONE -ne 0 ] && break
+ ratelimit || break
done
-# wait for all background jobs, detecting errors
-while [ $((COUNT--)) -gt 0 ]
+# wait for all background jobs, detecting errors
+while [ "$COUNT" -gt 0 ]
do
- wait $DASHN;
- DONE=$((DONE+$?))
+ ratelimit done
done
[ $DONE -ne 0 ] && exit 1
UNSTRIPPED="$UNSTRIPPED/${OUTNAME/*\//}"
-do_loudly $BUILD $LNKFILES $LLINK -o "$UNSTRIPPED" || exit 1
-if [ ! -z "$NOSTRIP" ] ||
+do_loudly $BUILD $LNKFILES $LINK -o "$UNSTRIPPED" || exit 1
+if [ -n "$NOSTRIP" ] ||
! do_loudly ${CROSS_COMPILE}${STRIP} "$UNSTRIPPED" -o "$OUTNAME"
then
[ -z "$NOSTRIP" ] && echo "strip failed, using unstripped"
@@ -297,10 +321,9 @@ then
cp "$UNSTRIPPED" "$OUTNAME" || exit 1
fi
-# gcc 4.4's strip command is buggy, and doesn't set the executable bit on
-# its output the way SUSv4 suggests it do so. While we're at it, make sure
-# we don't have the "w" bit set so things like bzip2's "cp -f" install don't
-# overwrite our binary through the symlink.
+# Remove write bit set so buggy installs (like bzip's) don't overwrite the
+# multiplexer binary via truncate-and-write through a symlink.
do_loudly chmod 555 "$OUTNAME" || exit 1
-echo
+# Ensure make wrapper sees success return code
+[ -z "$V" ] && echo >&2 || true
diff --git a/scripts/mcm-buildall.sh b/scripts/mcm-buildall.sh
index cac41372..11a10136 100755
--- a/scripts/mcm-buildall.sh
+++ b/scripts/mcm-buildall.sh
@@ -91,7 +91,11 @@ make_toolchain()
# Prevent cross compiler reusing dynamically linked host build files for
# $BOOTSTRAP arch
- [ -z "$TYPE" ] && make clean
+ [ -z "$TYPE" ] && {
+ [ -e musl-git-master ] && mv musl-git-master keep-this-dir
+ make clean
+ [ -e keep-this-dir ] && mv keep-this-dir musl-git-master
+ }
if [ "$TYPE" == native ]
then
@@ -138,13 +142,6 @@ fix_nommu()
PP=patches/musl-"$(sed -n 's/MUSL_VER[ \t]*=[ \t]*//p' Makefile)"
mkdir -p "$PP" &&
cat > "$PP"/0001-nommu.patch << 'EOF'
---- a/include/features.h
-+++ b/include/features.h
-@@ -3,2 +3,4 @@
-
-+#define __MUSL__ 1
-+
- #if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
--- a/src/legacy/daemon.c
+++ b/src/legacy/daemon.c
@@ -17,3 +17,3 @@
diff --git a/scripts/mkflags.c b/scripts/mkflags.c
index 6560db50..79cf1656 100644
--- a/scripts/mkflags.c
+++ b/scripts/mkflags.c
@@ -1,5 +1,5 @@
-// Take three word input lines on stdin and produce flag #defines to stdout.
-// The three words on each input lnie are command name, option string with
+// Read three word input lines from stdin and produce flag #defines to stdout.
+// The three words on each input line are command name, option string with
// current config, option string from allyesconfig. The three are space
// separated and the last two are in double quotes.
@@ -14,9 +14,8 @@
#include <ctype.h>
struct flag {
- struct flag *next;
+ struct flag *next, *lopt;
char *command;
- struct flag *lopt;
};
int chrtype(char c)
@@ -38,7 +37,7 @@ int chrtype(char c)
char *mark_gaps(char *flags, char *all)
{
char *n, *new, c;
- int bare = 2;
+ int bare = 1;
// Shell feeds in " " for blank args, leading space not meaningful.
while (isspace(*flags)) flags++;
@@ -50,7 +49,6 @@ char *mark_gaps(char *flags, char *all)
if (*all == '(') {
int len = 0;
- if (bare) bare = 1;
while (all[len]) if (all[len++] == ')') break;
if (strncmp(flags, all, len)) {
// bare longopts need their own skip placeholders
@@ -95,6 +93,10 @@ struct flag *digest(char *string)
if (*string == '(') {
struct flag *new = calloc(sizeof(struct flag), 1);
+ if (string[1]==')') {
+ fprintf(stderr, "empty () longopt in '%s'", err);
+ exit(1);
+ }
new->command = ++string;
// Attach longopt to previous short opt, if any.
@@ -131,6 +133,10 @@ struct flag *digest(char *string)
} else {
struct flag *new = calloc(sizeof(struct flag), 1);
+ if (string[0]=='~' && string[1]!='(') {
+ fprintf(stderr, "~ without (longopt) in '%s'", err);
+ exit(1);
+ }
new->command = string++;
new->next = list;
list = new;
@@ -164,9 +170,8 @@ int main(int argc, char *argv[])
// See "intentionally crappy", above.
if (!(out = outbuf)) return 1;
- printf("#undef FORCED_FLAG\n#undef FORCED_FLAGLL\n"
- "#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1\n#define FORCED_FLAGLL 1ULL\n"
- "#else\n#define FORCED_FLAG 0\n#define FORCED_FLAGLL 0LL\n#endif\n\n");
+ printf("#undef FORCED_FLAG\n#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1LL\n"
+ "#else\n#define FORCED_FLAG 0LL\n#endif\n\n");
for (;;) {
struct flag *flist, *aflist, *offlist;
@@ -208,7 +213,8 @@ int main(int argc, char *argv[])
while (offlist) {
char *s = (char []){0, 0, 0, 0};
- if (!offlist->command) s = offlist->lopt->command;
+ if (!offlist->command || *offlist->command=='~')
+ s = offlist->lopt->command;
else {
*s = *offlist->command;
if (127 < (unsigned char)*s) sprintf(s, "X%02X", 127&*s);
@@ -223,11 +229,11 @@ int main(int argc, char *argv[])
out += strlen(out);
while (aflist) {
- char *llstr = bit>30 ? "LL" : "", *s = (char []){0, 0, 0, 0};
+ char *s = (char []){0, 0, 0, 0};
int enabled = 0;
// Output flag macro for bare longopts
- if (!aflist->command) {
+ if (!aflist->command || *aflist->command=='~') {
s = aflist->lopt->command;
if (flist && flist->lopt &&
!strcmp(flist->lopt->command, aflist->lopt->command)) enabled++;
@@ -238,8 +244,8 @@ int main(int argc, char *argv[])
if (flist && flist->command && *aflist->command == *flist->command)
enabled++;
}
- out += sprintf(out, "#define FLAG_%s (%s%s<<%d)\n",
- s, enabled ? "1" : "FORCED_FLAG", llstr, bit++);
+ out += sprintf(out, "#define FLAG_%s (%s<<%d)\n",
+ s, enabled ? "1LL" : "FORCED_FLAG", bit++);
aflist = aflist->next;
if (enabled) flist = flist->next;
}
diff --git a/scripts/mkroot.sh b/scripts/mkroot.sh
index c099bec7..2ac634bc 100755
--- a/scripts/mkroot.sh
+++ b/scripts/mkroot.sh
@@ -1,292 +1 @@
-#!/bin/bash
-
-# ------------------------------ Part 1: Setup -------------------------------
-
-# Clear environment variables by restarting script w/bare minimum passed through
-[ -z "$NOCLEAR" ] && exec env -i NOCLEAR=1 HOME="$HOME" PATH="$PATH" \
- LINUX="$LINUX" CROSS="$CROSS" CROSS_COMPILE="$CROSS_COMPILE" "$0" "$@"
-
-# assign command line NAME=VALUE args to env vars, the rest are packages
-for i in "$@"; do
- [ "${i/=/}" != "$i" ] && export "$i" || { [ "$i" != -- ] && PKG="$PKG $i"; }
-done
-
-# Set default directory locations (overrideable from command line)
-: ${LOG:=${BUILD:=${TOP:=$PWD/root}/build}/log} ${AIRLOCK:=$BUILD/airlock}
-: ${CCC:=$PWD/ccc} ${PKGDIR:=$PWD/scripts/root}
-
-# useful functions
-announce() { echo -e "\033]2;$CROSS $*\007\n=== $*"; }
-die() { echo "$@" >&2; exit 1; }
-
-# ----- Are we cross compiling (via CROSS_COMPILE= or CROSS=)
-
-if [ -n "$CROSS_COMPILE" ]; then
- CROSS_COMPILE="$(realpath -s "$CROSS_COMPILE")" # airlock needs absolute path
- [ -z "$CROSS" ] && CROSS=${CROSS_COMPILE/*\//} CROSS=${CROSS/-*/}
-
-elif [ -n "$CROSS" ]; then # CROSS=all/allnonstop/$ARCH else list known $ARCHes
- [ ! -d "$CCC" ] && die "No ccc symlink to compiler directory."
- TARGETS="$(ls "$CCC" | sed -n 's/-.*//p' | sort -u)"
-
- if [ "${CROSS::3}" == all ]; then # loop calling ourselves for each target
- for i in $TARGETS; do
- "$0" "$@" CROSS=$i || [ "$CROSS" == allnonstop ] || exit 1
- done; exit
-
- else # Find matching cross compiler under ccc/ else list available targets
- CROSS_COMPILE="$(echo "$CCC/$CROSS"-*cross/bin/"$CROSS"*-cc)" # wildcard
- [ ! -e "$CROSS_COMPILE" ] && echo $TARGETS && exit # list available targets
- CROSS_COMPILE="${CROSS_COMPILE%cc}" # trim to prefix for cc/ld/as/nm/strip
- fi
-fi
-
-# Verify selected compiler works
-${CROSS_COMPILE}cc --static -xc - -o /dev/null <<< "int main(void){return 0;}"||
- die "${CROSS_COMPILE}cc can't create static binaries"
-
-# When not cross compiling set CROSS=host. Create per-target output directory
-: ${CROSS:=host} ${OUTPUT:=$TOP/$CROSS}
-
-# ----- Create hermetic build environment
-
-if [ -z "$NOAIRLOCK"] && [ -n "$CROSS_COMPILE" ]; then
- # When cross compiling set host $PATH to binaries with known behavior by
- # - building a host toybox later builds use as their command line
- # - cherry-picking specific commands from old path via symlink
- if [ ! -e "$AIRLOCK/toybox" ]; then
- announce "airlock" &&
- PREFIX="$AIRLOCK" KCONFIG_CONFIG=.singleconfig_airlock CROSS_COMPILE= \
- make clean defconfig toybox install_airlock && # see scripts/install.sh
- rm .singleconfig_airlock || exit 1
- fi
- export PATH="$AIRLOCK"
-fi
-
-# Create per-target work directories
-MYBUILD="$BUILD/${CROSS}-tmp" && rm -rf "$MYBUILD" &&
-mkdir -p "$MYBUILD" "$OUTPUT" "$LOG" || exit 1
-[ -z "$ROOT" ] && ROOT="$OUTPUT/fs" && rm -rf "$ROOT"
-
-# ----- log build output
-
-# Install command line recording wrapper, logs all commands run from $PATH
-if [ -z "$NOLOGPATH" ]; then
- # Move cross compiler into $PATH so calls to it get logged
- [ -n "$CROSS_COMPILE" ] && PATH="${CROSS_COMPILE%/*}:$PATH" &&
- CROSS_COMPILE=${CROSS_COMPILE##*/}
- export WRAPDIR="$BUILD/record-commands" LOGPATH="$LOG/$CROSS-commands.txt"
- rm -rf "$WRAPDIR" "$LOGPATH" generated/obj &&
- WRAPDIR="$WRAPDIR" CROSS_COMPILE= NOSTRIP=1 source scripts/record-commands ||
- exit 1
-fi
-
-# Start logging stdout/stderr
-rm -f "$LOG/$CROSS".{n,y} || exit 1
-[ -z "$NOLOG" ] && exec > >(tee "$LOG/$CROSS.n") 2>&1
-echo "Building for $CROSS"
-
-# ---------------------- Part 2: Create root filesystem -----------------------
-
-# ----- Create new root filesystem's directory layout.
-
-# FHS wants boot media opt srv usr/{local,share}, stuff under /var...
-mkdir -p "$ROOT"/{dev,etc/rc,home,mnt,proc,root,sys,tmp/run,usr/{bin,sbin,lib},var} &&
-chmod a+rwxt "$ROOT"/tmp && ln -s usr/{bin,sbin,lib} tmp/run "$ROOT" || exit 1
-
-# Write init script. Runs as pid 1 from initramfs to set up and hand off system.
-cat > "$ROOT"/init << 'EOF' &&
-#!/bin/sh
-
-export HOME=/home PATH=/bin:/sbin
-
-if ! mountpoint -q dev; then
- mount -t devtmpfs dev dev
- [ $$ -eq 1 ] && exec 0<>/dev/console 1>&0 2>&1
- for i in ,fd /0,stdin /1,stdout /2,stderr
- do ln -sf /proc/self/fd${i/,*/} dev/${i/*,/}; done
- mkdir dev/shm
- chmod +t /dev/shm
-fi
-mountpoint -q dev/pts || { mkdir dev/pts && mount -t devpts dev/pts dev/pts; }
-mountpoint -q proc || mount -t proc proc proc
-mountpoint -q sys || mount -t sysfs sys sys
-echo 0 99999 > /proc/sys/net/ipv4/ping_group_range
-
-if [ $$ -eq 1 ]; then # Setup networking for QEMU (needs /proc)
- ifconfig lo 127.0.0.1
- ifconfig eth0 10.0.2.15
- route add default gw 10.0.2.2
- [ "$(date +%s)" -lt 1000 ] && timeout 2 sntp -sq 10.0.2.2 # Ask host
- [ "$(date +%s)" -lt 10000000 ] && sntp -sq time.google.com
-
- # Run package scripts (if any)
- for i in $(ls -1 /etc/rc 2>/dev/null | sort); do . /etc/rc/"$i"; done
-
- [ -z "$CONSOLE" ] && CONSOLE="$(</sys/class/tty/console/active)"
- [ -z "$HANDOFF" ] && HANDOFF=/bin/sh && echo -e '\e[?7hType exit when done.'
- echo 3 > /proc/sys/kernel/printk
- exec oneit -c /dev/"${CONSOLE:-console}" $HANDOFF
-else # for chroot
- /bin/sh
- umount /dev/pts /dev /sys /proc
-fi
-EOF
-chmod +x "$ROOT"/init &&
-
-# Google's nameserver, passwd+group with special (root/nobody) accounts + guest
-echo "nameserver 8.8.8.8" > "$ROOT"/etc/resolv.conf &&
-cat > "$ROOT"/etc/passwd << 'EOF' &&
-root:x:0:0:root:/root:/bin/sh
-guest:x:500:500:guest:/home/guest:/bin/sh
-nobody:x:65534:65534:nobody:/proc/self:/dev/null
-EOF
-echo -e 'root:x:0:\nguest:x:500:\nnobody:x:65534:' > "$ROOT"/etc/group || exit 1
-
-# Build static toybox with existing .config if there is one, else defconfig+sh
-announce toybox
-[ ! -z "$PENDING" ] && rm -f .config
-[ -e .config ] && CONF=silentoldconfig || unset CONF
-for i in $PENDING sh route wget; do XX="$XX"$'\n'CONFIG_${i^^?}=y; done
-LDFLAGS=--static PREFIX="$ROOT" make clean \
- ${CONF:-defconfig KCONFIG_ALLCONFIG=<(echo "$XX")} toybox install || exit 1
-
-# Build any packages listed on command line
-for i in ${PKG:+plumbing $PKG}; do
- announce "$i"; PATH="$PKGDIR:$PATH" source $i || die $i
-done
-
-# ------------------ Part 3: Build + package bootable system ------------------
-
-# ----- Build kernel for target
-
-if [ -z "$LINUX" ] || [ ! -d "$LINUX/kernel" ]; then
- echo 'No $LINUX directory, kernel build skipped.'
-else
- # Which architecture are we building a kernel for?
- LINUX="$(realpath "$LINUX")"
- [ -z "$TARGET" ] &&
- { [ "$CROSS" == host ] && TARGET="$(uname -m)" || TARGET="$CROSS"; }
-
- # Target-specific info in an (alphabetical order) if/else staircase
- # Each target needs board config, serial console, RTC, ethernet, block device.
-
- if [ "$TARGET" == armv5l ]; then
- # This could use the same VIRT board as armv7, but let's demonstrate a
- # different one requiring a separate device tree binary.
- QEMU="arm -M versatilepb -net nic,model=rtl8139 -net user"
- KARCH=arm KARGS=ttyAMA0 VMLINUX=arch/arm/boot/zImage
- KCONF=CPU_ARM926T,MMU,VFP,ARM_THUMB,AEABI,ARCH_VERSATILE,ATAGS,DEPRECATED_PARAM_STRUCT,ARM_ATAG_DTB_COMPAT,ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND,SERIAL_AMBA_PL011,SERIAL_AMBA_PL011_CONSOLE,RTC_CLASS,RTC_DRV_PL031,RTC_HCTOSYS,PCI,PCI_VERSATILE,BLK_DEV_SD,SCSI,SCSI_LOWLEVEL,SCSI_SYM53C8XX_2,SCSI_SYM53C8XX_MMIO,NET_VENDOR_REALTEK,8139CP
- KERNEL_CONFIG="CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0"
- DTB=arch/arm/boot/dts/versatile-pb.dtb
- elif [ "$TARGET" == armv7l ] || [ "$TARGET" == aarch64 ]; then
- if [ "$TARGET" == aarch64 ]; then
- QEMU="aarch64 -M virt -cpu cortex-a57"
- KARCH=arm64 VMLINUX=arch/arm64/boot/Image
- else
- QEMU="arm -M virt" KARCH=arm VMLINUX=arch/arm/boot/zImage
- fi
- KARGS=ttyAMA0
- KCONF=MMU,ARCH_MULTI_V7,ARCH_VIRT,SOC_DRA7XX,ARCH_OMAP2PLUS_TYPICAL,ARCH_ALPINE,ARM_THUMB,VDSO,CPU_IDLE,ARM_CPUIDLE,KERNEL_MODE_NEON,SERIAL_AMBA_PL011,SERIAL_AMBA_PL011_CONSOLE,RTC_CLASS,RTC_HCTOSYS,RTC_DRV_PL031,NET_CORE,VIRTIO_MENU,VIRTIO_NET,PCI,PCI_HOST_GENERIC,VIRTIO_BLK,VIRTIO_PCI,VIRTIO_MMIO,ATA,ATA_SFF,ATA_BMDMA,ATA_PIIX,PATA_PLATFORM,PATA_OF_PLATFORM,ATA_GENERIC,CONFIG_ARM_LPAE
- elif [ "$TARGET" == hexagon ]; then
- QEMU="hexagon -M comet" KARGS=ttyS0 VMLINUX=vmlinux
- KARCH="hexagon LLVM_IAS=1" KCONF=SPI,SPI_BITBANG,IOMMU_SUPPORT
- elif [ "$TARGET" == i486 ] || [ "$TARGET" == i686 ] ||
- [ "$TARGET" == x86_64 ] || [ "$TARGET" == x32 ]; then
- if [ "$TARGET" == i486 ]; then
- QEMU="i386 -cpu 486 -global fw_cfg.dma_enabled=false" KCONF=M486
- elif [ "$TARGET" == i686 ]; then
- QEMU="i386 -cpu pentium3" KCONF=MPENTIUMII
- else
- QEMU=x86_64 KCONF=64BIT
- [ "$TARGET" == x32 ] && KCONF=X86_X32
- fi
- KARCH=x86 KARGS=ttyS0 VMLINUX=arch/x86/boot/bzImage
- KCONF=$KCONF,UNWINDER_FRAME_POINTER,PCI,BLK_DEV_SD,ATA,ATA_SFF,ATA_BMDMA,ATA_PIIX,NET_VENDOR_INTEL,E1000,SERIAL_8250,SERIAL_8250_CONSOLE,RTC_CLASS
- elif [ "$TARGET" == m68k ]; then
- QEMU="m68k -M q800" KARCH=m68k KARGS=ttyS0 VMLINUX=vmlinux
- KCONF=MMU,M68040,M68KFPU_EMU,MAC,SCSI_MAC_ESP,MACINTOSH_DRIVERS,ADB,ADB_MACII,NET_CORE,NET_VENDOR_NATSEMI,MACSONIC,SERIAL_PMACZILOG,SERIAL_PMACZILOG_TTYS,SERIAL_PMACZILOG_CONSOLE
- elif [ "$TARGET" == mips ] || [ "$TARGET" == mipsel ]; then
- QEMU="mips -M malta" KARCH=mips KARGS=ttyS0 VMLINUX=vmlinux
- KCONF=MIPS_MALTA,CPU_MIPS32_R2,SERIAL_8250,SERIAL_8250_CONSOLE,PCI,BLK_DEV_SD,ATA,ATA_SFF,ATA_BMDMA,ATA_PIIX,NET_VENDOR_AMD,PCNET32,POWER_RESET,POWER_RESET_SYSCON
- [ "$TARGET" == mipsel ] && KCONF=$KCONF,CPU_LITTLE_ENDIAN &&
- QEMU="mipsel -M malta"
- elif [ "$TARGET" == powerpc ]; then
- KARCH=powerpc QEMU="ppc -M g3beige" KARGS=ttyS0 VMLINUX=vmlinux
- KCONF=ALTIVEC,PPC_PMAC,PPC_OF_BOOT_TRAMPOLINE,IDE,IDE_GD,IDE_GD_ATA,BLK_DEV_IDE_PMAC,BLK_DEV_IDE_PMAC_ATA100FIRST,MACINTOSH_DRIVERS,ADB,ADB_CUDA,NET_VENDOR_NATSEMI,NET_VENDOR_8390,NE2K_PCI,SERIO,SERIAL_PMACZILOG,SERIAL_PMACZILOG_TTYS,SERIAL_PMACZILOG_CONSOLE,BOOTX_TEXT
- elif [ "$TARGET" == powerpc64le ]; then
- KARCH=powerpc QEMU="ppc64 -M pseries -vga none" KARGS=hvc0
- VMLINUX=vmlinux
- KCONF=PPC64,PPC_PSERIES,CPU_LITTLE_ENDIAN,PPC_OF_BOOT_TRAMPOLINE,BLK_DEV_SD,SCSI_LOWLEVEL,SCSI_IBMVSCSI,ATA,NET_VENDOR_IBM,IBMVETH,HVC_CONSOLE,PPC_TRANSACTIONAL_MEM,PPC_DISABLE_WERROR,SECTION_MISMATCH_WARN_ONLY
- elif [ "$TARGET" = s390x ]; then
- QEMU="s390x" KARCH=s390 VMLINUX=arch/s390/boot/bzImage
- KCONF=MARCH_Z900,PACK_STACK,NET_CORE,VIRTIO_NET,VIRTIO_BLK,SCLP_TTY,SCLP_CONSOLE,SCLP_VT220_TTY,SCLP_VT220_CONSOLE,S390_GUEST
- elif [ "$TARGET" == sh2eb ]; then
- BUILTIN=1 KARCH=sh VMLINUX=vmlinux
- KERNEL_CONFIG=$'CONFIG_MEMORY_START=0x10000000\nCONFIG_CMDLINE="console=ttyUL0 earlycon"'
- KCONF=CPU_SUBTYPE_J2,CPU_BIG_ENDIAN,SH_JCORE_SOC,SMP,BINFMT_ELF_FDPIC,JCORE_EMAC,SERIAL_UARTLITE,SERIAL_UARTLITE_CONSOLE,HZ_100,CMDLINE_OVERWRITE,SPI,SPI_JCORE,MMC,PWRSEQ_SIMPLE,MMC_BLOCK,MMC_SPI
- elif [ "$TARGET" == sh4 ]; then
- QEMU="sh4 -M r2d -serial null -serial mon:stdio" KARCH=sh
- KARGS="ttySC1 noiotrap" VMLINUX=arch/sh/boot/zImage
- KERNEL_CONFIG="CONFIG_MEMORY_START=0x0c000000"
- KCONF=CPU_SUBTYPE_SH7751R,MMU,VSYSCALL,SH_FPU,SH_RTS7751R2D,RTS7751R2D_PLUS,SERIAL_SH_SCI,SERIAL_SH_SCI_CONSOLE,PCI,NET_VENDOR_REALTEK,8139CP,PCI,BLK_DEV_SD,ATA,ATA_SFF,ATA_BMDMA,PATA_PLATFORM,BINFMT_ELF_FDPIC,BINFMT_FLAT
-#see also SPI SPI_SH_SCI MFD_SM501 RTC_CLASS RTC_DRV_R9701 RTC_DRV_SH RTC_HCTOSYS
- else die "Unknown \$TARGET $TARGET"
- fi
-
- # Write the qemu launch script
- if [ -n "$QEMU" ]; then
- [ -z "$BUILTIN" ] && INITRD="-initrd ${CROSS}root.cpio.gz"
- { echo qemu-system-"$QEMU" '"$@"' $QEMU_MORE -nographic -no-reboot -m 256 \
- -kernel $(basename $VMLINUX) $INITRD ${DTB:+-dtb "$(basename "$DTB")"} \
- "-append \"panic=1 HOST=$TARGET console=$KARGS \$KARGS\"" &&
- echo "echo -e '\\e[?7h'"
- } > "$OUTPUT/qemu-$TARGET.sh" &&
- chmod +x "$OUTPUT/qemu-$TARGET.sh" || exit 1
- fi
-
- announce "linux-$KARCH"
- pushd "$LINUX" && make distclean && popd &&
- cp -sfR "$LINUX" "$MYBUILD/linux" && pushd "$MYBUILD/linux" &&
- sed -is '/select HAVE_STACK_VALIDATION/d' arch/x86/Kconfig && # Fix x86-64
- sed -is 's/depends on !SMP/& || !MMU/' mm/Kconfig && # Fix sh2eb
-
- # Write miniconfig
- { echo "# make ARCH=$KARCH allnoconfig KCONFIG_ALLCONFIG=$TARGET.miniconf"
- echo -e "# make ARCH=$KARCH -j \$(nproc)\n# boot $VMLINUX\n\n"
- echo "# CONFIG_EMBEDDED is not set"
-
- # Expand list of =y symbols, first generic then architecture-specific
- for i in BINFMT_ELF,BINFMT_SCRIPT,NO_HZ,HIGH_RES_TIMERS,BLK_DEV,BLK_DEV_INITRD,RD_GZIP,BLK_DEV_LOOP,EXT4_FS,EXT4_USE_FOR_EXT2,VFAT_FS,FAT_DEFAULT_UTF8,MISC_FILESYSTEMS,SQUASHFS,SQUASHFS_XATTR,SQUASHFS_ZLIB,DEVTMPFS,DEVTMPFS_MOUNT,TMPFS,TMPFS_POSIX_ACL,NET,PACKET,UNIX,INET,IPV6,NETDEVICES,NET_CORE,NETCONSOLE,ETHERNET,COMPAT_32BIT_TIME,EARLY_PRINTK,IKCONFIG,IKCONFIG_PROC $KCONF $KEXTRA ; do
- echo "# architecture ${X:-independent}"
- sed -E '/^$/d;s/([^,]*)($|,)/CONFIG_\1=y\n/g' <<< "$i"
- X=specific
- done
- [ -n "$BUILTIN" ] && echo -e CONFIG_INITRAMFS_SOURCE="\"$OUTPUT/fs\""
- echo "$KERNEL_CONFIG"
- } > "$OUTPUT/miniconfig-$TARGET" &&
- make ARCH=$KARCH allnoconfig KCONFIG_ALLCONFIG="$OUTPUT/miniconfig-$TARGET" &&
-
- # Second config pass to remove stupid kernel defaults
- # See http://lkml.iu.edu/hypermail/linux/kernel/1912.3/03493.html
- sed -e 's/# CONFIG_EXPERT .*/CONFIG_EXPERT=y/' -e "$(sed -E -e '/^$/d' \
- -e 's@([^,]*)($|,)@/^CONFIG_\1=y/d;$a# CONFIG_\1 is not set/\n@g' \
- <<< VT,SCHED_DEBUG,DEBUG_MISC,X86_DEBUG_FPU)" -i .config &&
- yes "" | make ARCH=$KARCH oldconfig > /dev/null &&
-
- # Build kernel. Copy config, device tree binary, and kernel binary to output
- make ARCH=$KARCH CROSS_COMPILE="$CROSS_COMPILE" -j $(nproc) &&
- cp .config "$OUTPUT/linux-fullconfig" || exit 1
- [ -n "$DTB" ] && { cp "$DTB" "$OUTPUT" || exit 1 ;}
- cp "$VMLINUX" "$OUTPUT" && cd .. && rm -rf linux && popd || exit 1
-fi
-
-# clean up and package root filesystem for initramfs.
-if [ -z "$BUILTIN" ]; then
- announce "${CROSS}root.cpio.gz"
- (cd "$ROOT" && find . | cpio -o -H newc ${CROSS_COMPILE:+--no-preserve-owner}\
- | gzip) > "$OUTPUT/$CROSS"root.cpio.gz || exit 1
-fi
-
-mv "$LOG/$CROSS".{n,y}
-rmdir "$MYBUILD" "$BUILD" 2>/dev/null || exit 0 # remove if empty, not an error
+#!/usr/bin/printf Moved to mkroot/mkroot.sh\n\c%s
diff --git a/scripts/mkstatus.py b/scripts/mkstatus.py
index ed6dd544..41a1bed2 100755
--- a/scripts/mkstatus.py
+++ b/scripts/mkstatus.py
@@ -40,7 +40,7 @@ print "all commands=%s" % len(reverse)
# Run a couple sanity checks on input
for i in toystuff:
- if (i in pending): print "barf %s" % i
+ if (i in pending): print "Pending command not roadmap: %s" % i
unknowns=[]
for i in toystuff + pending:
diff --git a/scripts/portability.sh b/scripts/portability.sh
index 3af2be5f..4241916a 100644
--- a/scripts/portability.sh
+++ b/scripts/portability.sh
@@ -2,9 +2,9 @@
source ./configure
-if [ -z "$(command -v "${CROSS_COMPILE}${CC}")" ]
+if [ -z "$(command -v "$CROSS_COMPILE$CC")" ]
then
- echo "No ${CROSS_COMPILE}${CC} found" >&2
+ echo "No $CROSS_COMPILE$CC found" >&2
exit 1
fi
@@ -16,26 +16,30 @@ fi
# Tell linker to do dead code elimination at function level
if [ "$(uname)" == "Darwin" ]
then
+ CFLAGS+=" -Wno-deprecated-declarations"
: ${LDOPTIMIZE:=-Wl,-dead_strip} ${STRIP:=strip}
else
: ${LDOPTIMIZE:=-Wl,--gc-sections -Wl,--as-needed} ${STRIP:=strip -s -R .note* -R .comment}
fi
+# Disable a pointless warning only clang produces
+[ -n "$("$CROSS_COMPILE$CC" --version | grep -w clang)" ] &&
+ CFLAGS+=" -Wno-string-plus-int -Wno-invalid-source-encoding"
+
# Address Sanitizer
-if [ ! -z "$ASAN" ]; then
+if [ -n "$ASAN" ]; then
# Turn ASan on and disable most optimization to get more readable backtraces.
# (Technically ASAN is just "-fsanitize=address" and the rest is optional.)
- ASAN_FLAGS="-fsanitize=address -O1 -g -fno-omit-frame-pointer -fno-optimize-sibling-calls"
- CFLAGS="$CFLAGS $ASAN_FLAGS"
- HOSTCC="$HOSTCC $ASAN_FLAGS"
- NOSTRIP=1
+ export CFLAGS="$CFLAGS -fsanitize=address -O1 -g -fno-omit-frame-pointer -fno-optimize-sibling-calls"
+ export NOSTRIP=1
# Ignore leaks on exit. TODO
export ASAN_OPTIONS="detect_leaks=0"
+ # only do this once
unset ASAN
fi
-# Centos 7 bug workaround, EOL June 30 2024. TODO
-DASHN=-n; wait -n 2>/dev/null; [ $? -eq 2 ] && unset DASHN
+# Probe number of available processors, and add one.
+: ${CPUS:=$(($(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null)+1))}
# If the build is using gnu tools, make them behave less randomly.
export LANG=c
diff --git a/scripts/record-commands b/scripts/record-commands
deleted file mode 100755
index d2b779fa..00000000
--- a/scripts/record-commands
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-
-# Set up command recording wrapper
-
-[ -z "$WRAPDIR" ] && WRAPDIR="$PWD"/record-commands && RM=$(which rm)
-[ -z "$LOGPATH" ] && export LOGPATH="$PWD"/log.txt
-
-if [ ${#BASH_SOURCE[@]} -lt 2 ] && [ $# -eq 0 ]
-then
- echo "usage: WRAPDIR=dir LOGPATH=log.txt record-commands COMMAND..."
- echo 'Then examine log.txt. "record-commands echo" to just setup $WRAPDIR'
- exit 1
-fi
-
-if [ ! -x "$WRAPDIR/logpath" ]
-then
- mkdir -p "$WRAPDIR" && PREFIX="$WRAPDIR/" scripts/single.sh logpath || exit 1
- echo "$PATH" | tr : '\n' | while read DIR
- do
- find "$DIR/" -type f,l -maxdepth 1 -executable -exec basename {} \; | \
- while read FILE
- do
- ln -s logpath "$WRAPDIR/$FILE" 2>/dev/null
- done
- done
-fi
-
-# Delete old log (if any)
-rm -f "$LOGPATH"
-
-# When sourced, set up wrapper for current context.
-export PATH="$WRAPDIR:$PATH"
-if [ ${#BASH_SOURCE[@]} -lt 2 ]
-then
- "$@"
- X=$?
-
- [ ! -z "$RM" ] && "$RM" -rf "$WRAPDIR"
-
- exit $X
-fi
-
diff --git a/scripts/root/dropbear b/scripts/root/dropbear
deleted file mode 100755
index 75839c34..00000000
--- a/scripts/root/dropbear
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/echo Try "scripts/mkroot.sh dropbear"
-
-# Example overlay file, adding dropbear (which requires zlib)
-
-echo === download source
-
-download e6d119755acdf9104d7ba236b1242696940ed6dd \
- http://downloads.sf.net/libpng/zlib-1.2.11.tar.gz
-
-download c3d4fe27fa17ec8217dbedbd33dd73a1ca6cda2c \
- https://matt.ucc.asn.au/dropbear/releases/dropbear-2020.81.tar.bz2
-
-echo === Native build static zlib
-
-setupfor zlib
-# They keep checking in broken generated files.
-rm -f Makefile zconf.h &&
-CC=${CROSS_COMPILE}cc LD=${CROSS_COMPILE}ld AS=${CROSS_COMPILE}as ./configure &&
-make -j $(nproc) || exit 1
-
-# do _not_ cleanup zlib, we need the files we just built for dropbear
-cd ..
-
-echo === $HOST Native build static dropbear
-
-setupfor dropbear
-# Repeat after me: "autoconf is useless"
-echo 'echo "$@"' > config.sub &&
-ZLIB="$(echo ../zlib*)" &&
-CFLAGS="-I $ZLIB -O2" LDFLAGS="-L $ZLIB" ./configure --enable-static \
- --disable-wtmp --host="$(basename "$CROSS_COMPILE" | sed 's/-$//')" &&
-sed -i 's@/usr/bin/dbclient@ssh@' options.h &&
-sed -i 's@\(#define NON_INETD_MODE\) 1@\1 0@' default_options.h &&
-make -j $(nproc) PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" MULTI=1 SCPPROGRESS=1 &&
-${CROSS_COMPILE}strip dropbearmulti &&
-mkdir -p "$ROOT"/{bin,etc/{rc,dropbear},var/log} &&
-touch "$ROOT"/var/log/lastlog &&
-cp dropbearmulti "$ROOT"/bin || exit 1
-for i in "$ROOT"/bin/{ssh,dropbear,scp,dropbearkey}
-do
- ln -s dropbearmulti $i || exit 1
-done
-cleanup
-
-rm -rf zlib-*
-
-# user root password root, user guest no password
-echo -e 'root:$1$939UTPzb$/PfVYAsF2Hqi/AQ3UBjbK/:::::::\nguest::::::::' > "$ROOT"/etc/shadow &&
-chmod 600 "$ROOT"/etc/shadow &&
-
-echo 'netcat -p 22 -L dropbear -iRB &' > "$ROOT"/etc/rc/dropbear &&
-
-# file to run on host to ssh into guest
-echo 'ssh -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" ${1:+$1@}127.0.0.1 -p 2222' > "$OUTPUT"/ssh2dropbear.sh &&
-chmod +x "$OUTPUT"/ssh2dropbear.sh
-
-# Forward 127.0.0.1:2222 into qemu instance
-QEMU_MORE="-nic user,hostfwd=tcp:127.0.0.1:2222-:22"
diff --git a/scripts/root/plumbing b/scripts/root/plumbing
deleted file mode 100755
index ff302803..00000000
--- a/scripts/root/plumbing
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/echo run this from "make root"
-
-# Plumbing to download files
-
-[ -z "$ROOT" ] && echo "no" && exit 1
-mkdir -p "${DOWNLOAD:=$PWD/root_download}" || exit 1
-
-### Functions to download, extract, and clean up after source packages.
-
-# Usage: download HASH URL
-# Grabs source from URL confirming SHA1 hash (Basically "wget $2")
-# If extracted source is in $DOWNLOAD (no version) build will use that instead
-download() {
- FILE="$(basename "$2")"
- [ -d "$DOWNLOAD/${FILE/-*/}" ] && echo "$FILE" local && return 0
- X=0; while true; do
- [ "$(sha1sum < "$DOWNLOAD/$FILE" 2>/dev/null)" == "$1 -" ] &&
- echo "$FILE" confirmed && break
- rm -f $DOWNLOAD/${FILE/-[0-9]*/}-[0-9]* || exit 1
- [ $X -eq 0 ] && X=1 || exit 1
- wget "$2" -O "$DOWNLOAD/$FILE"
- done
-}
-
-# Usage: setupfor PACKAGE
-# Extracts source tarball (or snapshot a repo) to create disposable build dir.
-# Basically "tar xvzCf $MYBUILD $DOWNLOAD/$1.tar.gz && cd $NEWDIR"
-setupfor() {
- PACKAGE="$(basename "$1")"
- announce "$PACKAGE" && cd "$MYBUILD" && rm -rf "$PACKAGE" || exit 1
- if [ -d "$DOWNLOAD/$PACKAGE" ]; then
- cp -la "$DOWNLOAD/$PACKAGE/." "$PACKAGE" && cd "$PACKAGE" || exit 1
- else
- tar xvaf "$DOWNLOAD/$PACKAGE"-*.t* && cd "$PACKAGE"-* || exit 1
- fi
-}
-
-# Usage: cleanup
-# Delete setupfor's dir, exiting if build failed (basically "rm -rf $PACKAGE")
-cleanup() {
- [ $? -ne 0 ] && exit 1
- [ -z "$PACKAGE" ] && exit 1
- [ ! -z "$NO_CLEANUP" ] && return
- cd .. && rm -rf "$PACKAGE"* || exit 1
-}
diff --git a/scripts/runtest.sh b/scripts/runtest.sh
index 5a647677..ce6e0fd0 100644
--- a/scripts/runtest.sh
+++ b/scripts/runtest.sh
@@ -2,9 +2,7 @@
#
# Copyright 2005 by Rob Landley
-# This file defines two main functions, "testcmd" and "optional". The
-# first performs a test, the second enables/disables tests based on
-# configuration options.
+# This file defines three main functions: "testing", "testcmd", and "txpect".
# The following environment variables enable optional behavior in "testing":
# DEBUG - Show every command run by test script.
@@ -30,26 +28,13 @@
# The environment variable "FAILCOUNT" contains a cumulative total of the
# number of failed tests.
#
-# The "optional" function is used to skip certain tests (by setting the
-# environment variable SKIP), ala:
-# optional CFG_THINGY
+# The environment variable "SKIP" says how many upcoming tests to skip,
+# defaulting to 0 and counting down when set to a higher number.
#
-# The "optional" function checks the environment variable "OPTIONFLAGS",
-# which is either empty (in which case it always clears SKIP) or
-# else contains a colon-separated list of features (in which case the function
-# clears SKIP if the flag was found, or sets it to 1 if the flag was not found).
-
-export FAILCOUNT=0
-export SKIP=
-
-# Helper functions
-
-# Check config to see if option is enabled, set SKIP if not.
-
-SHOWPASS=PASS
-SHOWFAIL=FAIL
-SHOWSKIP=SKIP
+# Function "optional" enables/disables tests based on configuration options.
+export FAILCOUNT=0 SKIP=0
+: ${SHOWPASS:=PASS} ${SHOWFAIL:=FAIL} ${SHOWSKIP:=SKIP}
if tty -s <&1
then
SHOWPASS="$(echo -e "\033[1;32m${SHOWPASS}\033[0m")"
@@ -57,34 +42,64 @@ then
SHOWSKIP="$(echo -e "\033[1;33m${SHOWSKIP}\033[0m")"
fi
-optional()
+# Helper functions
+
+# Check if VERBOSE= contains a given string. (This allows combining.)
+verbose_has()
{
- option=`printf %s "$OPTIONFLAGS" | egrep "(^|:)$1(:|\$)"`
- # Not set?
- if [ -z "$1" ] || [ -z "$OPTIONFLAGS" ] || [ ${#option} -ne 0 ]
+ [ "${VERBOSE/$1/}" != "$VERBOSE" ]
+}
+
+wrong_args()
+{
+ if [ $# -ne 5 ]
then
- unset SKIP
- return
+ printf "%s\n" "Test $NAME has the wrong number of arguments ($# $*)" >&2
+ exit
fi
- SKIP=1
}
-verbose_has()
+# Announce success
+do_pass()
{
- [ "${VERBOSE/$1/}" != "$VERBOSE" ]
+ verbose_has nopass || printf "%s\n" "$SHOWPASS: $NAME"
}
+# Announce failure and handle fallout for txpect
+do_fail()
+{
+ FAILCOUNT=$(($FAILCOUNT+1))
+ printf "%s\n" "$SHOWFAIL: $NAME"
+ if [ ! -z "$CASE" ]
+ then
+ echo "Expected '$CASE'"
+ echo "Got '$A'"
+ fi
+ ! verbose_has all && exit 1
+}
+
+# Functions test files call directly
+
+# Set SKIP high if option not enabled in $OPTIONFLAGS (unless OPTIONFLAGS blank)
+optional()
+{
+ [ -n "$OPTIONFLAGS" ] && [ "$OPTIONFLAGS" == "${OPTIONFLAGS/:$1:/}" ] &&
+ SKIP=99999 || SKIP=0
+}
+
+# Evalute command line and skip next test when false
skipnot()
{
if verbose_has quiet
then
- eval "$@" 2>/dev/null
+ eval "$@" >/dev/null 2>&1
else
eval "$@"
fi
- [ $? -eq 0 ] || SKIPNEXT=1
+ [ $? -eq 0 ] || { ((++SKIP)); return 1; }
}
+# Skip this test (rest of command line) when not running toybox.
toyonly()
{
IS_TOYBOX="$("$C" --version 2>/dev/null)"
@@ -93,61 +108,40 @@ toyonly()
case "$IS_TOYBOX" in
toybox*) ;;
This\ is\ not\ GNU*) ;;
- *) SKIPNEXT=1 ;;
+ *) [ $SKIP -eq 0 ] && ((++SKIP)) ;;
esac
"$@"
}
-wrong_args()
-{
- if [ $# -ne 5 ]
- then
- printf "%s\n" "Test $NAME has the wrong number of arguments ($# $*)" >&2
- exit
- fi
-}
-
-# Announce success
-do_pass()
-{
- ! verbose_has nopass && printf "%s\n" "$SHOWPASS: $NAME"
-}
-
-# The testing function
-
+# Takes five arguments: "name" "command" "result" "infile" "stdin"
testing()
{
- NAME="$CMDNAME $1"
wrong_args "$@"
- [ -z "$1" ] && NAME=$2
+ [ -z "$1" ] && NAME="$2" || NAME="$1"
+ [ "${NAME#$CMDNAME }" == "$NAME" ] && NAME="$CMDNAME $1"
[ -n "$DEBUG" ] && set -x
- if [ -n "$SKIP" -o -n "$SKIP_HOST" -a -n "$TEST_HOST" -o -n "$SKIPNEXT" ]
+ if [ "$SKIP" -gt 0 ]
then
- verbose_has quiet && printf "%s\n" "$SHOWSKIP: $NAME"
- unset SKIPNEXT
+ verbose_has quiet || printf "%s\n" "$SHOWSKIP: $NAME"
+ ((--SKIP))
+
return 0
fi
- echo -ne "$3" > expected
+ echo -ne "$3" > ../expected
[ ! -z "$4" ] && echo -ne "$4" > input || rm -f input
- echo -ne "$5" | ${EVAL:-eval --} "$2" > actual
+ echo -ne "$5" | ${EVAL:-eval --} "$2" > ../actual
RETVAL=$?
# Catch segfaults
- [ $RETVAL -gt 128 ] && [ $RETVAL -lt 255 ] &&
+ [ $RETVAL -gt 128 ] &&
echo "exited with signal (or returned $RETVAL)" >> actual
- DIFF="$(diff -au${NOSPACE:+w} expected actual)"
- if [ -n "$DIFF" ]
- then
- FAILCOUNT=$(($FAILCOUNT+1))
- printf "%s\n" "$SHOWFAIL: $NAME"
- else
- ! verbose_has nopass && printf "%s\n" "$SHOWPASS: $NAME"
- fi
+ DIFF="$(cd ..; diff -au${NOSPACE:+w} expected actual)"
+ [ -z "$DIFF" ] && do_pass || VERBOSE=all do_fail
if ! verbose_has quiet && { [ -n "$DIFF" ] || verbose_has spam; }
then
[ ! -z "$4" ] && printf "%s\n" "echo -ne \"$4\" > input"
@@ -156,34 +150,22 @@ testing()
fi
[ -n "$DIFF" ] && ! verbose_has all && exit 1
- rm -f input expected actual
+ rm -f input ../expected ../actual
[ -n "$DEBUG" ] && set +x
return 0
}
+# Wrapper for "testing", adds command name being tested to start of command line
testcmd()
{
wrong_args "$@"
- X="$1"
- [ -z "$X" ] && X="$CMDNAME $2"
- testing "$X" "\"$C\" $2" "$3" "$4" "$5"
+ testing "${1:-$CMDNAME $2}" "\"$C\" $2" "$3" "$4" "$5"
}
-# Announce failure and handle fallout for txpect
-do_fail()
-{
- FAILCOUNT=$(($FAILCOUNT+1))
- printf "%s\n" "$SHOWFAIL: $NAME"
- if [ ! -z "$CASE" ]
- then
- echo "Expected '$CASE'"
- echo "Got '$A'"
- fi
- ! verbose_has all && exit 1
-}
+# Simple implementation of "expect" written in shell.
# txpect NAME COMMAND [I/O/E/Xstring]...
# Run COMMAND and interact with it: send I strings to input, read O or E
@@ -191,7 +173,7 @@ do_fail()
# X means close stdin/stdout/stderr and match return code (blank means nonzero)
txpect()
{
- local NAME CASE VERBOSITY LEN A B X O
+ local NAME CASE VERBOSITY LEN PID A B X O
# Run command with redirection through fifos
NAME="$CMDNAME $1"
@@ -204,13 +186,14 @@ txpect()
return
fi
eval "$2" <in-$$ >out-$$ 2>err-$$ &
+ PID=$!
shift 2
: {IN}>in-$$ {OUT}<out-$$ {ERR}<err-$$ && rm in-$$ out-$$ err-$$
[ $? -ne 0 ] && { do_fail;return;}
# Loop through challenge/response pairs, with 2 second timeout
- while [ $# -gt 0 ]
+ while [ $# -gt 0 -a -n "$PID" ]
do
VERBOSITY="$VERBOSITY"$'\n'"$1" LEN=$((${#1}-1)) CASE="$1" A= B=
@@ -234,29 +217,33 @@ txpect()
then
[ -z "$A" -o "$X" -ne 0 ] && { do_fail;break;}
else
- if [ ${1::1} == 'R' ] && [[ "$A" =~ "${1:2}" ]]; then true
+ if [ ${1::1} == 'R' ] && grep -q "${1:2}" <<< "$A"; then true
elif [ ${1::1} != 'R' ] && [ "$A" == "${1:1}" ]; then true
else
# Append the rest of the output if there is any.
read -t.1 B <&$O
A="$A$B"
read -t.1 -rN 9999 B<&$ERR
- do_fail;break;
+ do_fail
+ break
fi
fi
;;
# close I/O and wait for exit
X)
- exec {IN}<&- {OUT}<&- {ERR}<&-
- wait
+ exec {IN}<&-
+ wait $PID
A=$?
+ exec {OUT}<&- {ERR}<&-
if [ -z "$LEN" ]
then
[ $A -eq 0 ] && { do_fail;break;} # any error
else
[ $A != "${1:1}" ] && { do_fail;break;} # specific value
fi
+ do_pass
+ return
;;
*) do_fail; break ;;
esac
@@ -270,65 +257,6 @@ txpect()
do_pass
else
! verbose_has quiet && echo "$VERBOSITY" >&2
+ do_fail
fi
}
-
-# Recursively grab an executable and all the libraries needed to run it.
-# Source paths beginning with / will be copied into destpath, otherwise
-# the file is assumed to already be there and only its library dependencies
-# are copied.
-
-mkchroot()
-{
- [ $# -lt 2 ] && return
-
- echo -n .
-
- dest=$1
- shift
- for i in "$@"
- do
- [ "${i:0:1}" == "/" ] || i=$(which $i)
- [ -f "$dest/$i" ] && continue
- if [ -e "$i" ]
- then
- d=`echo "$i" | grep -o '.*/'` &&
- mkdir -p "$dest/$d" &&
- cat "$i" > "$dest/$i" &&
- chmod +x "$dest/$i"
- else
- echo "Not found: $i"
- fi
- mkchroot "$dest" $(ldd "$i" | egrep -o '/.* ')
- done
-}
-
-# Set up a chroot environment and run commands within it.
-# Needed commands listed on command line
-# Script fed to stdin.
-
-dochroot()
-{
- mkdir tmpdir4chroot
- mount -t ramfs tmpdir4chroot tmpdir4chroot
- mkdir -p tmpdir4chroot/{etc,sys,proc,tmp,dev}
- cp -L testing.sh tmpdir4chroot
-
- # Copy utilities from command line arguments
-
- echo -n "Setup chroot"
- mkchroot tmpdir4chroot $*
- echo
-
- mknod tmpdir4chroot/dev/tty c 5 0
- mknod tmpdir4chroot/dev/null c 1 3
- mknod tmpdir4chroot/dev/zero c 1 5
-
- # Copy script from stdin
-
- cat > tmpdir4chroot/test.sh
- chmod +x tmpdir4chroot/test.sh
- chroot tmpdir4chroot /test.sh
- umount -l tmpdir4chroot
- rmdir tmpdir4chroot
-}
diff --git a/scripts/single.sh b/scripts/single.sh
index 023ccea6..f4f28be9 100755
--- a/scripts/single.sh
+++ b/scripts/single.sh
@@ -4,6 +4,8 @@
[ -z "$1" ] && { echo "usage: single.sh command..." >&2; exit 1; }
+source scripts/portability.sh
+
# Add trailing / to PREFIX when it's set but hasn't got one
[ "$PREFIX" == "${PREFIX%/}" ] && PREFIX="${PREFIX:+$PREFIX/}"
@@ -17,7 +19,7 @@ else
# Force dependencies to rebuild headers if we build multiplexer after this.
touch "$KCONFIG_CONFIG"
fi
-GLOBDEP="$(sed -n 's/CONFIG_\(TOYBOX_[^=]*\)=y/\1/p' "$KCONFIG_CONFIG")"
+GLOBDEP="$($SED -n 's/CONFIG_\(TOYBOX_[^=]*\)=y/\1/p' "$KCONFIG_CONFIG")"
KCONFIG_CONFIG=.singleconfig
for i in "$@"
@@ -36,15 +38,15 @@ do
unset DEPENDS MPDEL
if [ "$i" == sh ]
then
- DEPENDS="$(sed -n 's/USE_\([^(]*\)(NEWTOY([^,]*,.*TOYFLAG_MAYFORK.*/\1/p' toys/*/*.c)"
+ DEPENDS="$($SED -n 's/USE_\([^(]*\)(NEWTOY([^,]*,.*TOYFLAG_MAYFORK.*/\1/p' toys/*/*.c)"
else
MPDEL='s/CONFIG_TOYBOX=y/# CONFIG_TOYBOX is not set/;t'
fi
# Enable stuff this command depends on
- DEPENDS="$({ echo $DEPENDS $GLOBDEP; sed -n "/^config *$i"'$/,/^$/{s/^[ \t]*depends on //;T;s/[!][A-Z0-9_]*//g;s/ *&& */|/g;p}' $TOYFILE;}| xargs | tr ' ' '|')"
+ DEPENDS="$({ echo $DEPENDS $GLOBDEP; $SED -n "/^config *$i"'$/,/^$/{s/^[ \t]*depends on //;T;s/[!][A-Z0-9_]*//g;s/ *&& */|/g;p}' $TOYFILE;}| xargs | tr ' ' '|')"
NAME=$(echo $i | tr a-z- A-Z_)
- sed -ri -e "$MPDEL" \
+ $SED -ri -e "$MPDEL" \
-e "s/# (CONFIG_($NAME|${NAME}_.*${DEPENDS:+|$DEPENDS})) is not set/\1=y/" \
"$KCONFIG_CONFIG" || exit 1
diff --git a/scripts/test.sh b/scripts/test.sh
index da22f661..c29a9aa9 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -8,26 +8,28 @@ export FILES="$PWD"/tests/files
trap 'kill $(jobs -p) 2>/dev/null; exit 1' INT
-rm -rf generated/testdir
-mkdir -p generated/testdir/testdir
+export PREFIX=generated/testdir
+rm -rf "$PREFIX"
+mkdir -p "$PREFIX"/testdir
if [ -z "$TEST_HOST" ]
then
if [ $# -ne 0 ]
then
- PREFIX=generated/testdir/ scripts/single.sh "$@" || exit 1
+ scripts/single.sh "$@" || exit 1
else
- make install_flat PREFIX=generated/testdir || exit 1
+ scripts/install.sh --symlink --force || exit 1
fi
fi
-cd generated/testdir
+export -n PREFIX
+cd "$PREFIX"
PATH="$PWD:$PATH"
TESTDIR="$PWD"
export LC_COLLATE=C
[ -f "$TOPDIR/generated/config.h" ] &&
- export OPTIONFLAGS=:$(echo $($SED -nr 's/^#define CFG_(.*) 1/\1/p' "$TOPDIR/generated/config.h") | $SED 's/ /:/g')
+ export OPTIONFLAGS=:$($SED -nr 's/^#define CFG_(.*) 1$/\1/p' "$TOPDIR/generated/config.h" | tr '\n' :)
do_test()
{
@@ -38,16 +40,16 @@ do_test()
if [ -z "$TEST_HOST" ]
then
C="$TESTDIR/$CMDNAME"
- [ ! -e "$C" ] && echo "$CMDNAME disabled" && return
+ [ ! -e "$C" ] && echo "$SHOWSKIP: $CMDNAME disabled" && return
C="$(dirname $(realpath "$C"))/$CMDNAME"
else
C="$(which $CMDNAME 2>/dev/null)"
[ -z "$C" ] && printf '%s\n' "$SHOWSKIP: no $CMDNAME" && return
fi
- (. "$1"; cd "$TESTDIR"; touch continue)
+ (. "$1"; cd "$TESTDIR"; echo "$FAILCOUNT" > continue)
cd "$TESTDIR"
- [ -e continue ] || exit 1
+ [ -e continue ] && FAILCOUNT=$(($(cat continue)+$FAILCOUNT)) || exit 1
}
if [ $# -ne 0 ]