--- kernel-mod.eclass 2004-02-29 20:08:22.536926456 -0500 +++ kernel-mod.eclass.koutput2 2004-02-29 20:09:25.379372952 -0500 @@ -8,17 +8,45 @@ # This eclass differs from kmod.eclass because it doesn't require modules # to be added to the kernel source tree first. +# Variables you can use to change behavior +# +# KERNEL_MOD_SOURCES - space seperated list of source to unpack in +# kernel-mod_src_unpack() if you don't want ${A} unpacked. +# +# KERNEL_MOD_KOUTPUT_PATCH - Patch to apply in src_unpack() if a seperate output +# directory is detected. +# + +inherit eutils + ECLASS=kernel-mod INHERITED="$INHERITED $ECLASS" S=${WORKDIR}/${P} DESCRIPTION="Based on the $ECLASS eclass" SRC_URI="${SRC_URI:-unknown - please fix me!!}" -KERNEL_DIR="${KERNEL_DIR:-/usr/src/linux}" +KERNEL_DIR="${KERNEL_DIR:-${ROOT}/usr/src/linux}" kernel-mod_getmakefilevar () { - grep $1 $2 | head -n 1 | cut -d = -f 2- | awk '{ print $1 }' + grep $1 $2 | head -n 1 | grep -v ":=" | cut -d = -f 2- | awk '{ print $1 }' +} + +kernel-mod_getconfigvar() +{ + local configopt="CONFIG_${1}" + local configresult + + if [ -z ${KV_OUTPUT} ]; then + kernel-mod_getversion + fi + + configresult="`grep ^$configopt ${KV_OUTPUT}/.config | cut -d= -f 2-`" + if [ -z "${configresult}" ]; then + echo "n" + else + echo ${configresult} | awk '{ print $1 }' + fi } kernel-mod_getversion () @@ -29,42 +57,45 @@ # the Linux kernel that we are going to compile against if [ -h ${KERNEL_DIR} ] ; then - einfo "${KERNEL_DIR} is a symbolic link" + einfo "`echo ${KERNEL_DIR} | tr -s /` is a symbolic link" einfo "Determining the real directory of the Linux kernel source code" - KV_DIR="`ls -ld --full-time ${KERNEL_DIR} | awk '{ print $11 }'`" + KV_DIR="`readlink ${KERNEL_DIR}`" elif [ -d ${KERNEL_DIR} ] ; then - einfo "${KERNEL_DIR} is a real directory" - KV_DIR="`ls -ld --full-time ${KERNEL_DIR} | awk '{ print $9 }'`" + einfo "`echo ${KERNEL_DIR} | tr -s /` is a real directory" + KV_DIR="`ls -d ${KERNEL_DIR}`" + # KV_DIR="`ls -ld --full-time ${KERNEL_DIR} | awk '{ print $9 }'`" else eerror "Directory '${KERNEL_DIR}' cannot be found" die fi - KV_DIR="`basename $KV_DIR`" + KV_DIR="`basename ${KV_DIR}`" # now, we need to break that down into versions KV_DIR_VERSION_FULL="`echo $KV_DIR | cut -f 2- -d -`" - KV_DIR_MAJOR="`echo $KV_DIR_VERSION_FULL | cut -f 1 -d .`" - KV_DIR_MINOR="`echo $KV_DIR_VERSION_FULL | cut -f 2 -d .`" - KV_DIR_PATCH="`echo $KV_DIR_VERSION_FULL | cut -f 3 -d . | cut -f 3 -d -`" - KV_DIR_TYPE="`echo $KV_DIR_VERSION_FULL | cut -f 2- -d -`" + KV_DIR_MAJOR="`echo ${KV_DIR_VERSION_FULL} | cut -f 1 -d .`" + KV_DIR_MINOR="`echo ${KV_DIR_VERSION_FULL} | cut -f 2 -d .`" + KV_DIR_PATCH="`echo ${KV_DIR_VERSION_FULL} | cut -f 3 -d . | cut -f 3 -d -`" + KV_DIR_TYPE="`echo ${KV_DIR_VERSION_FULL} | cut -f 2- -d -`" # sanity check - do the settings in the kernel's makefile match # the directory that the kernel src is stored in? KV_MK_FILE="${KERNEL_DIR}/Makefile" - KV_MK_MAJOR="`kernel-mod_getmakefilevar VERSION $KV_MK_FILE`" - KV_MK_MINOR="`kernel-mod_getmakefilevar PATCHLEVEL $KV_MK_FILE`" - KV_MK_PATCH="`kernel-mod_getmakefilevar SUBLEVEL $KV_MK_FILE`" - KV_MK_TYPE="`kernel-mod_getmakefilevar EXTRAVERSION $KV_MK_FILE`" + KV_MK_MAJOR="`kernel-mod_getmakefilevar VERSION ${KV_MK_FILE}`" + KV_MK_MINOR="`kernel-mod_getmakefilevar PATCHLEVEL ${KV_MK_FILE}`" + KV_MK_PATCH="`kernel-mod_getmakefilevar SUBLEVEL ${KV_MK_FILE}`" + KV_MK_TYPE="`kernel-mod_getmakefilevar EXTRAVERSION ${KV_MK_FILE}`" - KV_MK_VERSION_FULL="$KV_MK_MAJOR.$KV_MK_MINOR.$KV_MK_PATCH$KV_MK_TYPE" + KV_MK_VERSION_FULL="${KV_MK_MAJOR}.${KV_MK_MINOR}.${KV_MK_PATCH}${KV_MK_TYPE}" - if [ "$KV_MK_VERSION_FULL" != "$KV_DIR_VERSION_FULL" ]; then + KV_MK_OUTPUT="`kernel-mod_getmakefilevar ^KBUILD_OUTPUT ${KV_MK_FILE}`" + + if [ "$KV_MK_VERSION_FULL" != "${KV_DIR_VERSION_FULL}" ]; then ewarn - ewarn "The kernel Makefile says that this is a $KV_MK_VERSION_FULL kernel" - ewarn "but the source is in a directory for a $KV_DIR_VERSION_FULL kernel." + ewarn "The kernel Makefile says that this is a ${KV_MK_VERSION_FULL} kernel" + ewarn "but the source is in a directory for a ${KV_DIR_VERSION_FULL} kernel." ewarn ewarn "This goes against the recommended Gentoo naming convention." ewarn "Please rename your source directory to 'linux-${KV_MK_VERSION_FULL}'" @@ -76,22 +107,56 @@ # # do not rely on any of the variables above being available - KV_VERSION_FULL="$KV_MK_VERSION_FULL" - KV_MAJOR="$KV_MK_MAJOR" - KV_MINOR="$KV_MK_MINOR" - KV_PATCH="$KV_MK_PATCH" - KV_TYPE="$KV_MK_TYPE" + KV_VERSION_FULL="${KV_MK_VERSION_FULL}" + KV_MAJOR="${KV_MK_MAJOR}" + KV_MINOR="${KV_MK_MINOR}" + KV_PATCH="${KV_MK_PATCH}" + KV_TYPE="${KV_MK_TYPE}" + + # if we found an output location, use that. otherwise use KERNEL_DIR. + if [ ! -z "${KV_MK_OUTPUT}" ] + then + KV_OUTPUT="${ROOT}/${KV_MK_OUTPUT}" + else + KV_OUTPUT="${KERNEL_DIR}" + fi + + # KV_OBJ can be used when manually installing kernel modules + if [ "${KV_MINOR}" -gt "4" ] + then + KV_OBJ="ko" + else + KV_OBJ="o" + fi + + einfo "Building for Linux ${KV_VERSION_FULL} found in `echo ${KERNEL_DIR} | tr -s /`" - einfo "Building for Linux ${KV_VERSION_FULL} found in ${KERNEL_DIR}" + if kernel-mod_is_kernel 2 5 || kernel-mod_is_kernel 2 6 + then + einfo "which outputs to `echo ${KV_OUTPUT} | tr -s /`" + + # Warn them if they aren't using a different output directory + if [ "${KV_OUTPUT}" = "${ROOT}/usr/src/linux" ]; then + ewarn "By not using the kernel's ability to output to an alternative" + ewarn "directory, some external module builds may fail." + ewarn "See " + fi + fi } kernel-mod_checkzlibinflate_configured () { einfo "Checking for status of CONFIG_ZLIB_INFLATE support in your kernel" - . ${KERNEL_DIR}/.config || die "kernel has not been configured yet" - [ "$CONFIG_ZLIB_INFLATE" != "y" ] && kernel-mod_badconfig_zlib - [ "$CONFIG_ZLIB_DEFLATE" != "y" ] && kernel-mod_badconfig_zlib + if [ -z ${KV_OUTPUT} ]; then + kernel-mod_getversion + fi + + ! -f ${KV_OUTPUT}/.config || die "kernel has not been configured yet" + [ "`kernel-mod_getconfigvar ZLIB_INFLATE`" != "y" ] && \ + kernel-mod_badconfig_zlib + [ "`kernel-mod_getconfigvar ZLIB_DEFLATE`" != "y" ] && \ + kernel-mod_badconfig_zlib # bug #27882 - zlib routines are only linked into the kernel # if something compiled into the kernel calls them @@ -109,16 +174,16 @@ local x LINENO_END="`grep -n 'CONFIG_ZLIB_INFLATE y' ${KERNEL_DIR}/lib/Config.in | cut -d : -f 1`" - LINENO_START="`head -n $LINENO_END ${KERNEL_DIR}/lib/Config.in | grep -n 'if \[' | tail -n 1 | cut -d : -f 1`" - (( LINENO_AMOUNT = $LINENO_END - $LINENO_START )) - (( LINENO_END = $LINENO_END - 1 )) + LINENO_START="`head -n ${LINENO_END} ${KERNEL_DIR}/lib/Config.in | grep -n 'if \[' | tail -n 1 | cut -d : -f 1`" + (( LINENO_AMOUNT = ${LINENO_END} - ${LINENO_START} )) + (( LINENO_END = ${LINENO_END} - 1 )) - SYMBOLS="`head -n $LINENO_END ${KERNEL_DIR}/lib/Config.in | tail -n $LINENO_AMOUNT | sed -e 's/^.*\(CONFIG_[^\" ]*\).*/\1/g;'`" + SYMBOLS="`head -n ${LINENO_END} ${KERNEL_DIR}/lib/Config.in | tail -n ${LINENO_AMOUNT} | sed -e 's/^.*\(CONFIG_[^\" ]*\).*/\1/g;'`" # okay, now we have a list of symbols # we need to check each one in turn, to see whether it is set or not - for x in $SYMBOLS ; do + for x in ${SYMBOLS} ; do if [ "${!x}" = "y" ]; then # we have a winner! einfo "${x} ensures zlib is linked into your kernel - excellent" @@ -140,8 +205,8 @@ eerror "Please ensure that you enable at least one of these options:" eerror - for x in $SYMBOLS ; do - eerror " * $x" + for x in ${SYMBOLS} ; do + eerror " * ${x}" done eerror @@ -151,13 +216,177 @@ die "Kernel doesn't include zlib support" } +# make_linux_writeable() is used to allow portage to write to +# /usr/src/linux. This is a BIG no-no, but the "easiest" way for +# 2.6 module compilation. Since it's so horrible, we force users to accept +# doing it via a variable controlled by /etc/env.d/20kernel and kernel-config + +kernel-mod_make_linux_writable() +{ + # LINUX_PORTAGE_WRITABLE is set in /etc/env.d/20kernel to "yes" + # if someone really wants to do that + if [ "${LINUX_PORTAGE_WRITABLE}" != "yes" ] + then + if [ "${FEATURES/sandbox/}" != "${FEATURES}" ] + then + eerror "Due to the 2.6 kernel build system, external module compilation" + eerror "with a normal setup requires write access to ${KERNEL_DIR}" + eerror "There are several ways to fix/prevent this." + eerror "Users can willingly let portage make this writable by doing" + eerror "# kernel-config permit-writable on" + eerror "and then running 'env-update && source /etc/profile'" + eerror "However, this is considered a security risk!" + eerror "" + eerror "The prefered method is to enable Gentoo's new 'koutput' method" + eerror "for kernel modules. See the doc FIXME" + eerror "To enable this, you'll need to run" + eerror "# kernel-config kernel-output /var/tmp/kernel-output" + eerror "and then install a new kernel" + die "Incompatible kernel setup" + else + ewarn "Detected sandbox disabled for kernel module ebuild" + fi + fi + + ewarn "Making ${ROOT}/usr/src/linux-${KV} writable by portage!!!" + addwrite ${ROOT}/usr/src/linux-${KV} +} + + +# do_buildpatches performs the needed koutput patches as needed +kernel-mod_do_buildpatches() +{ + if [ -z ${KV_OUTPUT} ]; then + kernel-mod_getversion + fi + + cd ${S} + if kernel-mod_is_koutput && [ -n "${KERNEL_MOD_KOUTPUT_PATCH}" ]; then + EPATCH_SINGLE_MESSAGE="Patching to enable koutput compatibility" \ + epatch ${KERNEL_MOD_KOUTPUT_PATCH} + fi +} + +kernel-mod_src_unpack () +{ + check_KV + kernel-mod_getversion + + # KERNEL_MOD_SOURCES is used if you don't want to unpack just ${A} + # It can be set to "none" if you need to unpack things by hand + # (like the nvidia-kernel ebuild). If set to "none", you'll have + # to do any patching by hand as ${S} won't be around yet! + # You can just call kernel-mod_do_buildpatches after unpacking ${S} + # if need be. + if [ -z "${KERNEL_MOD_SOURCES}" ] + then + unpack ${A} + elif [ "${KERNEL_MOD_SOURCES}" != "none" ] + then + unpack ${KERNEL_MOD_SOURCES} + fi + + if is_kernel 2 5 || is_kernel 2 6 + then + # If we have sources we've unpacked, patch as needed + if [ "${KERNEL_MOD_SOURCES}" != "none" ]; then + kernel-mod_do_buildpatches + fi + fi +} + kernel-mod_src_compile () { + if is_kernel 2 5 || is_kernel 2 6 + then + # If we're on 2.5/2.6 and not koutputing, we need to make + # /usr/src/linux writable to succeed + if ! is_koutput + then + kernel-mod_make_linux_writable + fi + + unset ARCH + fi emake KERNEL_DIR=${KERNEL_DIR} || die } +kernel-mod_pkg_postinst() +{ + einfo "Checking kernel module dependancies" + test -r "${ROOT}/${KV_OUTPUT}/System.map" && \ + depmod -ae -F "${ROOT}/${KV_OUTPUT}/System.map" -b "${ROOT}" -r ${KV} +} + +# is_kernel() takes two arguments. They should be the major and minor number +# of the kernel you'd like to check for. e.g. +# +# if is_kernel 2 6; then foo; fi +# +kernel-mod_is_kernel() { + if [ -z "${KV_MAJOR}" ] + then + kernel-mod_getversion + fi + + if [ "${KV_MAJOR}" -eq "${1}" -a "${KV_MINOR}" -eq "${2}" ] + then + return 0 + else + return 1 + fi +} + +# is_koutput() should be used to determing if we are using the koutput +# method of compilation for 2.6 kernels + +kernel-mod_is_koutput() { + if [ -z ${KV_OUTPUT} ] + then + kernel-mod_getversion + fi + + if [ "${KV_OUTPUT}" != "${ROOT}/usr/src/linux" ]; then + return 0 + else + return 1 + fi +} + + +# warn_deprecated() is here to give a consistent warning message +# about the deprecation of certain functions + +warn_deprecated() { + if [ -z ${1} ] + then + eerror "warn_deprecated called from invalid context." + eerror "Please pass the function name as an argument." + die "warn_deprecated called without an argument" + fi + + ewarn "" + ewarn "The function ${1} is deprecated. Please remove the use" + ewarn "of this function from your ebuilds." + + if [ -n ${2} ] + then + ewarn "" + ewarn "Use of this function has been replaced by ${2}" + ewarn "See kernel-mod.eclass for more information" + fi +} + +# The is_X_X_kernel() functions are now deprecated. Please convert +# existing and new ebuilds to using the is_kernel() function. + kernel-mod_is_2_4_kernel() { - kernel-mod_getversion + if [ -z ${KV_MINOR} ] + then + kernel-mod_getversion + fi + + warn_deprecated kernel-mod_is_2_4_kernel is_kernel if [ "${KV_MAJOR}" -eq 2 -a "${KV_MINOR}" -eq 4 ] then @@ -168,7 +397,12 @@ } kernel-mod_is_2_5_kernel() { - kernel-mod_getversion + if [ -z ${KV_MINOR} ] + then + kernel-mod_getversion + fi + + warn_deprecated kernel-mod_is_2_5_kernel is_kernel if [ "${KV_MAJOR}" -eq 2 -a "${KV_MINOR}" -eq 5 ] then @@ -179,7 +413,12 @@ } kernel-mod_is_2_6_kernel() { - kernel-mod_getversion + if [ -z ${KV_MINOR} ] + then + kernel-mod_getversion + fi + + warn_deprecated kernel-mod_is_2_6_kernel is_kernel if [ "${KV_MAJOR}" -eq 2 -a "${KV_MINOR}" -eq 6 ] then @@ -189,4 +428,4 @@ fi } -EXPORT_FUNCTIONS src_compile +EXPORT_FUNCTIONS src_unpack src_compile pkg_postinst is_kernel is_koutput