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