This script performs build testing, by building several configurations
several times. The script is introduced to improve the consistency of
testing changes in the kernel configuration.

This version build randconfig 9 times, as well as allyesconfig,
allnoconfig and allmodconfig. Depending on the used machine and system
setup, the script might take a while to finish.

The script logs all the used config files, as well as the output of the
build commands to a log directory "build_check_logs", so that this data
can be retrieved after running the script.

Signed-off-by: Norbert Manthey <[email protected]>
---
 scripts/check_build.sh | 136 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 136 insertions(+)
 create mode 100755 scripts/check_build.sh

diff --git a/scripts/check_build.sh b/scripts/check_build.sh
new file mode 100755
index 0000000..a100d99
--- /dev/null
+++ b/scripts/check_build.sh
@@ -0,0 +1,136 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Check whether kernel changes compile with multiple configurations.
+# Configurations that fail for the current commit are tested on an upstream
+# commit, and failures are ignored in case the configuration fails on the
+# upstream commit as well.
+#
+# Usage:
+# ./scripts/check_build.sh [upstream-commit]
+#
+# Example:
+# ./scripts/check_build.sh origin/master
+
+# Fail early on error or uninitialized values
+set -e -u
+
+# Write all files to this directory
+declare -r LOG_DIR=build_check_logs
+
+# Gather all configurations we should build, in form of make targets
+collect_configurations ()
+{
+       local CONFIGS="randconfig allyesconfig allnoconfig allmodconfig"
+       local -i I=0
+
+       while [ "$I" -le 8 ]; do I=$((I+1)); CONFIGS+=" randconfig"; done
+
+       echo "$CONFIGS"
+}
+
+# Build the kernel with the current configuration, return the status, log to $1
+build ()
+{
+       local -r LOG_FILE="$1"
+       local -i STATUS=0
+
+       make clean -j $(nproc) &> /dev/null
+       make -j $(nproc) &>> "$LOG_FILE" || STATUS=$?
+
+       echo "build status: $STATUS" >> "$LOG_FILE"
+       echo "[$SECONDS] build status: $STATUS"
+       return "$STATUS"
+}
+
+# Check whether we're executing from a clean repository, and proper location
+check_environment()
+{
+       local -r UPSTREAM_COMMIT="$1"
+
+       if [ ! -x scripts/check_build.sh ]; then
+               echo "error: please execute script from repository root!"
+               exit 1
+       fi
+
+       if ! git diff-index --quiet HEAD --; then
+               echo "error: please commit or stash your local changes!"
+               exit 1
+       fi
+
+       if ! git cat-file -e "$UPSTREAM_COMMIT" &> /dev/null; then
+               echo "error: upstream commit $UPSTREAM_COMMIT does not exist!"
+               exit 1
+       fi
+}
+
+TEST_COMMIT=$(git rev-parse --short HEAD)
+
+LAST_TAG=$(git describe --abbrev=0)
+DEFAULT_UPSTREAM="origin/master"
+[ -z "$LAST_TAG" ] || DEFAULT_UPSTREAM="$LAST_TAG"
+UPSTREAM_COMMIT="${1:-$DEFAULT_UPSTREAM}"
+
+# Before starting, check call location and git environment
+check_environment "$UPSTREAM_COMMIT"
+
+# Collect status, as well as failing configuration file names
+declare -i OVERALL_STATUS=0
+mkdir -p "$LOG_DIR"
+BRANCH_FAILS=""
+UPSTREAM_FAILS=""
+
+# Build multiple configurations
+declare -i COUNT=0
+declare -r CONFIGS=$(collect_configurations)
+echo "[$SECONDS] Check commit $TEST_COMMIT with upstream reference 
$UPSTREAM_COMMIT"
+for config in $CONFIGS
+do
+       COUNT=$((COUNT+1))
+       echo "[$SECONDS] build $config as build nr $COUNT"
+       LOG_FILE=$LOG_DIR/build-"$COUNT"-"$config".log
+
+       # Prepare configuration, and memorize it
+       STATUS=0
+       make "$config" &> "$LOG_FILE" || STATUS=$?
+       cp .config $LOG_DIR/config-"$COUNT"-"$config"
+
+       # Try to build with current configuration
+       build "$LOG_FILE" || STATUS=$?
+
+       # Evaluate build failure
+       if [ "$STATUS" -ne 0 ]
+       then
+               cp .config "$LOG_DIR"/config-failing-branch-"$COUNT"-"$config"
+               echo "[$SECONDS] check whether current configuration fails 
upstream as well ..."
+               echo "[$SECONDS] go back in time to commit $UPSTREAM_COMMIT"
+
+               # Check whether upstream commit builds
+               git checkout "$UPSTREAM_COMMIT" &>> "$LOG_FILE"
+               UPSTREAM_STATUS=0
+               build "$LOG_FILE" || UPSTREAM_STATUS=$?
+               git checkout "$TEST_COMMIT" &>> "$LOG_FILE"
+
+               if [ "$UPSTREAM_STATUS" -ne 0 ]
+               then
+                       echo "[$SECONDS] upstream build fails as well, ignore 
failure"
+                       cp .config 
"$LOG_DIR"/config-failing-upstream-"$COUNT"-"$config"
+                       UPSTREAM_FAILS+=" config-$COUNT-$config"
+               else
+                       echo "[$SECONDS] upstream build succeeds, while branch 
build fails"
+                       BRANCH_FAILS+=" config-$COUNT-$config"
+                       OVERALL_STATUS=1
+               fi
+
+               echo "[$SECONDS] jump back to commit under test, $TEST_COMMIT"
+       fi
+done
+
+# Print summary, and exit with status of local changes
+echo "Finished after $SECONDS seconds"
+echo "Found upstream failures: $UPSTREAM_FAILS"
+echo "Found branch failures: $BRANCH_FAILS"
+echo "Collected configurations and logs can be found in $LOG_DIR"
+
+# Exit 0, if no build fails, or the upstream commit always fails as well
+exit $OVERALL_STATUS
-- 
2.7.4

Amazon Development Center Germany GmbH
Berlin - Dresden - Aachen
main office: Krausenstr. 38, 10117 Berlin
Geschaeftsfuehrer: Dr. Ralf Herbrich, Christian Schlaeger
Ust-ID: DE289237879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B

Reply via email to