#!/bin/bash -eu

# Generate a minimal kernel build tree that can be used to build OOT
# modules and doesn't take up much space.  This is useful for quickly
# verifying kcompat changes across the full range of kernel versions
# we intend to support.
#
# It depends on the linux-<version>-buildfixes branches to allow
# building older kernel versions with a current compiler.  An
# alternative is to install multiple versions (perhaps in chroots or
# containers), but that takes more space.

export_source () {
    local version=$1
    local target_dir=$2

    if git rev-list linux-$version-buildfixes -1 >&/dev/null; then
	ref=linux-$version-buildfixes
    else
	ref=v$version
    fi

    rm -rf "$target_dir"
    git archive --format=tar --prefix="$target_dir/" $ref | tar xf -
}

# Can't assume scripts/config is present
set_config_sym () {
    local name=$1
    local value=$2

    echo "setting $name=$value"

    sed -i -r "/^($name=|# $name is not set)/d" .config
    if [ "$value" = n ]; then
	echo >>.config "# $name is not set"
    else
	echo >>.config "$name=$value"
    fi
}

set_config () {
    make defconfig
    set_config_sym CONFIG_SFC m  # should select everything we need, if present
    set_config_sym CONFIG_CRC32 m
    set_config_sym CONFIG_HWMON m
    set_config_sym CONFIG_I2C m
    set_config_sym CONFIG_I2C_ALGOBIT m
    set_config_sym CONFIG_MTD m
    set_config_sym CONFIG_PCI_IOV y
    set_config_sym CONFIG_PPS m
    set_config_sym CONFIG_PTP_1588_CLOCK m
    set_config_sym CONFIG_SENSORS_LM87 m
    set_config_sym CONFIG_SENSORS_LM90 m
    yes '' | make oldconfig
}

remove_unwanted () {
    # Note we can't use -prune and -delete together.  Read the find manual.
    find . -path ./.config -prune -o \
	-path ./.tmp_versions -prune -o \
	-path ./.version -prune -o \
	-ipath './module*' -prune -o \
	-path ./scripts -prune -o \
	-name 'Kconfig*' -prune -o \
	-name 'Makefile*' -prune -o \
	-name include -prune -o \
	-type f -exec rm -f {} \+
}

export GIT_DIR="$(readlink -f "$1")"
if [ -d "$GIT_DIR/.git" ]; then
    GIT_DIR="$GIT_DIR/.git"
fi
top_dir="$2"
shift 2

mkdir -p "$top_dir"
cd "$top_dir"

for version in "$@"; do
    export_source $version linux-$version
    cd linux-$version
    set_config
    make -j$(nproc)
    remove_unwanted
    cd ..
done
