--- /dev/null
+#! /bin/bash
+#
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Distributed under the terms of the GNU General Public License v2
+
+# Print help if no args provided.
+if [[ $# -eq 0 || $1 == "--help" || $1 == "-h" ]]; then
+ name=$(basename $0)
+ cat <<-EOF
+ USAGE: ./${name} [list of boards]
+ e.g. ./${name} x86-generic amd64-generic daisy
+ This command will build kernel for the following boards:
+ - x86-generic
+ - amd64-generic
+ - daisy
+ It will then generate a file containing all smatch errors not already
+ in the known errors whitelist. Duplicates will be listed only once.
+
+ If chromeos-kernel is not cros_workon'd for a board, that board will
+ be skipped.
+ EOF
+ exit
+fi
+
+# Put board name arguments into a list.
+BOARDS=()
+SKIPPED_BOARDS=()
+while [[ $# -gt 0 ]]; do
+ board=$1
+ # If kernel is not cros-workon'd, then skip this board.
+ if cros_workon-${board} list | grep -q chromeos-kernel; then
+ BOARDS+=( "${board}" )
+ else
+ SKIPPED_BOARDS+=( "${board}" )
+ fi
+ shift
+done
+
+datestamp() {
+ date +%Y%m%d%H%M%s
+}
+
+# We want to ignore smatch test errors when building kernel, so that we can
+# collect those errors for updating the whitelist.
+export FEATURES='test test-fail-continue'
+export USE="smatch ignore_test_errors"
+LOG_FILES=()
+for board in "${BOARDS[@]}"; do
+ LOG_FILE=/tmp/${board}-kernel-$(datestamp).log
+
+ emerge-${board} chromeos-kernel |& tee "${LOG_FILE}"
+ pipestatus=${PIPESTATUS[*]}
+ if [[ ${pipestatus// } -ne 0 ]]; then
+ echo "Error building kernel for ${board}" >&2
+ exit 1
+ fi
+
+ grep "Non-whitelisted error found:" "${LOG_FILE}" | \
+ grep -o "kernel/files.*" | sort > "${LOG_FILE}.new_errors"
+ LOG_FILES+=( "${LOG_FILE}.new_errors" )
+done
+
+# Create a new log file to contain all errors, overwriting it if it already
+# exists. For each board's new errors, add to this log file the errors that
+# haven't already been added. This creates the union of all new errors.
+NEW_ERRORS_FILE=/tmp/smatch_new_errors-$(datestamp).log
+for log_file in "${LOG_FILES[@]}"; do
+ while read line; do
+ fgrep -q "${line}" "${NEW_ERRORS_FILE}" && continue
+ echo "${line}"
+ done < "${log_file}"
+done > "${NEW_ERRORS_FILE}"
+
+# Rename the new errors file to reflect the new boards, and move it to the
+# current working directory.
+BOARDS_NO_SPACES=$(printf -- -%s "${BOARDS[@]}")
+NEW_ERRORS_FILE_FINAL=smatch_new_errors${BOARDS_NO_SPACES}.log
+if [[ $(wc -l < "${NEW_ERRORS_FILE}") -ne 0 ]]; then
+ mv "${NEW_ERRORS_FILE}" "${NEW_ERRORS_FILE_FINAL}" || exit
+fi
+
+echo "*****************************************************"
+echo "Done building kernel for these boards: ${BOARDS[*]}"
+[[ ${#SKIPPED_BOARDS[@]} -gt 0 ]] && \
+ echo "Skipped these boards because kernel was not cros_workon'd:" \
+ "${SKIPPED_BOARDS[*]}"
+if [[ -e ${NEW_ERRORS_FILE_FINAL} ]]; then
+ echo "New smatch errors are in ${NEW_ERRORS_FILE_FINAL}"
+else
+ echo "No new smatch errors found."
+fi