set -e
set -u
usage() {
local bold=$(tput bold)
local underline=$(tput smul)
local normal=$(tput sgr0)
cat << EOF
${bold}SYNOPSIS${normal}
${bold}${0}${normal} [MODE] [OPTION]... [PARAMETER]...
${bold}DESCRIPTION${normal}
Script automates ${underline}module${normal} build against specific ${underline}kernel${normal} version.
It can download fresh copy of sources from ${underline}github${normal}, untar it,
prepare and build evdi in this 'sandboxed' environment.
${bold}MODES${normal}
${bold}--clean${normal}
Get clean version of ${bold}tar.gz${normal}.
This is the ${underline}default${normal} behaviour.
${bold}--cached${normal}
Use previously downloaded ${bold}tar.gz${normal}.
${bold}--ci${normal}
Use previously extracted sources from ${bold}tar.gz${normal}.
${bold}--repo${normal}
${bold}--repo-clean${normal}
Use clean clone from updated local mirror of ${underline}kernel${normal} repository.
${bold}--repo-cached${normal}
Use clean clone from local mirror of ${underline}kernel${normal} repository.
${bold}--repo-ci${normal}
Use previous clone from local mirror of ${underline}kernel${normal} repository.
${bold}OPTIONS${normal}
${bold}-j${normal} ${underline}jobs${normal}, ${bold}--jobs=${normal}${underline}jobs${normal}, ${bold}--jobs${normal} ${underline}jobs${normal}
Specifies the number of commands to run simultaneously.
Similar as in ${bold}make${normal}.
Default is ${underline}1${normal}.
${bold}-t${normal} ${underline}dir${normal}, ${bold}--tmp=${normal}${underline}dir${normal}, ${bold}--tmp${normal} ${underline}dir${normal}
Subdirectory to store kernel sources.
Default is ${underline}tmp${normal}.
${bold}--help${normal}
Show this message.
${bold}PARAMETERS${normal}
${bold}all${normal}
Build against all ${underline}KVER${normal} specified in ${bold}.travis.yml${normal} file.
${underline}KVERS${normal}
List of kernel versions to build against (e.g. ${underline}3.19 4.10${normal}).
${bold}EXAMPLES${normal}
${bold}${0} 4.12${normal}
Build against newly downloaded sources of ${underline}4.12${normal}.
${bold}${0} --ci master${normal}
Build against already ${underline}extracted${normal} sources of ${underline}master${normal}.
${bold}${0} --ci master --cached 4.11${normal}
Build against already ${underline}extracted${normal} sources of ${underline}master${normal} and
clean sources of previously ${underline}cached${normal} ${bold}tar.gz${normal} of ${underline}4.11${normal}.
${bold}${0} -j 4 all${normal}
Build against ${underline}all${normal} kernels listed in ${bold}.travis.yml${normal}
file, passing ${underline}--jobs=4${normal} to ${bold}make${normal}.
${bold}${0} --repo-cached 5.5${normal}
Build against clean clone of ${underline}5.5${normal} kernel from local
${underline}kernel${normal} mirror.
${bold}${0} --repo-ci 5.6-rc1${normal}
Build against prevously cloned ${underline}5.6-rc1${normal} kernel from
local ${underline}kernel${normal} mirror.
EOF
}
get_versions_from_file() { local PREFIX="^ \- KVER="
grep "${PREFIX}" < "${1}" | sed -e "s/${PREFIX}//g"
}
prepare_tar_gz_sources() { local PACKAGE="${1}.tar.gz"
local SOURCES="${2}"
local CC="${3}"
local SRC_DIR="$(pwd)/${SOURCES}"
if [ "${MODE}" = "CLEAN" ]; then
rm -f "${PACKAGE}"
fi
if [ ! -e "${PACKAGE}" ]; then
wget -O "${PACKAGE}" "https://github.com/torvalds/linux/archive/${PACKAGE}"
fi
if [ "${MODE}" = "CLEAN" ] || [ "${MODE}" = "CACHED" ]; then
rm -rf "${SOURCES}"
fi
if [ ! -e "${SOURCES}" ]; then
tar -xzf "${PACKAGE}"
prepare_kernel "${SRC_DIR}" "${CC}"
elif [ "${MODE}" != "CI" ]; then
prepare_kernel "${SRC_DIR}" "${CC}"
fi
}
prepare_repo_sources() { local PACKAGE="${1}"
local SOURCES="${2}"
local CC="${3}"
local SRC_DIR="$(pwd)/${SOURCES}"
if [ ! -e linux.git ]; then
git clone --bare https://github.com/torvalds/linux linux.git
git remote add github https://github.com/torvalds/linux
fi
if [ "${MODE}" = "REPO-CLEAN" ]; then (
cd linux.git
git fetch github
) fi
if [ "${MODE}" = "REPO-CLEAN" ] || [ "${MODE}" = "REPO-CACHED" ]; then
rm -rf "${SOURCES}"
fi
if [ ! -e "${SOURCES}" ]; then
git clone --depth 1 --branch "${PACKAGE}" "file://$(pwd)/linux.git" "${SOURCES}"
prepare_kernel "${SRC_DIR}" "${CC}"
elif [ "${MODE}" != "REPO-CI" ]; then
prepare_kernel "${SRC_DIR}" "${CC}"
fi
}
prepare_sources() { ( if [ ! -d "${TMP}" ]; then
mkdir "${TMP}"
fi
cd "${TMP}"
if [[ ${MODE} == REPO* ]]; then
prepare_repo_sources "${1}" "${2}" "${3}"
else
prepare_tar_gz_sources "${1}" "${2}" "${3}"
fi
) }
prepare_kernel() { ( cd "${1}"
make olddefconfig CC="${2}" --jobs=${JOBS}
make prepare CC="${2}" --jobs=${JOBS}
make modules_prepare CC="${2}" --jobs=${JOBS}
if [[ ${KVER:0:1} < "5" ]]; then
make scripts CC="${2}" --jobs=${JOBS}
fi
) }
build_one() { local KVER=${1}
local CC="${CC:-gcc}"
local HEADER="$(echo "# Running ${MODE} --jobs=${JOBS} build for ${KVER} in ${TMP}")"
echo ""
echo "${HEADER//?/#}"
echo "${HEADER}"
echo ""
local src_dir
if [ "${KVER}" = "master" ]; then
prepare_sources "master" "linux-master" "${CC}"
src_dir="$(pwd)/${TMP}/linux-master"
else
prepare_sources "v${KVER}" "linux-${KVER}" "${CC}"
src_dir="$(pwd)/${TMP}/linux-${KVER}"
fi
make KDIR="${src_dir}" CC="${CC}" --jobs=${JOBS}
}
MODE="CLEAN"
JOBS="1"
TMP="tmp"
while [[ $# -gt 0 ]]
do
case ${1} in
--clean)
MODE="CLEAN"
;;
--cached)
MODE="CACHED"
;;
--ci)
MODE="CI"
;;
--repo|--repo-clean)
MODE="REPO-CLEAN"
;;
--repo-cached)
MODE="REPO-CACHED"
;;
--repo-ci)
MODE="REPO-CI"
;;
-j|--jobs)
shift
JOBS="${1}"
;;
--jobs=*)
JOBS="${1#*=}"
;;
-t|--tmp)
shift
TMP="${1}"
;;
--tmp=*)
TMP="${1#*=}"
;;
-h|--help)
usage
exit 0
;;
-*)
echo "Unknown option '${1}'" >&2
usage >&2
exit 1
;;
all)
for KVER in $(get_versions_from_file '.travis.yml'); do
build_one "${KVER}"
done
;;
*)
build_one "${1}"
;;
esac
shift
done