#!/bin/bash # Script to merge all configs and run 'make oldconfig' on it to wade out bad juju. # Then split the configs into distro-commmon and flavour-specific parts # # See this page for more details: # http://dev.chromium.org/chromium-os/how-tos-and-troubleshooting/kernel-configuration error() { printf 'error: %b\n' "$*" >&2 } die() { error "$@" exit 1 } usage() { cat <<-EOF Usage: ${0##*/} [options] Options: -h This screen. EOF if [[ $# -gt 0 ]]; then echo die "$@" else exit 0 fi } build_one() { local arch=$1 local kernarch # Map debian archs to kernel archs. case "${arch}" in armel) kernarch="arm" ;; *) kernarch="${arch}" ;; esac echo "" echo "***************************************" echo "* Processing ${arch} (${kernarch}) ... " local O="$(pwd)/build/${arch}" mkdir -p "${O}" local config local archconfdir="${confdir}/${arch}" local flavourconfigs=( $(cd "${archconfdir}" && echo *.flavour.config) ) # Merge configs # We merge base.config + common.config + .flavour.config for config in "${flavourconfigs[@]}"; do cat \ "${base_conf}" \ "${archconfdir}/common.config" \ "${archconfdir}/${config}" \ > "${O}/.config" # Call oldconfig or menuconfig case ${mode} in oldconfig|olddefconfig) # Weed out incorrect config parameters echo "* Run ${mode} on ${arch}/${config} ..." make -j O="${O}" ARCH=${kernarch} "${mode}" ;; editconfig) # Interactively edit config parameters echo "* ${arch}/${config}: press to edit, S to skip" read -s -n 1 case ${REPLY} in s|S) echo "* Skip: running oldconfig" make -j O="${O}" ARCH=${kernarch} oldconfig ;; *) echo "* Running menuconfig" make -j O="${O}" ARCH=${kernarch} menuconfig ;; esac ;; *) # Bad! die "invalid mode ${mode}" ;; esac cat "${O}/.config" > "${archconfdir}/${config}" if [[ "${keep}" == "1" ]]; then # oldconfig is probably redundant because .config is # likely formatted already at this point, however # this only take a split-second and could flag some # issues. make -j O="${O}" ARCH=${kernarch} oldconfig make -j O="${O}" ARCH=${kernarch} savedefconfig mv "${O}"/.config "CONFIGS/${arch}-${config}" mv "${O}"/defconfig "CONFIGS/${arch}-${config}.def" fi done echo "Running splitconfig for ${arch}" echo # Can we make this more robust by avoiding $tmpdir completely? # This approach was used for now because I didn't want to change # splitconfig pushd "${archconfdir}" >/dev/null rm common.config "${bindir}/splitconfig" mv common.config "${tmpdir}/${arch}.config" popd >/dev/null } cleanup() { rm -rf "${tmpdir}" } cd_kerneldir() { # We have to be in the top level kernel source directory. if [[ ! -f MAINTAINERS || ! -f Makefile ]]; then # See if we can find it automatically first. local d=$(realpath "${0%/*}/../..") cd "${d}" if [[ ! -f MAINTAINERS || ! -f Makefile ]]; then die "This does not appear to be the kernel source directory." else echo "Using top kernel dir: ${d}" fi fi } main() { # Process use flags first (so -h works nicely). local opt while getopts "h" opt; do case ${opt} in h) usage ;; *) usage "Invalid option ${opt}" ;; esac done shift $(( OPTIND - 1 )) # Process the remaining args. local mode=$1 case ${mode} in oldconfig|olddefconfig) ;; # All is good editconfig) ;; # All is good genconfig) ;; # All is good *) usage "invalid/missing mode: ${mode}" ;; esac # Then make sure we're in the right directory. cd_kerneldir # Set up variables the build func expects. local kerneldir=$(pwd) local confdir="${kerneldir}/chromeos/config" local archs=( x86_64 armel ) local bindir="${kerneldir}/chromeos/scripts" local base_conf="${confdir}/base.config" export tmpdir=$(mktemp -d) trap cleanup EXIT local keep=0 if [[ "${mode}" == "genconfig" ]]; then keep=1 mode="oldconfig" mkdir -p CONFIGS fi mkdir -p build echo "running ${mode} for ${archs[*]}" echo "" for arch in "${archs[@]}"; do build_one "${arch}" done # Now run splitconfig on all the .common.config copied to $tmpdir. pushd "${tmpdir}" >/dev/null "${bindir}/splitconfig" mv "common.config" "${base_conf}" for arch in "${archs[@]}"; do mv "${arch}.config" "${confdir}/${arch}/common.config" done } main "$@"