| 1 | #!/bin/sh
 | 
|---|
| 2 | 
 | 
|---|
| 3 | #
 | 
|---|
| 4 | # Copyright (c) 2014 Vojtech Horky
 | 
|---|
| 5 | # All rights reserved.
 | 
|---|
| 6 | #
 | 
|---|
| 7 | # Redistribution and use in source and binary forms, with or without
 | 
|---|
| 8 | # modification, are permitted provided that the following conditions
 | 
|---|
| 9 | # are met:
 | 
|---|
| 10 | #
 | 
|---|
| 11 | # - Redistributions of source code must retain the above copyright
 | 
|---|
| 12 | #   notice, this list of conditions and the following disclaimer.
 | 
|---|
| 13 | # - Redistributions in binary form must reproduce the above copyright
 | 
|---|
| 14 | #   notice, this list of conditions and the following disclaimer in the
 | 
|---|
| 15 | #   documentation and/or other materials provided with the distribution.
 | 
|---|
| 16 | # - The name of the author may not be used to endorse or promote products
 | 
|---|
| 17 | #   derived from this software without specific prior written permission.
 | 
|---|
| 18 | #
 | 
|---|
| 19 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 | 
|---|
| 20 | # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
|---|
| 21 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
|---|
| 22 | # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
|---|
| 23 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
|---|
| 24 | # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
|---|
| 25 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
|---|
| 26 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
|---|
| 27 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
|---|
| 28 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
|---|
| 29 | #
 | 
|---|
| 30 | 
 | 
|---|
| 31 | 
 | 
|---|
| 32 | LOOPS=1
 | 
|---|
| 33 | JOBS=1
 | 
|---|
| 34 | MAX_RETRIES=20
 | 
|---|
| 35 | FILENAME_PREFIX=random_run_
 | 
|---|
| 36 | PRUNE_CONFIG_FILE=${FILENAME_PREFIX}prune.config
 | 
|---|
| 37 | 
 | 
|---|
| 38 | echo -n "">"$PRUNE_CONFIG_FILE"
 | 
|---|
| 39 | 
 | 
|---|
| 40 | while getopts n:j:x:hs option; do
 | 
|---|
| 41 |         case $option in
 | 
|---|
| 42 |         n)
 | 
|---|
| 43 |                 LOOPS="$OPTARG"
 | 
|---|
| 44 |                 ;;
 | 
|---|
| 45 |         j)
 | 
|---|
| 46 |                 JOBS="$OPTARG"
 | 
|---|
| 47 |                 ;;
 | 
|---|
| 48 |         x)
 | 
|---|
| 49 |                 echo "$OPTARG" | tr -d ' ' >>"$PRUNE_CONFIG_FILE"
 | 
|---|
| 50 |                 ;;
 | 
|---|
| 51 |         s)
 | 
|---|
| 52 |                 ;;
 | 
|---|
| 53 |         *|h)
 | 
|---|
| 54 |                 echo "Usage: $0 [options]"
 | 
|---|
| 55 |                 echo "where [options] could be:"
 | 
|---|
| 56 |                 echo
 | 
|---|
| 57 |                 echo "  -n LOOPS"
 | 
|---|
| 58 |                 echo "      How many configurations to check."
 | 
|---|
| 59 |                 echo "      (Default is one configuration.)"
 | 
|---|
| 60 |                 echo "  -j PARALLELISM"
 | 
|---|
| 61 |                 echo "      How many parallel jobs to execute by 'make'."
 | 
|---|
| 62 |                 echo "      (Default is single job configuration.)"
 | 
|---|
| 63 |                 echo "  -s"
 | 
|---|
| 64 |                 echo "      Use only supported compilers."
 | 
|---|
| 65 |                 echo "      (That is, only GCC cross-compiler and Clang.)"
 | 
|---|
| 66 |                 echo "  -x CONFIG_OPTION=value"
 | 
|---|
| 67 |                 echo "      Skip the configuration if this option is present."
 | 
|---|
| 68 |                 echo "      (Example: CONFIG_BINUTILS=n means that only configurations"
 | 
|---|
| 69 |                 echo "      where binutils *are* included would be built.)"
 | 
|---|
| 70 |                 echo "  -h"
 | 
|---|
| 71 |                 echo "      Print this help and exit."
 | 
|---|
| 72 |                 echo
 | 
|---|
| 73 |                 if [ "$option" = "h" ]; then
 | 
|---|
| 74 |                         exit 0
 | 
|---|
| 75 |                 else
 | 
|---|
| 76 |                         exit 1
 | 
|---|
| 77 |                 fi
 | 
|---|
| 78 |                 ;;
 | 
|---|
| 79 |         esac
 | 
|---|
| 80 | done
 | 
|---|
| 81 | 
 | 
|---|
| 82 | 
 | 
|---|
| 83 | COUNTER=0
 | 
|---|
| 84 | FAILED=0
 | 
|---|
| 85 | while [ $COUNTER -lt $LOOPS ]; do
 | 
|---|
| 86 |         COUNTER=$(( $COUNTER + 1 ))
 | 
|---|
| 87 |         echo "Try #$COUNTER ($FAILED failed):" >&2
 | 
|---|
| 88 | 
 | 
|---|
| 89 |         (
 | 
|---|
| 90 |                 echo "  Cleaning after previous build." >&2
 | 
|---|
| 91 |                 make distclean -j$JOBS 2>&1 || exit 1
 | 
|---|
| 92 | 
 | 
|---|
| 93 | 
 | 
|---|
| 94 |                 echo "  Preparing random configuration." >&2
 | 
|---|
| 95 |                 # It would be nicer to allow set the constraints directly to
 | 
|---|
| 96 |                 # the tools/config.py script but this usually works.
 | 
|---|
| 97 |                 # We retry $MAX_RETRIES before aborting this run completely.
 | 
|---|
| 98 |                 RETRIES=0
 | 
|---|
| 99 |                 while true; do
 | 
|---|
| 100 |                         RETRIES=$(( $RETRIES + 1 ))
 | 
|---|
| 101 |                         if [ $RETRIES -ge $MAX_RETRIES ]; then
 | 
|---|
| 102 |                                 echo "  Failed to generate random configuration with given constraints after $RETRIES tries." >&2
 | 
|---|
| 103 |                                 exit 2
 | 
|---|
| 104 |                         fi
 | 
|---|
| 105 | 
 | 
|---|
| 106 |                         make random-config 2>&1 || exit 1
 | 
|---|
| 107 | 
 | 
|---|
| 108 |                         tr -d ' ' <Makefile.config >"${FILENAME_PREFIX}config.trimmed"
 | 
|---|
| 109 | 
 | 
|---|
| 110 |                         THIS_CONFIG_OKAY=true
 | 
|---|
| 111 |                         while read pattern; do
 | 
|---|
| 112 |                                 if grep -q -e "$pattern" "${FILENAME_PREFIX}config.trimmed"; then
 | 
|---|
| 113 |                                         THIS_CONFIG_OKAY=false
 | 
|---|
| 114 |                                         break
 | 
|---|
| 115 |                                 fi
 | 
|---|
| 116 |                         done <"$PRUNE_CONFIG_FILE"
 | 
|---|
| 117 | 
 | 
|---|
| 118 |                         rm -f "${FILENAME_PREFIX}config.trimmed"
 | 
|---|
| 119 | 
 | 
|---|
| 120 |                         if $THIS_CONFIG_OKAY; then
 | 
|---|
| 121 |                                 break
 | 
|---|
| 122 |                         fi
 | 
|---|
| 123 |                 done
 | 
|---|
| 124 | 
 | 
|---|
| 125 | 
 | 
|---|
| 126 |                 # Report basic info about the configuration and build it
 | 
|---|
| 127 |                 BASIC_CONFIG=`sed -n \
 | 
|---|
| 128 |                         -e 's#PLATFORM = \(.*\)#\1#p' \
 | 
|---|
| 129 |                         -e 's#MACHINE = \(.*\)#\1#p' \
 | 
|---|
| 130 |                         -e 's#COMPILER = \(.*\)#\1#p' \
 | 
|---|
| 131 |                         Makefile.config \
 | 
|---|
| 132 |                         | paste '-sd,' | sed 's#,#, #g'`
 | 
|---|
| 133 |                 echo -n "  Building ($BASIC_CONFIG)... " >&2
 | 
|---|
| 134 | 
 | 
|---|
| 135 |                 make -j$JOBS 2>&1
 | 
|---|
| 136 |                 if [ $? -eq 0 ]; then
 | 
|---|
| 137 |                         echo "okay." >&2
 | 
|---|
| 138 |                         exit 0
 | 
|---|
| 139 |                 else
 | 
|---|
| 140 |                         echo "failed." >&2
 | 
|---|
| 141 |                         exit 1
 | 
|---|
| 142 |                 fi
 | 
|---|
| 143 | 
 | 
|---|
| 144 |         ) >random_run_$COUNTER.log
 | 
|---|
| 145 |         RC=$?
 | 
|---|
| 146 | 
 | 
|---|
| 147 |         if [ $RC -ne 0 ]; then
 | 
|---|
| 148 |                 tail -n 10 random_run_$COUNTER.log | sed 's#.*#    | &#'
 | 
|---|
| 149 |                 FAILED=$(( $FAILED + 1 ))
 | 
|---|
| 150 |         fi
 | 
|---|
| 151 | 
 | 
|---|
| 152 |         if [ -e Makefile.config ]; then
 | 
|---|
| 153 |                 cp Makefile.config "$FILENAME_PREFIX$COUNTER.Makefile.config"
 | 
|---|
| 154 |                 cp config.h "$FILENAME_PREFIX$COUNTER.config.h"
 | 
|---|
| 155 |         fi
 | 
|---|
| 156 | done
 | 
|---|
| 157 | 
 | 
|---|
| 158 | rm "$PRUNE_CONFIG_FILE"
 | 
|---|
| 159 | 
 | 
|---|
| 160 | echo "Out of $LOOPS tries, $FAILED configurations failed to compile." >&2
 | 
|---|