Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mjeveritt/a7767e0d702191d8df976a6a7d32b9a3 to your computer and use it in GitHub Desktop.
Save mjeveritt/a7767e0d702191d8df976a6a7d32b9a3 to your computer and use it in GitHub Desktop.
/usr/local/portage.mjeveritt/eclass/kernel-mje-1.eclass
# Copyright 1999-2019 Michael Everitt
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: kernel-mje-1.eclass
# @MAINTAINER:
# Michael Everitt <m.j.everitt@iee.org>
# @AUTHOR:
# Gentoo Kernel project <kernel@gentoo.org>
# John Mylchreest <johnm@gentoo.org>
# Mike Pagano <mpagano@gentoo.org>
# <so many, many others, please add yourself>
# @SUPPORTED_EAPIS: 4 5 6
# @BLURB: Eclass for kernel packages
# @DESCRIPTION:
# Modified functions for src_unpack and src_prepare to enable
# better patch handling
# @ECLASS-VARIABLE: KPATCH_DIR
# @DEFAULT_UNSET
# @DESCRIPTION:
# Location for patches to be applied
# @ECLASS-VARIABLE: myLC_ALL
# @DEFAULT_UNSET
# @DESCRIPTION:
# system LC_ALL setting
# @ECLASS-VARIABLE: myLANG
# @DEFAULT_UNSET
# @DESCRIPTION:
# system LANG setting
inherit kernel-2
[[ ${EAPI:-0} == [45] ]] && inherit epatch
[[ ${EAPI:-0} == [456] ]] && inherit estack eapi7-ver
case ${EAPI:-0} in
4|5|6)
EXPORT_FUNCTIONS src_{unpack,prepare} ;;
*) die "${ECLASS}: EAPI ${EAPI} not supported" ;;
esac
# @FUNCTION: unipatch_unpack
# @USAGE: <list of patches to apply>
# @DESCRIPTION:
# Universal function that will unpack/prepare patches to be applied to source
unipatch_unpack() {
local i x y z extention PIPE_CMD UNIPATCH_DROP ELINE
local STRICT_COUNT PATCH_LEVEL
# set to a standard locale to ensure sorts are ordered properly.
myLC_ALL="${LC_ALL}"
myLANG="${LANG}"
LC_ALL="C"
LANG=""
[ -z "${KPATCH_DIR}" ] && KPATCH_DIR="${WORKDIR}/patches/"
[ ! -d ${KPATCH_DIR} ] && mkdir -p ${KPATCH_DIR}
# We're gonna need it when doing patches with a predefined patchlevel
eshopts_push -s extglob
# This function will unpack all passed tarballs, add any passed patches,
# and remove any passed patchnumbers
# usage can be either via an env var or by params
# although due to the nature we pass this within this eclass
# it shall be by param only.
# -z "${UNIPATCH_LIST}" ] && UNIPATCH_LIST="${@}"
UNIPATCH_LIST="${@}"
#unpack any passed tarballs
for i in ${UNIPATCH_LIST}; do
if echo ${i} | grep -qs -e "\.tar" -e "\.tbz" -e "\.tgz" ; then
if [ -n "${UNIPATCH_STRICTORDER}" ]; then
unset z
STRICT_COUNT=$((10#${STRICT_COUNT} + 1))
for((y=0; y<$((6 - ${#STRICT_COUNT})); y++));
do z="${z}0";
done
PATCH_ORDER="${z}${STRICT_COUNT}"
mkdir -p "${KPATCH_DIR}/${PATCH_ORDER}"
pushd "${KPATCH_DIR}/${PATCH_ORDER}" >/dev/null
unpack ${i##*/}
popd >/dev/null
else
pushd "${KPATCH_DIR}" >/dev/null
unpack ${i##*/}
popd >/dev/null
fi
[[ ${i} == *:* ]] && echo ">>> Strict patch levels not currently supported for tarballed patchsets"
else
extention=${i/*./}
extention=${extention/:*/}
PIPE_CMD=""
case ${extention} in
xz) PIPE_CMD="xz -dc";;
lzma) PIPE_CMD="lzma -dc";;
bz2) PIPE_CMD="bzip2 -dc";;
patch*) PIPE_CMD="cat";;
diff) PIPE_CMD="cat";;
gz|Z|z) PIPE_CMD="gzip -dc";;
ZIP|zip) PIPE_CMD="unzip -p";;
*) UNIPATCH_DROP="${UNIPATCH_DROP} ${i/:*/}";;
esac
PATCH_LEVEL=${i/*([^:])?(:)}
i=${i/:*/}
x=${i/*\//}
x=${x/\.${extention}/}
if [ -n "${PIPE_CMD}" ]; then
if [ ! -r "${i}" ]; then
echo
eerror "FATAL: unable to locate:"
eerror "${i}"
eerror "for read-only. The file either has incorrect permissions"
eerror "or does not exist."
die Unable to locate ${i}
fi
if [ -n "${UNIPATCH_STRICTORDER}" ]; then
unset z
STRICT_COUNT=$((10#${STRICT_COUNT} + 1))
for((y=0; y<$((6 - ${#STRICT_COUNT})); y++));
do z="${z}0";
done
PATCH_ORDER="${z}${STRICT_COUNT}"
mkdir -p ${KPATCH_DIR}/${PATCH_ORDER}/
$(${PIPE_CMD} ${i} > ${KPATCH_DIR}/${PATCH_ORDER}/${x}.patch${PATCH_LEVEL}) || die "uncompressing patch failed"
else
$(${PIPE_CMD} ${i} > ${KPATCH_DIR}/${x}.patch${PATCH_LEVEL}) || die "uncompressing patch failed"
fi
fi
fi
# If experimental was not chosen by the user, drop experimental patches not in K_EXP_GENPATCHES_LIST.
if [[ "${i}" == *"genpatches-"*".experimental."* && -n ${K_EXP_GENPATCHES_PULL} ]] ; then
if [[ -z ${K_EXP_GENPATCHES_NOUSE} ]] && use experimental; then
continue
fi
local j
for j in ${KPATCH_DIR}/*/50*_*.patch*; do
for k in ${K_EXP_GENPATCHES_LIST} ; do
[[ "$(basename ${j})" == ${k}* ]] && continue 2
done
UNIPATCH_DROP+=" $(basename ${j})"
done
else
UNIPATCH_LIST_GENPATCHES+=" ${DISTDIR}/${tarball}"
debug-print "genpatches tarball: $tarball"
local GCC_MAJOR_VER=$(gcc-major-version)
local GCC_MINOR_VER=$(gcc-minor-version)
# optimization patch for gcc < 8.X and kernel > 4.13
if [[ ${GCC_MAJOR_VER} -lt 8 ]] && [[ ${GCC_MAJOR_VER} -gt 4 ]]; then
if kernel_is ge 4 13 ; then
UNIPATCH_DROP+=" 5011_enable-cpu-optimizations-for-gcc8.patch"
fi
# optimization patch for gcc >= 8 and kernel ge 4.13
elif [[ "${GCC_MAJOR_VER}" -ge 8 ]]; then
if kernel_is ge 4 13; then
# support old kernels for a period. For now, remove as all gcc versions required are masked
UNIPATCH_DROP+=" 5010_enable-additional-cpu-optimizations-for-gcc.patch"
UNIPATCH_DROP+=" 5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch"
fi
fi
fi
done
#populate KPATCH_DIRS so we know where to look to remove the excludes
x=${KPATCH_DIR}
KPATCH_DIR=""
for i in $(find ${x} -type d | sort -n); do
KPATCH_DIR="${KPATCH_DIR} ${i}"
done
# do not apply fbcondecor patch to sparc/sparc64 as it breaks boot
# bug #272676
if [[ "$(tc-arch)" = "sparc" || "$(tc-arch)" = "sparc64" ]]; then
if [[ ${KV_MAJOR} -ge 3 || ${KV_MAJOR}.${KV_MINOR}.${KV_PATCH} > 2.6.28 ]]; then
if [[ ! -z ${K_WANT_GENPATCHES} ]] ; then
UNIPATCH_DROP="${UNIPATCH_DROP} *_fbcondecor*.patch"
echo
ewarn "fbcondecor currently prevents sparc/sparc64 from booting"
ewarn "for kernel versions >= 2.6.29. Removing fbcondecor patch."
ewarn "See https://bugs.gentoo.org/show_bug.cgi?id=272676 for details"
echo
fi
fi
fi
#so now lets get rid of the patchno's we want to exclude
UNIPATCH_DROP="${UNIPATCH_EXCLUDE} ${UNIPATCH_DROP}"
for i in ${UNIPATCH_DROP}; do
ebegin "Excluding Patch #${i}"
for x in ${KPATCH_DIR}; do rm -f ${x}/${i}* 2>/dev/null; done
eend $?
done
eshopts_pop
}
# @FUNCTION: unipatch_apply
# @USAGE:
# @DESCRIPTION:
# Universal function that will actually apply patches to source
unipatch_apply() {
local i x PATCH_DEPTH STDERR_T
# We're gonna need it when doing patches with a predefined patchlevel
eshopts_push -s extglob
# and now, finally, we patch it :)
for x in ${KPATCH_DIR}; do
for i in $(find ${x} -maxdepth 1 -iname "*.patch*" -or -iname "*.diff*" | sort -n); do
STDERR_T="${T}/${i/*\//}"
STDERR_T="${STDERR_T/.patch*/.err}"
[ -z ${i/*.patch*/} ] && PATCH_DEPTH=${i/*.patch/}
#[ -z ${i/*.diff*/} ] && PATCH_DEPTH=${i/*.diff/}
if [ -z "${PATCH_DEPTH}" ]; then PATCH_DEPTH=0; fi
####################################################################
# IMPORTANT: This is temporary code to support Linux git 3.15_rc1! #
# #
# The patch contains a removal of a symlink, followed by addition #
# of a file with the same name as the symlink in the same #
# location; this causes the dry-run to fail, filed bug #507656. #
# #
# https://bugs.gentoo.org/show_bug.cgi?id=507656 #
####################################################################
if [[ -n ${K_FROM_GIT} ]] ; then
if [[ ${KV_MAJOR} -gt 3 || ( ${KV_MAJOR} -eq 3 && ${KV_PATCH} -gt 15 ) &&
${RELEASETYPE} == -rc ]] ; then
ebegin "Applying ${i/*\//} (-p1)"
if [ $(patch -p1 --no-backup-if-mismatch -f < ${i} >> ${STDERR_T}) "$?" -le 2 ]; then
eend 0
rm ${STDERR_T} || die
break
else
eend 1
eerror "Failed to apply patch ${i/*\//}"
eerror "Please attach ${STDERR_T} to any bug you may post."
eshopts_pop
die "Failed to apply ${i/*\//} on patch depth 1."
fi
fi
fi
####################################################################
while [ ${PATCH_DEPTH} -lt 5 ]; do
echo "Attempting Dry-run:" >> ${STDERR_T}
echo "cmd: patch -p${PATCH_DEPTH} --no-backup-if-mismatch --dry-run -f < ${i}" >> ${STDERR_T}
echo "=======================================================" >> ${STDERR_T}
if [ $(patch -p${PATCH_DEPTH} --no-backup-if-mismatch --dry-run -f < ${i} >> ${STDERR_T}) $? -eq 0 ]; then
ebegin "Applying ${i/*\//} (-p${PATCH_DEPTH})"
echo "Attempting patch:" > ${STDERR_T}
echo "cmd: patch -p${PATCH_DEPTH} --no-backup-if-mismatch -f < ${i}" >> ${STDERR_T}
echo "=======================================================" >> ${STDERR_T}
if [ $(patch -p${PATCH_DEPTH} --no-backup-if-mismatch -f < ${i} >> ${STDERR_T}) "$?" -eq 0 ]; then
eend 0
rm ${STDERR_T} || die
break
else
eend 1
eerror "Failed to apply patch ${i/*\//}"
eerror "Please attach ${STDERR_T} to any bug you may post."
eshopts_pop
die "Failed to apply ${i/*\//} on patch depth ${PATCH_DEPTH}."
fi
else
PATCH_DEPTH=$((${PATCH_DEPTH} + 1))
fi
done
if [ ${PATCH_DEPTH} -eq 5 ]; then
eerror "Failed to dry-run patch ${i/*\//}"
eerror "Please attach ${STDERR_T} to any bug you may post."
eshopts_pop
die "Unable to dry-run patch on any patch depth lower than 5."
fi
done
done
# When genpatches is used, we want to install 0000_README which documents
# the patches that were used; such that the user can see them, bug #301478.
if [[ ! -z ${K_WANT_GENPATCHES} ]] ; then
UNIPATCH_DOCS="${UNIPATCH_DOCS} 0000_README"
fi
# When files listed in UNIPATCH_DOCS are found in KPATCH_DIR's, we copy it
# to the temporary directory and remember them in UNIPATCH_DOCS to install
# them during the install phase.
local tmp
for x in ${KPATCH_DIR}; do
for i in ${UNIPATCH_DOCS}; do
if [[ -f ${x}/${i} ]] ; then
tmp="${tmp} ${i}"
cp -f "${x}/${i}" "${T}"/ || die
fi
done
done
UNIPATCH_DOCS="${tmp}"
# clean up KPATCH_DIR's - fixes bug #53610
for x in ${KPATCH_DIR}; do rm -Rf ${x}; done
LC_ALL="${myLC_ALL}"
LANG="${myLANG}"
eshopts_pop
}
# @FUNCTION: kernel-mje-1_src_unpack
# @USAGE:
# @DESCRIPTION:
# unpack sources ONLY !
kernel-mje-1_src_unpack() {
universal_unpack
# request UNIPATCH_LIST_GENPATCHES in phase since it calls 'use'
handle_genpatches --set-unipatch-list
[[ -n ${UNIPATCH_LIST} || -n ${UNIPATCH_LIST_DEFAULT} || -n ${UNIPATCH_LIST_GENPATCHES} ]] && \
unipatch_unpack "${UNIPATCH_LIST_DEFAULT} ${UNIPATCH_LIST_GENPATCHES} ${UNIPATCH_LIST}"
}
# @FUNCTION: kernel-2_src_prepare
# @USAGE:
# @DESCRIPTION:
# Apply any user patches
kernel-mje-1_src_prepare() {
debug-print "Doing unipatch..."
unipatch_apply
debug-print "Doing premake..."
# allow ebuilds to massage the source tree after patching but before
# we run misc `make` functions below
[[ $(type -t kernel-2_hook_premake) == "function" ]] && kernel-2_hook_premake
debug-print "Doing unpack_set_extraversion..."
[[ -z ${K_NOSETEXTRAVERSION} ]] && unpack_set_extraversion
unpack_fix_install_path
# Setup xmakeopts and cd into sourcetree.
env_setup_xmakeopts
cd "${S}"
# We dont need a version.h for anything other than headers
# at least, I should hope we dont. If this causes problems
# take out the if/fi block and inform me please.
# unpack_2_6 should now be 2.6.17 safe anyways
if [[ ${ETYPE} == headers ]]; then
kernel_is 2 4 && unpack_2_4
kernel_is 2 6 && unpack_2_6
fi
if [[ $K_DEBLOB_AVAILABLE == 1 ]] && use deblob ; then
cp "${DISTDIR}/${DEBLOB_A}" "${T}" || die "cp ${DEBLOB_A} failed"
cp "${DISTDIR}/${DEBLOB_CHECK_A}" "${T}/deblob-check" || die "cp ${DEBLOB_CHECK_A} failed"
chmod +x "${T}/${DEBLOB_A}" "${T}/deblob-check" || die "chmod deblob scripts failed"
fi
# fix a problem on ppc where TOUT writes to /usr/src/linux breaking sandbox
# only do this for kernel < 2.6.27 since this file does not exist in later
# kernels
if [[ -n ${KV_MINOR} && ${KV_MAJOR}.${KV_MINOR}.${KV_PATCH} < 2.6.27 ]] ; then
sed -i \
-e 's|TOUT := .tmp_gas_check|TOUT := $(T).tmp_gas_check|' \
"${S}"/arch/ppc/Makefile
else
sed -i \
-e 's|TOUT := .tmp_gas_check|TOUT := $(T).tmp_gas_check|' \
"${S}"/arch/powerpc/Makefile
fi
debug-print "Applying any user patches"
# apply any user patches
case ${EAPI:-0} in
4|5) epatch_user ;;
6) eapply_user ;;
esac
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment